From 564ba904339e2ff9b67f8c7e1ec7fc8ce7c74dec Mon Sep 17 00:00:00 2001 From: Kevin Wasserman Date: Fri, 14 Mar 2014 11:49:01 -0400 Subject: [PATCH] Don't create duplicate identities. LP 1180914. When adding a new identity, replace any existing identity with the same nai. Provide appropriate confirmation dialog if gui is available. --- src/moonshot-id.vala | 72 ++++++++++++++++++++++++++++++ src/moonshot-idcard-store.vala | 2 +- src/moonshot-identities-manager.vala | 57 +++++++++++++++++++++-- src/moonshot-identity-management-view.vala | 30 +++++++++++-- src/moonshot-keyring-store.vala | 8 ++-- src/moonshot-local-flat-file-store.vala | 9 ++-- 6 files changed, 164 insertions(+), 14 deletions(-) diff --git a/src/moonshot-id.vala b/src/moonshot-id.vala index 8f90e8d..9418911 100644 --- a/src/moonshot-id.vala +++ b/src/moonshot-id.vala @@ -4,12 +4,31 @@ public class TrustAnchor : Object public string subject {get; set; default = "";} public string subject_alt {get; set; default = "";} public string server_cert {get; set; default = "";} + public int Compare(TrustAnchor other) + { + if (this.ca_cert != other.ca_cert) + return 1; + if (this.subject != other.subject) + return 1; + if (this.subject_alt != other.subject_alt) + return 1; + if (this.server_cert != other.server_cert) + return 1; + return 0; + } } public struct Rule { public string pattern; public string always_confirm; + public int Compare(Rule other) { + if (this.pattern != other.pattern) + return 1; + if (this.always_confirm != other.always_confirm) + return 1; + return 0; + } } public class IdCard : Object @@ -57,6 +76,37 @@ public class IdCard : Object return (display_name == NO_IDENTITY); } + public enum DiffFlags { + DISPLAY_NAME, + USERNAME, + PASSWORD, + ISSUER, + RULES, + SERVICES, + TRUST_ANCHOR; + } + + public int Compare(IdCard other) + { + int diff = 0; + if (this.display_name != other.display_name) + diff |= 1 << DiffFlags.DISPLAY_NAME; + if (this.username != other.username) + diff |= 1 << DiffFlags.USERNAME; + if (this.password != other.password) + diff |= 1 << DiffFlags.PASSWORD; + if (this.issuer != other.issuer) + diff |= 1 << DiffFlags.ISSUER; + if (CompareRules(this.rules, other.rules)!=0) + diff |= 1 << DiffFlags.RULES; + if (CompareStringArray(this.services, other.services)!=0) + diff |= 1 << DiffFlags.SERVICES; + if (this.trust_anchor.Compare(other.trust_anchor)!=0) + diff |= 1 << DiffFlags.TRUST_ANCHOR; + stdout.printf("Diff Flags: %x\n", diff); + return diff; + } + public static IdCard NewNoIdentity() { IdCard card = new IdCard(); @@ -68,3 +118,25 @@ public class IdCard : Object password = null; } } + +public int CompareRules(Rule[] a, Rule[] b) +{ + if (a.length != b.length) + return 1; + for (int i=0; i get_card_list(); diff --git a/src/moonshot-identities-manager.vala b/src/moonshot-identities-manager.vala index ceadb30..b8b2f5d 100644 --- a/src/moonshot-identities-manager.vala +++ b/src/moonshot-identities-manager.vala @@ -109,6 +109,44 @@ public class IdentityManagerModel : Object { return true; } + private bool remove_duplicates(IdCard card) + { + bool duplicate_found = false; + bool found = false; + do { + var cards = get_card_list(); + found = false; + foreach (IdCard id_card in cards) { + if ((card != id_card) && (id_card.nai == card.nai)) { + stdout.printf("removing duplicate id for '%s'\n", card.nai); + remove_card_internal(id_card); + found = duplicate_found = true; + break; + } + } + } while (found); + return duplicate_found; + } + + public IdCard? find_id_card(string nai, bool force_flat_file_store) { + IdCard? retval = null; + IIdentityCardStore.StoreType saved_store_type = get_store_type(); + if (force_flat_file_store) + set_store_type(IIdentityCardStore.StoreType.FLAT_FILE); + + foreach (IdCard id in get_card_list()) { + if (id.nai == nai) { + retval = id; + break; + } + } + set_store_type(saved_store_type); + if (force_flat_file_store && + (saved_store_type != IIdentityCardStore.StoreType.FLAT_FILE)) + card_list_changed(); + return retval; + } + public void add_card(IdCard card, bool force_flat_file_store) { if (card.temporary) return; @@ -119,6 +157,8 @@ public class IdentityManagerModel : Object { if (force_flat_file_store) set_store_type(IIdentityCardStore.StoreType.FLAT_FILE); + remove_duplicates(card); + if (!display_name_is_valid (card.display_name, out candidate)) { card.display_name = candidate; @@ -147,10 +187,19 @@ public class IdentityManagerModel : Object { return retval; } - public void remove_card(IdCard card) { - password_table.RemovePassword(card, store); - store.remove_card(card); - card_list_changed(); + private bool remove_card_internal(IdCard card) { + if (card.temporary) + return false; + password_table.RemovePassword(card, store); + return store.remove_card(card); + } + + public bool remove_card(IdCard card) { + if (remove_card_internal(card)) { + card_list_changed(); + return true; + } + return false; } public void set_store_type(IIdentityCardStore.StoreType type) { diff --git a/src/moonshot-identity-management-view.vala b/src/moonshot-identity-management-view.vala index 515b8f9..77d8056 100644 --- a/src/moonshot-identity-management-view.vala +++ b/src/moonshot-identity-management-view.vala @@ -329,14 +329,38 @@ public class IdentityManagerView : Window { */ var ret = Gtk.ResponseType.YES; #else - - var dialog = new Gtk.MessageDialog (this, + Gtk.MessageDialog dialog; + IdCard? prev_id = identities_manager.find_id_card(id_card.nai, force_flat_file_store); + if (prev_id!=null) { + int flags = prev_id.Compare(id_card); + if (flags == 0) { + return false; // no changes, no need to update + } else if ((flags & (1< get_card_list() { -- 2.1.4