Fetch GitHub full name and e-mail from the plugin profile screen

Allows a user to select his details from the GitHub profile
displayed at /plugins/github-plugin/static/account.html

It is particularly useful when switching from a public identity
(e.g. when using GitHub plugin for OpenSource projects) to a private
use within a company. You can go to the account.html page 
and select an alternative e-mail address and Gerrit will be 
automatically updated.

Change-Id: Ib4ac50194c65336e64d2ef12e8463eccd42ad8e5
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
index bb2554c..1b9d536 100644
--- a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
+++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
@@ -197,7 +197,12 @@
   }
 
   private String getScopesKeyFromCookie(HttpServletRequest request) {
-    for(Cookie cookie : request.getCookies()) {
+    Cookie[] cookies = request.getCookies();
+    if(cookies == null) {
+      return null;
+    }
+
+    for(Cookie cookie : cookies) {
       if(cookie.getName().equalsIgnoreCase("scope")) {
         return cookie.getValue();
       }
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java
index 085125a..2ed144c 100644
--- a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java
+++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java
@@ -47,8 +47,6 @@
   public final String gitHubClientSecret;
   public final String logoutRedirectUrl;
   public final String httpHeader;
-  public final String httpDisplaynameHeader;
-  public final String httpEmailHeader;
   public final String gitHubOAuthUrl;
   public final String oAuthFinalRedirectUrl;
   public final String gitHubOAuthAccessTokenUrl;
@@ -61,8 +59,6 @@
   public GitHubOAuthConfig(CompositeConfig config)
       throws MalformedURLException {
     httpHeader = config.getString("auth", null, "httpHeader");
-    httpDisplaynameHeader = config.getString("auth", null, "httpDisplaynameHeader");
-    httpEmailHeader = config.getString("auth", null, "httpEmailHeader");
     gitHubUrl = dropTrailingSlash(
         Objects.firstNonNull(config.getString(CONF_SECTION, null, "url"),
             GITHUB_URL));
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthWebFilter.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthWebFilter.java
index 10985fd..bc64fde 100644
--- a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthWebFilter.java
+++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthWebFilter.java
@@ -119,9 +119,7 @@
       HttpServletRequest httpRequest, OAuthCookie authCookie) {
     httpRequest =
         authCookie == null ? httpRequest : new AuthenticatedHttpRequest(
-            httpRequest, config.httpHeader, authCookie.user,
-            config.httpDisplaynameHeader, authCookie.fullName,
-            config.httpEmailHeader, authCookie.email);
+            httpRequest, config.httpHeader, authCookie.user);
     return httpRequest;
   }
 
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/AccountController.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/AccountController.java
index 20fb53b..1c5b250 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/AccountController.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/AccountController.java
@@ -16,6 +16,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 
@@ -34,12 +35,23 @@
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import com.google.gerrit.extensions.restapi.RawInput;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountException;
+import com.google.gerrit.server.account.AccountManager;
 import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AddSshKey;
+import com.google.gerrit.server.account.AuthRequest;
 import com.google.gerrit.server.account.GetSshKeys;
+import com.google.gerrit.server.account.PutPreferred;
 import com.google.gerrit.server.account.GetSshKeys.SshKeyInfo;
+import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
+import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
 
 public class AccountController implements VelocityController {
@@ -48,17 +60,46 @@
       .getLogger(VelocityControllerServlet.class);
   private final AddSshKey restAddSshKey;
   private final GetSshKeys restGetSshKeys;
+  private final AccountManager accountManager;
+  private final Provider<ReviewDb> dbProvider;
+  private final AccountCache accountCache;
 
   @Inject
   public AccountController(final AddSshKey restAddSshKey,
-      final GetSshKeys restGetSshKeys) {
+      final GetSshKeys restGetSshKeys, final AccountManager accountManager,
+      final Provider<ReviewDb> dbProvider, final AccountCache accountCache) {
     this.restAddSshKey = restAddSshKey;
     this.restGetSshKeys = restGetSshKeys;
+    this.accountManager = accountManager;
+    this.dbProvider = dbProvider;
+    this.accountCache = accountCache;
   }
 
   public void doAction(IdentifiedUser user, GitHubLogin hubLogin,
       HttpServletRequest req, HttpServletResponse resp, ControllerErrors errors)
       throws ServletException, IOException {
+    setAccountIdentity(user, req);
+    setAccoutPublicKeys(user, hubLogin, req);
+  }
+
+  private void setAccountIdentity(IdentifiedUser user, HttpServletRequest req) throws ServletException {
+    String fullName = req.getParameter("fullname");
+    String email = req.getParameter("email");
+    try {
+      accountManager.link(user.getAccountId(), AuthRequest.forEmail(email));
+      Account a = dbProvider.get().accounts().get(user.getAccountId());
+      a.setPreferredEmail(email);
+      a.setFullName(fullName);
+      dbProvider.get().accounts().update(Collections.singleton(a));
+      accountCache.evict(user.getAccountId());
+    } catch (AccountException | OrmException e) {
+      throw new ServletException("Cannot associated email '" + email
+          + "' to current user '" + user + "'", e);
+    }
+  }
+
+  private void setAccoutPublicKeys(IdentifiedUser user, GitHubLogin hubLogin,
+      HttpServletRequest req) throws IOException {
     GHMyself myself = hubLogin.getMyself();
     List<GHVerifiedKey> githubKeys = myself.getPublicVerifiedKeys();
     HashSet<String> gerritKeys = Sets.newHashSet(getCurrentGerritSshKeys(user));
@@ -74,7 +115,8 @@
     }
   }
 
-  private List<String> getCurrentGerritSshKeys(final IdentifiedUser user) throws IOException {
+  private List<String> getCurrentGerritSshKeys(final IdentifiedUser user)
+      throws IOException {
     AccountResource res = new AccountResource(user);
     try {
       List<SshKeyInfo> keysInfo = restGetSshKeys.apply(res);
diff --git a/github-plugin/src/main/resources/static/account.html b/github-plugin/src/main/resources/static/account.html
index ed51218..e352ebd 100644
--- a/github-plugin/src/main/resources/static/account.html
+++ b/github-plugin/src/main/resources/static/account.html
@@ -51,7 +51,15 @@
 						value="$!myself.name" readonly="readonly" /></li>
 
 					<li><label for="eMail">e-Mail:</label> 
-							<input maxlength="50" value="$!myself.email" type="text" name="email" readonly="readonly" /></li>
+						<select id="email" name="email">
+						#foreach ( $email in $myself.emails )
+							#if ( $email == $!myself.email )
+							<option selected="selected">$email</option>
+							#else
+							<option>$email</option>
+							#end
+						#end
+						</select>
 				</ul>
 
 				<h5>Import GitHub SSH Public Keys</h5>