Small refactor of contact creation
authorThomas
Wed, 29 Aug 2018 11:16:37 +0200
changeset 23511a6bc4294582
parent 2350 7103795126a0
child 2352 76687cbac48d
child 2353 81975e284b07
child 2356 b1c3af7ae954
Small refactor of contact creation
PEPIdentity.cs
ThisAddIn.cs
     1.1 --- a/PEPIdentity.cs	Mon Aug 27 11:10:40 2018 +0200
     1.2 +++ b/PEPIdentity.cs	Wed Aug 29 11:16:37 2018 +0200
     1.3 @@ -3,6 +3,7 @@
     1.4  using System.Collections.Generic;
     1.5  using System.ComponentModel;
     1.6  using System.Linq;
     1.7 +using System.Runtime.InteropServices;
     1.8  using Outlook = Microsoft.Office.Interop.Outlook;
     1.9  
    1.10  namespace pEp
    1.11 @@ -26,6 +27,8 @@
    1.12  
    1.13          private pEpIdentity internalIdentity;
    1.14  
    1.15 +        private static Dictionary<string, string>  userIdCache = new Dictionary<string, string>();
    1.16 +
    1.17          /**************************************************************
    1.18           * 
    1.19           * Constructors
    1.20 @@ -1063,7 +1066,7 @@
    1.21                              own = new PEPIdentity();
    1.22                              own.Address = address;
    1.23                              own.UserName = userName;
    1.24 -                            own.UserId = Globals.ThisAddIn.GetUserId(own.Address); // Not using 'myself ID'
    1.25 +                            own.UserId = PEPIdentity.GetUserId(own.Address); // Not using 'myself ID'
    1.26  
    1.27                              // Update the identity in the pEp engine (and get fingerprint)
    1.28                              try
    1.29 @@ -1467,7 +1470,7 @@
    1.30                                      try
    1.31                                      {
    1.32                                          contact = exchSender.GetContact() ?? PEPIdentity.CreateContact(from.Address, from.UserName, "EX");
    1.33 -                                        from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
    1.34 +                                        from.UserId = PEPIdentity.GetUserId(from.Address, contact);
    1.35  
    1.36                                          // Read the contact's ForceUnencrypted property
    1.37                                          from.IsForceUnencrypted = contact?.GetForceUnencrypted();
    1.38 @@ -1499,7 +1502,7 @@
    1.39                                  try
    1.40                                  {
    1.41                                      contact = sender.GetContact() ?? PEPIdentity.CreateContact(from.Address, from.UserName, "EX");
    1.42 -                                    from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
    1.43 +                                    from.UserId = PEPIdentity.GetUserId(from.Address, contact);
    1.44  
    1.45                                      // Read the contact's ForceUnencrypted property
    1.46                                      from.IsForceUnencrypted = contact?.GetForceUnencrypted();
    1.47 @@ -1537,7 +1540,7 @@
    1.48                          try
    1.49                          {
    1.50                              contact = sender.GetContact() ?? PEPIdentity.CreateContact(from.Address, from.UserName);
    1.51 -                            from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
    1.52 +                            from.UserId = PEPIdentity.GetUserId(from.Address, contact);
    1.53  
    1.54                              // Read the contact's ForceUnencrypted property
    1.55                              from.IsForceUnencrypted = contact?.GetForceUnencrypted();
    1.56 @@ -1602,36 +1605,14 @@
    1.57          /// <returns>The created contact or null if an error occured.</returns>
    1.58          private static Outlook.ContactItem CreateContact(string address, string userName, string addressType = null)
    1.59          {
    1.60 -            bool contactExists = false;
    1.61              Outlook.ContactItem contact = null;
    1.62  
    1.63 -            // Doublecheck to make sure there is not already a contact for this address
    1.64 -            Outlook.NameSpace ns = null;
    1.65 -            Outlook.Folder folder = null;
    1.66 -            Outlook.Items items = null;
    1.67 -            try
    1.68 -            {
    1.69 -                ns = Globals.ThisAddIn.Application.Session;
    1.70 -                folder = ns?.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts) as Outlook.Folder;
    1.71 -                items = folder?.Items;
    1.72 -                items = items?.Restrict(string.Format("[Email1Address]='{0}' Or [Email2Address]='{0}' Or [Email3Address]='{0}'", address));
    1.73 -                contactExists = (items?.Count > 0);
    1.74 -            }
    1.75 -            catch (Exception ex)
    1.76 -            {
    1.77 -                contactExists = false;
    1.78 -                Log.Error("CreateContact: Error doublechecking existence of contact with same address. " + ex.ToString());
    1.79 -            }
    1.80 -            finally
    1.81 -            {
    1.82 -                ns = null;
    1.83 -                folder = null;
    1.84 -                items = null;
    1.85 -            }
    1.86 +            // Doublecheck if contact already exists
    1.87 +            contact = PEPIdentity.GetContact(address);
    1.88  
    1.89              // If contact doesn't exist, create it.
    1.90              // Make also sure that it's not an own identity.
    1.91 -            if ((contactExists == false) &&
    1.92 +            if ((contact == null) &&
    1.93                  (PEPIdentity.GetIsOwnIdentity(address) == false))
    1.94              {
    1.95                  try
    1.96 @@ -1653,6 +1634,72 @@
    1.97          }
    1.98  
    1.99          /// <summary>
   1.100 +        /// Gets the Outlook contact for a given address.
   1.101 +        /// </summary>
   1.102 +        /// <param name="address">The address of the contact to retrieve.</param>
   1.103 +        /// <returns>The contact or null if no contact was found or an error occured.</returns>
   1.104 +        private static Outlook.ContactItem GetContact(string address)
   1.105 +        {
   1.106 +            Outlook.ContactItem contact = null;
   1.107 +            Outlook.NameSpace ns = null;
   1.108 +            Outlook.Folder folder = null;
   1.109 +            Outlook.Items items = null;
   1.110 +            Outlook.Items filteredItems = null;
   1.111 +
   1.112 +            try
   1.113 +            {
   1.114 +                // Get all contacts
   1.115 +                ns = Globals.ThisAddIn.Application.Session;
   1.116 +                folder = ns?.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts) as Outlook.Folder;
   1.117 +                items = folder?.Items;
   1.118 +
   1.119 +                // Try to find contact where primary address equals the given address
   1.120 +                filteredItems = items?.Restrict(string.Format("[Email1Address]='{0}'", address));
   1.121 +                if (filteredItems?.Count > 0)
   1.122 +                {
   1.123 +                    // If more than one was found, just take the first occurrence
   1.124 +                    contact = filteredItems[1] as Outlook.ContactItem;
   1.125 +                }
   1.126 +
   1.127 +                // If we have no contact yet, try to find contact where secondary address equals the given address
   1.128 +                if (contact == null)
   1.129 +                {
   1.130 +                    filteredItems = items?.Restrict(string.Format("[Email2Address]='{0}'", address));
   1.131 +                    if (filteredItems?.Count > 0)
   1.132 +                    {
   1.133 +                        // If more than one was found, just take the first occurrence
   1.134 +                        contact = filteredItems[1] as Outlook.ContactItem;
   1.135 +                    }
   1.136 +                }
   1.137 +
   1.138 +                // If we still have no contact yet, try to find contact where tertiary address equals the given address
   1.139 +                if (contact == null)
   1.140 +                {
   1.141 +                    filteredItems = items?.Restrict(string.Format("[Email3Address]='{0}'", address));
   1.142 +                    if (filteredItems?.Count > 0)
   1.143 +                    {
   1.144 +                        // If more than one was found, just take the first occurrence
   1.145 +                        contact = filteredItems[1] as Outlook.ContactItem;
   1.146 +                    }
   1.147 +                }
   1.148 +            }
   1.149 +            catch (Exception ex)
   1.150 +            {
   1.151 +                contact = null;
   1.152 +                Log.Error("GetContact: Error getting contact item. " + ex.ToString());
   1.153 +            }
   1.154 +            finally
   1.155 +            {
   1.156 +                ns = null;
   1.157 +                folder = null;
   1.158 +                items = null;
   1.159 +                filteredItems = null;
   1.160 +            }
   1.161 +
   1.162 +            return contact;
   1.163 +        }
   1.164 +
   1.165 +        /// <summary>
   1.166          /// Gets the default from/sender identity using the default Outlook user.
   1.167          /// Warning: The result can be null.
   1.168          /// </summary>
   1.169 @@ -1701,6 +1748,79 @@
   1.170          }
   1.171  
   1.172          /// <summary>
   1.173 +        /// Gets the pEp user ID for the given address and contact.
   1.174 +        /// </summary>
   1.175 +        /// <param name="address">The address to get the user ID for.</param>
   1.176 +        /// <param name="contact">The contact associated with the address (if any).
   1.177 +        /// This value can be null and is not required for 'myself' user IDs.</param>
   1.178 +        /// <returns>The user ID (Outlook EntryID) for the given address</returns>
   1.179 +        internal static string GetUserId(string address,
   1.180 +                                         Outlook.ContactItem contact = null)
   1.181 +        {
   1.182 +            string id = null;
   1.183 +            Outlook.Folder contactFolder = null;
   1.184 +
   1.185 +            try
   1.186 +            {
   1.187 +                if (string.IsNullOrEmpty(address) == false)
   1.188 +                {
   1.189 +                    // Search cache
   1.190 +                    if (id == null)
   1.191 +                    {
   1.192 +                        try
   1.193 +                        {
   1.194 +                            id = PEPIdentity.userIdCache[address];
   1.195 +                        }
   1.196 +                        catch
   1.197 +                        {
   1.198 +                            id = null;
   1.199 +                        }
   1.200 +                    }
   1.201 +
   1.202 +                    // Handle myself user ID calculation
   1.203 +                    if (id == null)
   1.204 +                    {
   1.205 +                        // Check if the address is myself
   1.206 +                        if (PEPIdentity.GetIsOwnIdentity(address))
   1.207 +                        {
   1.208 +                            id = PEPSettings.PEP_OWN_USER_ID;
   1.209 +                            PEPIdentity.userIdCache[address] = id;
   1.210 +                        }
   1.211 +                    }
   1.212 +
   1.213 +                    // Use a contact EntryID if available
   1.214 +                    if ((id == null) &&
   1.215 +                        (contact != null))
   1.216 +                    {
   1.217 +                        try
   1.218 +                        {
   1.219 +                            id = contact.EntryID;
   1.220 +                            PEPIdentity.userIdCache[address] = id;
   1.221 +                        }
   1.222 +                        catch
   1.223 +                        {
   1.224 +                            Log.Error("GetUserId: Attempted to use contact but failed.");
   1.225 +                        }
   1.226 +                    }
   1.227 +                }
   1.228 +            }
   1.229 +            catch (Exception ex)
   1.230 +            {
   1.231 +                Globals.StopAndSendCrashReport(ex);
   1.232 +            }
   1.233 +            finally
   1.234 +            {
   1.235 +                if (contactFolder != null)
   1.236 +                {
   1.237 +                    Marshal.FinalReleaseComObject(contactFolder);
   1.238 +                    contactFolder = null;
   1.239 +                }
   1.240 +            }
   1.241 +
   1.242 +            return (id);
   1.243 +        }
   1.244 +
   1.245 +        /// <summary>
   1.246          /// Creates a new pEp identity from the given outlook recipient.
   1.247          /// The output will never be null.
   1.248          /// Warning: The result can contain identity groups.
   1.249 @@ -1762,7 +1882,7 @@
   1.250                          contact = PEPIdentity.CreateContact(newIdent.Address, newIdent.UserName);
   1.251                      }
   1.252  
   1.253 -                    newIdent.UserId = Globals.ThisAddIn.GetUserId(newIdent.Address, contact);
   1.254 +                    newIdent.UserId = PEPIdentity.GetUserId(newIdent.Address, contact);
   1.255  
   1.256                      contact = null;
   1.257                  }
   1.258 @@ -1975,19 +2095,21 @@
   1.259                                      {
   1.260                                          currContact = exchUser.GetContact();
   1.261  
   1.262 -                                        if (contact == null && addContact)
   1.263 +                                        if ((currContact == null) && 
   1.264 +                                            addContact)
   1.265                                          {
   1.266                                              currContact = PEPIdentity.CreateContact(newIdent2.Address, newIdent2.UserName);
   1.267                                          }
   1.268  
   1.269                                          newIdent2.IsForceUnencrypted = currContact?.GetForceUnencrypted();
   1.270                                      }
   1.271 -                                    catch
   1.272 +                                    catch (Exception ex)
   1.273                                      {
   1.274                                          currContact = null;
   1.275 +                                        Log.Error("PEPIdentity.Create: Error creating contact for Exchange user." + ex.ToString());
   1.276                                      }
   1.277  
   1.278 -                                    newIdent2.UserId = Globals.ThisAddIn.GetUserId(newIdent2.Address, currContact);
   1.279 +                                    newIdent2.UserId = PEPIdentity.GetUserId(newIdent2.Address, currContact);
   1.280                                      newIdent.Members.Add(newIdent2);
   1.281                                  }
   1.282                              }
   1.283 @@ -2093,7 +2215,7 @@
   1.284                      }
   1.285                  }
   1.286  
   1.287 -                newIdent.UserId = Globals.ThisAddIn.GetUserId(newIdent.Address, contact);
   1.288 +                newIdent.UserId = PEPIdentity.GetUserId(newIdent.Address, contact);
   1.289  
   1.290                  identityCreated = true;
   1.291              }
     2.1 --- a/ThisAddIn.cs	Mon Aug 27 11:10:40 2018 +0200
     2.2 +++ b/ThisAddIn.cs	Wed Aug 29 11:16:37 2018 +0200
     2.3 @@ -51,7 +51,6 @@
     2.4          private bool                        initialized                 = false;
     2.5          private bool                        isItemSendHandlerEnabled    = true;
     2.6          private FormControlOptions.State    lastOptionsState            = null;
     2.7 -        private Dictionary<string, string>  userIdCache                 = new Dictionary<string, string>();
     2.8          private List<WatchedFolder>         watchedFolders              = new List<WatchedFolder>();
     2.9          private System.Windows.Forms.Timer  inboxCleaner                = null;
    2.10  
    2.11 @@ -545,9 +544,6 @@
    2.12                      UserName = acctSettings.UserName
    2.13                  };
    2.14  
    2.15 -                // Add to userId cache
    2.16 -                this.userIdCache[ownIdentity.Address] = ownIdentity.UserId;
    2.17 -
    2.18                  // Set not for sync flag if necessary
    2.19                  if ((acctSettings.Type.Contains("Imap")) ||
    2.20                      ((Globals.ThisAddIn.Settings.IsSyncEnabledForAllAccounts == false) &&
    2.21 @@ -591,79 +587,6 @@
    2.22          }
    2.23  
    2.24          /// <summary>
    2.25 -        /// Gets the pEp user ID for the given address and contact.
    2.26 -        /// </summary>
    2.27 -        /// <param name="address">The address to get the user ID for.</param>
    2.28 -        /// <param name="contact">The contact associated with the address (if any).
    2.29 -        /// This value can be null and is not required for 'myself' user IDs.</param>
    2.30 -        /// <returns>The user ID (Outlook EntryID) for the given address</returns>
    2.31 -        internal string GetUserId(string address,
    2.32 -                                  Outlook.ContactItem contact = null)
    2.33 -        {
    2.34 -            string id = null;
    2.35 -            Outlook.Folder contactFolder = null;
    2.36 -
    2.37 -            try
    2.38 -            {
    2.39 -                if (string.IsNullOrEmpty(address) == false)
    2.40 -                {
    2.41 -                    // Search cache
    2.42 -                    if (id == null)
    2.43 -                    {
    2.44 -                        try
    2.45 -                        {
    2.46 -                            id = this.userIdCache[address];
    2.47 -                        }
    2.48 -                        catch
    2.49 -                        {
    2.50 -                            id = null;
    2.51 -                        }
    2.52 -                    }
    2.53 -
    2.54 -                    // Handle myself user ID calculation
    2.55 -                    if (id == null)
    2.56 -                    {
    2.57 -                        // Check if the address is myself
    2.58 -                        if (PEPIdentity.GetIsOwnIdentity(address))
    2.59 -                        {
    2.60 -                            id = PEPSettings.PEP_OWN_USER_ID;
    2.61 -                            this.userIdCache[address] = id;
    2.62 -                        }
    2.63 -                    }
    2.64 -
    2.65 -                    // Use a contact EntryID if available
    2.66 -                    if ((id == null) &&
    2.67 -                        (contact != null))
    2.68 -                    {
    2.69 -                        try
    2.70 -                        {
    2.71 -                            id = contact.EntryID;
    2.72 -                            this.userIdCache[address] = id;
    2.73 -                        }
    2.74 -                        catch
    2.75 -                        {
    2.76 -                            Log.Error("GetUserId: Attempted to use contact but failed.");
    2.77 -                        }
    2.78 -                    }
    2.79 -                }
    2.80 -            }
    2.81 -            catch (Exception ex)
    2.82 -            {
    2.83 -                Globals.StopAndSendCrashReport(ex);
    2.84 -            }
    2.85 -            finally
    2.86 -            {
    2.87 -                if (contactFolder != null)
    2.88 -                {
    2.89 -                    Marshal.FinalReleaseComObject(contactFolder);
    2.90 -                    contactFolder = null;
    2.91 -                }
    2.92 -            }
    2.93 -
    2.94 -            return (id);
    2.95 -        }
    2.96 -
    2.97 -        /// <summary>
    2.98          /// Create a new Outlook MailItem from the given PEPMessage and send it.
    2.99          /// The sent message will not be processed by the 'Application_ItemSend' event.
   2.100          /// WARNING: Exchange ActiveSync accounts ignore the deleteAfterSend parameter (always false).