Accept email address automatically

When we do Gerrit development work we start by creating a "gerrit
test site". During test site initialization, normally we select
"DEVELOPMENT_BECOME_ANY_ACCOUNT" mode. However, to setup test user
accounts we need to register users. For every test-user we add
to the test site, Gerrit wants to send a confirmation email which
we need to receive and then click the link in it.
This change will enable Gerrit accept email address automatically
in "DEVELOPMENT_BECOME_ANY_ACCOUNT" mode.

Change-Id: Iec6f34e0ecd335b04ef5bf1a5d61c8a906cfd19f
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java
index 1117455..0b76558 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java
@@ -72,7 +72,7 @@
       AsyncCallback<VoidResult> callback);
 
   @SignInRequired
-  void registerEmail(String address, AsyncCallback<VoidResult> callback);
+  void registerEmail(String address, AsyncCallback<Account> callback);
 
   @SignInRequired
   void validateEmail(String token, AsyncCallback<VoidResult> callback);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
index 1d4aeca..53a2b58 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
@@ -57,6 +57,7 @@
   String buttonClearPassword();
   String buttonGeneratePassword();
   String invalidUserName();
+  String invalidUserEmail();
 
   String sshKeyInvalid();
   String sshKeyAlgorithm();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
index a1c96c7..ffc5218 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
@@ -38,7 +38,7 @@
 buttonClearPassword = Clear Password
 buttonGeneratePassword = Generate Password
 invalidUserName = Username must contain only letters, numbers, _, - or .
-
+invalidUserEmail = Email format is wrong.
 sshKeyInvalid = Invalid Key
 sshKeyAlgorithm = Algorithm
 sshKeyKey = Key
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
index 8fe4d5f..aa179ab 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.client.account;
 
+import com.google.gerrit.client.ErrorDialog;
 import com.google.gerrit.client.Gerrit;
 import com.google.gerrit.client.rpc.GerritCallback;
 import com.google.gerrit.client.ui.OnEditEnabler;
@@ -21,6 +22,7 @@
 import com.google.gerrit.reviewdb.AccountExternalId;
 import com.google.gerrit.reviewdb.ContactInformation;
 import com.google.gerrit.reviewdb.Account.FieldName;
+import com.google.gerrit.reviewdb.AuthType;
 import com.google.gwt.event.dom.client.ChangeEvent;
 import com.google.gwt.event.dom.client.ChangeHandler;
 import com.google.gwt.event.dom.client.ClickEvent;
@@ -38,7 +40,6 @@
 import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
 import com.google.gwtexpui.globalkey.client.NpTextBox;
 import com.google.gwtexpui.user.client.AutoCenterDialogBox;
