Bug 1315662 - delete SMTP server login credentials when deleting the account or if hostname/username changes. r=mkmelin a=jorgk
authoraceman <acelists@atlas.sk>
Sat, 15 Jun 2019 09:03:00 +0200
changeset 35562 ddad01cf38846c38d01e20316f82a3eb6e22937d
parent 35561 b22f400e1734a9ad5f058cd750abab2fb7aa75f2
child 35563 57264934515548042137b9f39421bdd8285eac6f
push id391
push userclokep@gmail.com
push dateTue, 09 Jul 2019 00:57:56 +0000
reviewersmkmelin, jorgk
bugs1315662
Bug 1315662 - delete SMTP server login credentials when deleting the account or if hostname/username changes. r=mkmelin a=jorgk
mailnews/base/prefs/content/am-smtp.js
mailnews/compose/src/nsSmtpServer.cpp
mailnews/compose/src/nsSmtpServer.h
--- a/mailnews/base/prefs/content/am-smtp.js
+++ b/mailnews/base/prefs/content/am-smtp.js
@@ -48,16 +48,21 @@ var gSmtpServerListWindow = {
     // confirm deletion
     let cancel = Services.prompt.confirmEx(window,
       this.mBundle.getString("smtpServers-confirmServerDeletionTitle"),
       this.mBundle.getFormattedString("smtpServers-confirmServerDeletion",
                                       [server.hostname], 1),
       Services.prompt.STD_YES_NO_BUTTONS, null, null, null, null, { });
 
     if (!cancel) {
+      // Remove password information first.
+      try {
+        server.forgetPassword();
+      } catch (e) { /* It is OK if this fails. */ }
+      // Remove the server.
       MailServices.smtp.deleteServer(server);
       parent.replaceWithDefaultSmtpServer(server.key);
       this.refreshServerList("", true);
     }
   },
 
   onAddServer(aEvent) {
     this.openServerEditor(null);
--- a/mailnews/compose/src/nsSmtpServer.cpp
+++ b/mailnews/compose/src/nsSmtpServer.cpp
@@ -101,36 +101,58 @@ nsresult nsSmtpServer::getPrefs() {
     branchName.AssignLiteral("mail.smtpserver.default.");
     rv = prefs->GetBranch(branchName.get(), getter_AddRefs(mDefPrefBranch));
     if (NS_FAILED(rv)) return rv;
   }
 
   return NS_OK;
 }
 
+// This function is intentionally called the same as in nsIMsgIncomingServer.
+nsresult
+nsSmtpServer::OnUserOrHostNameChanged(const nsACString& oldName,
+                                      const nsACString& newName,
+                                      bool hostnameChanged)
+{
+  // Reset password so that users are prompted for new password for the new user/host.
+  (void)ForgetPassword();
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsSmtpServer::GetHostname(nsACString &aHostname) {
   nsCString result;
   nsresult rv = mPrefBranch->GetCharPref("hostname", result);
   if (NS_FAILED(rv))
     aHostname.Truncate();
   else
     aHostname = result;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSmtpServer::SetHostname(const nsACString &aHostname) {
+  nsCString oldName;
+  nsresult rv = GetHostname(oldName);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // A few things to take care of if we're changing the hostname.
+  if (!oldName.Equals(aHostname, nsCaseInsensitiveCStringComparator())) {
+    rv = OnUserOrHostNameChanged(oldName, aHostname, true);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   if (!aHostname.IsEmpty())
     return mPrefBranch->SetCharPref("hostname", aHostname);
 
   // If the pref value is already empty, ClearUserPref will return
   // NS_ERROR_UNEXPECTED, so don't check the rv here.
-  mPrefBranch->ClearUserPref("hostname");
+  (void)mPrefBranch->ClearUserPref("hostname");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSmtpServer::GetDescription(nsACString &aDescription) {
   nsCString temp;
   mPrefBranch->GetCharPref("description", temp);
   aDescription.Assign(temp);
@@ -240,22 +262,32 @@ nsSmtpServer::GetUsername(nsACString &aU
     aUsername.Truncate();
   else
     aUsername = result;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSmtpServer::SetUsername(const nsACString &aUsername) {
+  // Need to take care of few things if we're changing the username.
+  nsCString oldName;
+  nsresult rv = GetUsername(oldName);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!oldName.Equals(aUsername)) {
+    rv = OnUserOrHostNameChanged(oldName, aUsername, false);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   if (!aUsername.IsEmpty())
     return mPrefBranch->SetCharPref("username", aUsername);
 
   // If the pref value is already empty, ClearUserPref will return
   // NS_ERROR_UNEXPECTED, so don't check the rv here.
-  mPrefBranch->ClearUserPref("username");
+  (void)mPrefBranch->ClearUserPref("username");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSmtpServer::GetClientid(nsACString &aClientid) {
   nsresult rv;
   rv = mPrefBranch->GetCharPref("clientid", aClientid);
   if (NS_FAILED(rv)) {
@@ -517,38 +549,26 @@ nsSmtpServer::GetUsernamePasswordWithUI(
 NS_IMETHODIMP
 nsSmtpServer::ForgetPassword() {
   nsresult rv;
   nsCOMPtr<nsILoginManager> loginMgr =
       do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Get the current server URI without the username
-  nsAutoCString serverUri(NS_LITERAL_CSTRING("smtp://"));
-
-  nsCString hostname;
-  rv = GetHostname(hostname);
-
-  if (NS_SUCCEEDED(rv) && !hostname.IsEmpty()) {
-    nsCString escapedHostname;
-    MsgEscapeString(hostname, nsINetUtil::ESCAPE_URL_PATH, escapedHostname);
-    // not all servers have a hostname
-    serverUri.Append(escapedHostname);
-  }
-
-  NS_ConvertUTF8toUTF16 currServer(serverUri);
+  NS_ConvertASCIItoUTF16 serverUri(GetServerURIInternal(false));
 
   nsCString serverCUsername;
   rv = GetUsername(serverCUsername);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ConvertUTF8toUTF16 serverUsername(serverCUsername);
 
   nsTArray<RefPtr<nsILoginInfo>> logins;
-  rv = loginMgr->FindLogins(currServer, EmptyString(), currServer, logins);
+  rv = loginMgr->FindLogins(serverUri, EmptyString(), serverUri, logins);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // There should only be one-login stored for this url, however just in case
   // there isn't.
   nsString username;
   for (uint32_t i = 0; i < logins.Length(); ++i) {
     if (NS_SUCCEEDED(logins[i]->GetUsername(username)) &&
         username.Equals(serverUsername)) {
--- a/mailnews/compose/src/nsSmtpServer.h
+++ b/mailnews/compose/src/nsSmtpServer.h
@@ -29,14 +29,16 @@ class nsSmtpServer : public nsISmtpServe
   nsCOMPtr<nsIPrefBranch> mPrefBranch;
   nsCOMPtr<nsIPrefBranch> mDefPrefBranch;
 
   nsresult getPrefs();
   void getIntPrefWithDefault(const char *prefName, int32_t *val,
                              int32_t defval);
   nsresult GetPasswordWithoutUI();
   nsCString GetServerURIInternal(const bool aIncludeUsername);
-
+  nsresult OnUserOrHostNameChanged(const nsACString& oldName,
+                                   const nsACString& newName,
+                                   bool hostnameChanged);
   nsString m_password;
   bool m_logonFailed;
 };
 
 #endif