X-Git-Url: http://www.project-moonshot.org/gitweb/?p=moonshot-ui.git;a=blobdiff_plain;f=src%2Fmoonshot-identity-management-view.vala;h=1ddb1c85e29ac3c67d18de36f5b33fa4f68555ea;hp=b0e1db2089543890cf43febc4da5c897552a8e07;hb=17d69131138577849d9cb170fd3ddb0da3ccb8b3;hpb=2127923777aa42d11750e0a0bd5b46d2ff5513e8 diff --git a/src/moonshot-identity-management-view.vala b/src/moonshot-identity-management-view.vala index b0e1db2..1ddb1c8 100644 --- a/src/moonshot-identity-management-view.vala +++ b/src/moonshot-identity-management-view.vala @@ -1,26 +1,33 @@ 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; +#if OS_MACOS + public OSXApplication osxApp; +#endif 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; @@ -50,15 +57,18 @@ class IdentityManagerView : Window { public IdentityManagerView(IdentityManagerApp app) { parent_app = app; - identities_manager = parent_app.model; +#if OS_MACOS + osxApp = OSXApplication.get_instance(); +#endif + 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(); + setup_list_model(); + load_id_cards(); connect_signals(); } @@ -66,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; @@ -184,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; @@ -197,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) @@ -244,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; } @@ -255,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, @@ -286,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); @@ -295,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) + public bool add_identity (IdCard id_card, bool force_flat_file_store) { - 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) - { - /* 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, @@ -347,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; } @@ -367,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; @@ -394,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)) { @@ -413,9 +402,9 @@ 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.INFO, + MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Are you sure you want to delete %s ID Card?"), id_card.issuer); var result = dialog.run (); @@ -429,197 +418,85 @@ 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); + prompting_service.set_label( _("Identity requested for service: %s").printf(service) ); + } - if (request.select_default) - { - identity = default_id_card; + public void queue_identity_request(IdentityRequest request) + { + 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 == 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; + public IdCard check_add_password(IdCard identity, IdentityRequest request, IdentityManagerModel model) + { + IdCard retval = identity; + bool idcard_has_pw = (identity.password != null) && (identity.password != ""); + bool request_has_pw = (request.password != null) && (request.password != ""); + if ((!idcard_has_pw) && (!identity.IsNoIdentity())) { + if (request_has_pw) { + identity.password = request.password; + retval = model.update_card(identity); + } else { + var dialog = new AddPasswordDialog (identity, request); + var result = dialog.run (); + + switch (result) { + case ResponseType.OK: + identity.password = dialog.password; + identity.store_password = dialog.remember; + if (dialog.remember) + identity.temporary = false; + retval = model.update_card(identity); + break; + default: + identity = null; + break; } - 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; + dialog.destroy (); } } - // 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); + return retval; } public void send_identity_cb (IdCard identity) { return_if_fail (request_queue.length > 0); + candidates = null; 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.store_id_cards(); - } - - if (identity.password == null) + check_add_password(identity, request, identities_manager); + if (this.request_queue.is_empty()) { - var dialog = new AddPasswordDialog (); - var result = dialog.run (); - - switch (result) { - case ResponseType.OK: - identity.password = dialog.password; - reset_password = ! dialog.remember; - break; - default: - identity = null; - break; + 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(); } - - dialog.destroy (); + } else { + IdentityRequest next = this.request_queue.peek_head(); + candidates = next.candidates; + set_prompting_service(next.service); } - - if (this.request_queue.is_empty()) - this.hide (); + 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) @@ -663,41 +540,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 to use %s?"), - custom_vbox.current_idcard.id_card.display_name); + _("Are you sure you want to stop '%s' ID Card from being used with %s?"), + custom_vbox.current_idcard.id_card.display_name, + 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