-import com.google.gwtjsonrpc.client.VoidResult;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -205,30 +206,7 @@
 
   private void postLoad() {
     if (haveAccount && haveEmails) {
-      if (currentEmail != null) {
-        boolean found = false;
-        for (int i = 0; i < emailPick.getItemCount(); i++) {
-          if (currentEmail.equals(emailPick.getValue(i))) {
-            emailPick.setSelectedIndex(i);
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          emailPick.addItem(currentEmail);
-          emailPick.setSelectedIndex(emailPick.getItemCount() - 1);
-        }
-      }
-      if (emailPick.getItemCount() > 0) {
-        emailPick.setVisible(true);
-        emailPick.setEnabled(true);
-        if (canRegisterNewEmail()) {
-          final String t = Util.C.buttonOpenRegisterNewEmail();
-          emailPick.addItem("... " + t + "  ", t);
-        }
-      } else {
-        emailPick.setVisible(false);
-      }
+      updateEmailList();
       registerNewEmail.setEnabled(true);
     }
     display();
@@ -270,14 +248,24 @@
         event.cancel();
         final String addr = inEmail.getText().trim();
         if (!addr.contains("@")) {
+          new ErrorDialog(Util.C.invalidUserEmail()).center();
           return;
         }
 
         inEmail.setEnabled(false);
         register.setEnabled(false);
-        Util.ACCOUNT_SEC.registerEmail(addr, new GerritCallback<VoidResult>() {
-          public void onSuccess(VoidResult result) {
+        Util.ACCOUNT_SEC.registerEmail(addr, new GerritCallback<Account>() {
+          public void onSuccess(Account currentUser) {
             box.hide();
+            if (Gerrit.getConfig().getAuthType() == AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT) {
+              currentEmail = addr;
+              if (emailPick.getItemCount() == 0) {
+                onSaveSuccess(currentUser);
+              } else {
+                save.setEnabled(true);
+              }
+              updateEmailList();
+            }
           }
 
           @Override
@@ -309,7 +297,9 @@
     buttons.add(register);
     buttons.add(cancel);
 
-    body.add(new HTML(Util.C.descRegisterNewEmail()));
+    if (Gerrit.getConfig().getAuthType() != AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT) {
+      body.add(new HTML(Util.C.descRegisterNewEmail()));
+    }
     body.add(inEmail);
     body.add(buttons);
 
@@ -367,4 +357,39 @@
   ContactInformation toContactInformation() {
     return null;
   }
+
+  private int emailListIndexOf(String value) {
+    for (int i = 0; i < emailPick.getItemCount(); i++) {
+      if (value.equalsIgnoreCase(emailPick.getValue(i))) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  private void updateEmailList() {
+    if (currentEmail != null) {
+      int index = emailListIndexOf(currentEmail);
+      if (index == -1) {
+        emailPick.addItem(currentEmail);
+        emailPick.setSelectedIndex(emailPick.getItemCount() - 1);
+      } else {
+        emailPick.setSelectedIndex(index);
+      }
+    }
+    if (emailPick.getItemCount() > 0) {
+      emailPick.setVisible(true);
+      emailPick.setEnabled(true);
+      if (canRegisterNewEmail()) {
+        final String t = Util.C.buttonOpenRegisterNewEmail();
+        int index = emailListIndexOf(t);
+        if (index != -1) {
+          emailPick.removeItem(index);
+        }
+        emailPick.addItem("... " + t + "  ", t);
+      }
+    } else {
+      emailPick.setVisible(false);
+    }
+  }
 }
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/AccountSecurityImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/AccountSecurityImpl.java
index 77662a1..df71700 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/AccountSecurityImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/AccountSecurityImpl.java
@@ -26,6 +26,7 @@
 import com.google.gerrit.reviewdb.AccountExternalId;
 import com.google.gerrit.reviewdb.AccountGroup;
 import com.google.gerrit.reviewdb.AccountSshKey;
+import com.google.gerrit.reviewdb.AuthType;
 import com.google.gerrit.reviewdb.ContactInformation;
 import com.google.gerrit.reviewdb.ContributorAgreement;
 import com.google.gerrit.reviewdb.ReviewDb;
@@ -270,18 +271,27 @@
   }
 
   public void registerEmail(final String address,
-      final AsyncCallback<VoidResult> cb) {
-    try {
-      final RegisterNewEmailSender sender;
-      sender = registerNewEmailFactory.create(address);
-      sender.send();
-      cb.onSuccess(VoidResult.INSTANCE);
-    } catch (EmailException e) {
-      log.error("Cannot send email verification message to " + address, e);
-      cb.onFailure(e);
-    } catch (RuntimeException e) {
-      log.error("Cannot send email verification message to " + address, e);
-      cb.onFailure(e);
+      final AsyncCallback<Account> cb) {
+    if (authConfig.getAuthType() == AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT) {
+      try {
+        accountManager.link(user.get().getAccountId(),
+            AuthRequest.forEmail(address));
+        cb.onSuccess(user.get().getAccount());
+      } catch (AccountException e) {
+        cb.onFailure(e);
+      }
+    } else {
+      try {
+        final RegisterNewEmailSender sender;
+        sender = registerNewEmailFactory.create(address);
+        sender.send();
+      } catch (EmailException e) {
+        log.error("Cannot send email verification message to " + address, e);
+        cb.onFailure(e);
+      } catch (RuntimeException e) {
+        log.error("Cannot send email verification message to " + address, e);
+        cb.onFailure(e);
+      }
     }
   }