X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fmoonshot-identity-management-view.vala;h=7571af01030223f8384b187e88f716dd89d27b9e;hb=4c49d170d9b2fbd4bc29fea2bb857d30c9aa81e5;hp=c758ba8e6ec279cda2bbe9ef12a37e03d3fed0da;hpb=aa21b108b0220d344ca50576a806072ec11d3845;p=moonshot-ui.git diff --git a/src/moonshot-identity-management-view.vala b/src/moonshot-identity-management-view.vala index c758ba8..7571af0 100644 --- a/src/moonshot-identity-management-view.vala +++ b/src/moonshot-identity-management-view.vala @@ -1,7 +1,7 @@ using Gee; using Gtk; -class IdentityManagerView : Window { +public class IdentityManagerView : Window { private const int WINDOW_WIDTH = 400; private const int WINDOW_HEIGHT = 500; protected IdentityManagerApp parent_app; @@ -11,19 +11,23 @@ class IdentityManagerView : Window { private UIManager ui_manager = new UIManager(); private Entry search_entry; private VBox vbox_right; + private VBox login_vbox; + private VBox services_vbox; private CustomVBox custom_vbox; private VBox services_internal_vbox; private Entry username_entry; private Entry password_entry; + private Label prompting_service; + private Label no_identity_title; + private CheckButton remember_checkbutton; private ListStore* listmodel; private TreeModelFilter filter; public IdentityManagerModel identities_manager; - private SList candidates; + private unowned SList candidates; - private IdCard default_id_card; public GLib.Queue request_queue; private HashTable service_button_map; @@ -59,15 +63,12 @@ class IdentityManagerView : Window { identities_manager = parent_app.model; request_queue = new GLib.Queue(); service_button_map = new HashTable (direct_hash, direct_equal); - this.title = "Moonshoot"; + this.title = "Moonshot Identity Selector"; this.set_position (WindowPosition.CENTER); set_default_size (WINDOW_WIDTH, WINDOW_HEIGHT); build_ui(); setup_list_model(); - load_id_cards(); -#if OS_MACOS - osxApp = app.osxApp; -#endif + load_id_cards(); connect_signals(); } @@ -75,11 +76,6 @@ class IdentityManagerView : Window { load_id_cards(); } - public void add_candidate (IdCard idcard) - { - candidates.append (idcard); - } - private bool visible_func (TreeModel model, TreeIter iter) { IdCard id_card; @@ -193,12 +189,16 @@ class IdentityManagerView : Window { } private void load_id_cards () { + string current_idcard_nai = null; + if (this.custom_vbox.current_idcard != null) { + current_idcard_nai = custom_vbox.current_idcard.id_card.nai; + custom_vbox.current_idcard = null; + } var children = this.custom_vbox.get_children (); foreach (var id_card_widget in children) { remove_id_card_widget((IdCardWidget)id_card_widget); } - - this.default_id_card = null; + this.listmodel->clear(); LinkedList card_list = identities_manager.get_card_list() ; if (card_list == null) { return; @@ -206,25 +206,38 @@ class IdentityManagerView : Window { foreach (IdCard id_card in card_list) { add_id_card_data (id_card); - add_id_card_widget (id_card); - } - - if (card_list.size > 0){ - this.default_id_card = card_list.first(); + IdCardWidget id_card_widget = add_id_card_widget (id_card); + if (id_card_widget.id_card.nai == current_idcard_nai) { + fill_details(id_card_widget); + id_card_widget.expand(); + } } + if (custom_vbox.current_idcard == null) + fill_details(null); } - private void fill_details (IdCardWidget id_card_widget) + private void fill_details (IdCardWidget? id_card_widget) { - var id_card = id_card_widget.id_card; - this.username_entry.set_text (id_card.username); - this.password_entry.set_text (id_card.password ?? ""); + var vr_children = this.vbox_right.get_children(); + foreach (var vr_child in vr_children) + this.vbox_right.remove(vr_child); + if (id_card_widget != null) { + var id_card = id_card_widget.id_card; + if (id_card.display_name == IdCard.NO_IDENTITY) { + this.vbox_right.pack_start(no_identity_title, false, true, 0); + } else { + this.username_entry.set_text (id_card.username); + this.password_entry.set_text (id_card.password ?? ""); + this.vbox_right.pack_start(login_vbox, false, true, 0); + this.remember_checkbutton.active = id_card.store_password; + } + this.vbox_right.pack_start (services_vbox, false, true, 0); - var children = this.services_internal_vbox.get_children (); - foreach (var hbox in children) - hbox.destroy(); - fill_services_vbox (id_card_widget.id_card); -// identities_manager.store_id_cards(); + var children = this.services_internal_vbox.get_children (); + foreach (var hbox in children) + services_internal_vbox.remove(hbox); + fill_services_vbox (id_card_widget.id_card); + } } private void show_details (IdCard id_card) @@ -253,8 +266,8 @@ class IdentityManagerView : Window { id_card.issuer = "Issuer"; id_card.username = dialog.username; id_card.password = dialog.password; + id_card.store_password = dialog.store_password; id_card.services = {}; - id_card.set_data("pixbuf", find_icon ("avatar-default", 48)); return id_card; } @@ -264,7 +277,7 @@ class IdentityManagerView : Window { TreeIter iter; Gdk.Pixbuf pixbuf; this.listmodel->append (out iter); - pixbuf = id_card.get_data("pixbuf"); + pixbuf = get_pixbuf(id_card); listmodel->set (iter, Columns.IDCARD_COL, id_card, Columns.LOGO_COL, pixbuf, @@ -295,7 +308,7 @@ class IdentityManagerView : Window { } } - private void add_id_card_widget (IdCard id_card) + private IdCardWidget add_id_card_widget (IdCard id_card) { var id_card_widget = new IdCardWidget (id_card); this.custom_vbox.add_id_card_widget (id_card_widget); @@ -304,50 +317,18 @@ class IdentityManagerView : Window { id_card_widget.send_id.connect ((w) => send_identity_cb (w.id_card)); id_card_widget.expanded.connect (this.custom_vbox.receive_expanded_event); id_card_widget.expanded.connect (fill_details); + return id_card_widget; } - /* This method finds a valid display name */ - public bool display_name_is_valid (string name, - out string? candidate) - { - foreach (IdCard id_card in identities_manager.get_card_list()) - { - if (id_card.display_name == name) - { - if (&candidate != null) - { - for (int i=0; i<1000; i++) - { - string tmp = "%s %d".printf (name, i); - if (display_name_is_valid (tmp, null)) - { - candidate = tmp; - break; - } - } - } - return false; - } - } - - return true; - } - - public void insert_id_card (IdCard id_card) - { - string candidate; - - if (!display_name_is_valid (id_card.display_name, out candidate)) - { - id_card.display_name = candidate; - } - - this.identities_manager.add_card(id_card); - } - - public bool add_identity (IdCard id_card) + public bool add_identity (IdCard id_card, bool force_flat_file_store) { - /* TODO: Check if display name already exists */ +#if OS_MACOS + /* + * TODO: We should have a confirmation dialog, but currently it will crash on Mac OS + * so for now we will install silently + */ + var ret = Gtk.ResponseType.YES; +#else var dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.DESTROY_WITH_PARENT, @@ -356,13 +337,12 @@ class IdentityManagerView : Window { _("Would you like to add '%s' ID Card to the ID Card Organizer?"), id_card.display_name); - dialog.show_all (); var ret = dialog.run (); - dialog.hide (); + dialog.destroy (); +#endif if (ret == Gtk.ResponseType.YES) { - id_card.set_data ("pixbuf", find_icon ("avatar-default", 48)); - this.insert_id_card (id_card); + this.identities_manager.add_card (id_card, force_flat_file_store); return true; } @@ -376,7 +356,7 @@ class IdentityManagerView : Window { switch (result) { case ResponseType.OK: - insert_id_card (get_id_card_data (dialog)); + this.identities_manager.add_card (get_id_card_data (dialog), false); break; default: break; @@ -403,7 +383,7 @@ class IdentityManagerView : Window { var children = this.custom_vbox.get_children (); foreach (var id_card_widget in children) - id_card_widget.destroy(); + remove_id_card_widget((IdCardWidget )id_card_widget); //id_card_widget.destroy(); if (filter.get_iter_first (out iter)) { @@ -422,7 +402,7 @@ class IdentityManagerView : Window { { var id_card = id_card_widget.id_card; - var dialog = new MessageDialog (null, + var dialog = new MessageDialog (this, DialogFlags.DESTROY_WITH_PARENT, MessageType.QUESTION, Gtk.ButtonsType.YES_NO, @@ -438,176 +418,36 @@ class IdentityManagerView : Window { dialog.destroy (); } - public void select_identity (IdentityRequest request) + public void set_prompting_service(string service) { - IdCard identity = null; - - this.request_queue.push_tail (request); - - if (custom_vbox.current_idcard != null && - custom_vbox.current_idcard.send_button != null) - custom_vbox.current_idcard.send_button.set_sensitive (true); - - if (request.select_default) - { - identity = default_id_card; - } - - if (identity == null) - { - bool has_nai = request.nai != null && request.nai != ""; - bool has_srv = request.service != null && request.service != ""; - bool confirm = false; - IdCard nai_provided = null; - - foreach (IdCard id in identities_manager.get_card_list()) - { - /* If NAI matches we add id card to the candidate list */ - if (has_nai && request.nai == id.nai) - { - nai_provided = id; - add_candidate (id); - continue; - } - - /* If any service matches we add id card to the candidate list */ - if (has_srv) - { - foreach (string srv in id.services) - { - if (request.service == srv) - { - add_candidate (id); - continue; - } - } - } - } - - /* If more than one candidate we dissasociate service from all ids */ - if (has_srv && candidates.length() > 1) - { - foreach (IdCard id in candidates) - { - int i = 0; - SList services_list = null; - bool has_service = false; - - foreach (string srv in id.services) - { - if (srv == request.service) - { - has_service = true; - continue; - } - services_list.append (srv); - } - - if (!has_service) - continue; - - if (services_list.length () == 0) - { - id.services = {}; - continue; - } - - string[] services = new string[services_list.length ()]; - foreach (string srv in services_list) - { - services[i] = srv; - i++; - } - - id.services = services; - } - } - -// identities_manager.store_id_cards (); - - /* If there are no candidates we use the service matching rules */ - if (candidates.length () == 0) - { - foreach (IdCard id in identities_manager.get_card_list()) - { - foreach (Rule rule in id.rules) - { - if (!match_service_pattern (request.service, rule.pattern)) - continue; - - candidates.append (id); - - if (rule.always_confirm == "true") - confirm = true; - } - } - } - - if (candidates.length () > 1) - { - if (has_nai && nai_provided != null) - { - identity = nai_provided; - confirm = false; - } - else - confirm = true; - } - else - identity = candidates.nth_data (0); - - /* TODO: If candidate list empty return fail */ - - if (confirm) - { - filter.refilter(); - redraw_id_card_widgets (); - show (); - return; - } - } - // Send back the identity (we can't directly run the - // callback because we may be being called from a 'yield') - Idle.add (() => { send_identity_cb (identity); return false; }); - return; - } - - private bool match_service_pattern (string service, string pattern) - { - var pspec = new PatternSpec (pattern); - return pspec.match_string (service); + prompting_service.set_label( _("Identity requested for service: %s").printf(service) ); } - public void send_identity_cb (IdCard identity) + public void queue_identity_request(IdentityRequest request) { - return_if_fail (request_queue.length > 0); - - var request = this.request_queue.pop_head (); - bool reset_password = false; - - if (request.service != null && request.service != "") - { - string[] services = new string[identity.services.length + 1]; - - for (int i = 0; i < identity.services.length; i++) - services[i] = identity.services[i]; - - services[identity.services.length] = request.service; - - identity.services = services; - - identities_manager.update_card (identity); + if (this.request_queue.is_empty()) + { /* setup widgets */ + candidates = request.candidates; + filter.refilter(); + redraw_id_card_widgets (); + set_prompting_service(request.service); + show (); } + this.request_queue.push_tail (request); + } - if (identity.password == null) + public void check_add_password(IdCard identity, IdentityRequest request, IdentityManagerModel model) + { + if ((identity.password == "") && !identity.IsNoIdentity()) { - var dialog = new AddPasswordDialog (); + var dialog = new AddPasswordDialog (identity, request); var result = dialog.run (); switch (result) { case ResponseType.OK: identity.password = dialog.password; - reset_password = ! dialog.remember; + identity.store_password = dialog.remember; + model.update_card(identity); break; default: identity = null; @@ -616,19 +456,38 @@ class IdentityManagerView : Window { dialog.destroy (); } + } + public void send_identity_cb (IdCard identity) + { + return_if_fail (request_queue.length > 0); + + candidates = null; + var request = this.request_queue.pop_head (); + check_add_password(identity, request, identities_manager); if (this.request_queue.is_empty()) - Gtk.main_quit (); + { + candidates = null; + prompting_service.set_label(_("")); + if (!parent_app.explicitly_launched) { +// The following occasionally causes the app to exit without sending the dbus +// reply, so for now we just don't exit +// Gtk.main_quit (); +// just hide instead + this.hide(); + } + } else { + IdentityRequest next = this.request_queue.peek_head(); + candidates = next.candidates; + set_prompting_service(next.service); + } + filter.refilter(); + redraw_id_card_widgets (); if (identity != null) - this.default_id_card = identity; + parent_app.default_id_card = identity; request.return_identity (identity); - - if (reset_password) - identity.password = null; - - candidates = null; } private void label_make_bold (Label label) @@ -672,42 +531,40 @@ class IdentityManagerView : Window { remove_button.clicked.connect ((remove_button) => { + var candidate = service_button_map.lookup (remove_button); + if (candidate == null) + return; var dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Are you sure you want to stop '%s' ID Card from being used with %s?"), custom_vbox.current_idcard.id_card.display_name, - _("this service")); + candidate); var ret = dialog.run(); dialog.hide(); if (ret == Gtk.ResponseType.YES) { IdCard idcard = custom_vbox.current_idcard.id_card; - var candidate = service_button_map.lookup (remove_button); - - SList services = new SList(); + if (idcard != null) { + SList services = new SList(); - foreach (string srv in idcard.services) - { - if (srv == candidate) - continue; - services.append (srv); - } + foreach (string srv in idcard.services) + { + if (srv == candidate) + continue; + services.append (srv); + } - idcard.services = new string[services.length()]; - for (int j=0; j