Merge branch 'stable-3.4' into stable-3.5

* stable-3.4:
  Set plugin version to 3.4.7
  Fire git ref update events for all imported refs
  PluginVelocityRuntimeProvider: Fix warning flagged by error prone
  Fix default scopes resolution

Change-Id: Ida702ab138d136e9ef6d65ad1e06af0611a86c32
diff --git a/github-oauth/pom.xml b/github-oauth/pom.xml
index 7868a8b..0b7a9b5 100644
--- a/github-oauth/pom.xml
+++ b/github-oauth/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>com.googlesource.gerrit.plugins.github</groupId>
     <artifactId>github-parent</artifactId>
-    <version>3.4.7</version>
+    <version>3.5.0.1</version>
   </parent>
   <artifactId>github-oauth</artifactId>
   <name>Gerrit Code Review - GitHub OAuth login</name>
diff --git a/github-plugin/pom.xml b/github-plugin/pom.xml
index 757372f..fed554e 100644
--- a/github-plugin/pom.xml
+++ b/github-plugin/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <artifactId>github-parent</artifactId>
     <groupId>com.googlesource.gerrit.plugins.github</groupId>
-    <version>3.4.7</version>
+    <version>3.5.0.1</version>
   </parent>
 
   <artifactId>github-plugin</artifactId>
diff --git a/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImporter.java b/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImporter.java
index 19ed82f..e826880 100644
--- a/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImporter.java
+++ b/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImporter.java
@@ -17,6 +17,7 @@
 import com.google.gerrit.entities.Account;
 import com.google.gerrit.server.ServerInitiated;
 import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.account.externalids.ExternalIdFactory;
 import com.google.gerrit.server.notedb.Sequences;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -28,21 +29,25 @@
 public class AccountImporter {
   private final Sequences sequences;
   private final Provider<AccountsUpdate> accountsUpdateProvider;
+  private final ExternalIdFactory externalIdFactory;
 
   @Inject
   public AccountImporter(
-      Sequences sequences, @ServerInitiated Provider<AccountsUpdate> accountsUpdateProvider) {
+      Sequences sequences,
+      @ServerInitiated Provider<AccountsUpdate> accountsUpdateProvider,
+      ExternalIdFactory externalIdFactory) {
     this.sequences = sequences;
     this.accountsUpdateProvider = accountsUpdateProvider;
+    this.externalIdFactory = externalIdFactory;
   }
 
   public Account.Id importAccount(String login, String name, String email)
       throws IOException, ConfigInvalidException {
     Account.Id id = Account.id(sequences.nextAccountId());
     List<ExternalId> extIds = new ArrayList<>();
-    extIds.add(ExternalId.createEmail(id, email));
-    extIds.add(ExternalId.create(ExternalId.SCHEME_GERRIT, login, id));
-    extIds.add(ExternalId.create(ExternalId.SCHEME_USERNAME, login, id));
+    extIds.add(externalIdFactory.createEmail(id, email));
+    extIds.add(externalIdFactory.create(ExternalId.SCHEME_GERRIT, login, id));
+    extIds.add(externalIdFactory.create(ExternalId.SCHEME_USERNAME, login, id));
     AccountState accountUpdate =
         accountsUpdateProvider
             .get()
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/CreateProjectStep.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/CreateProjectStep.java
index 870a13b..f25e6ee 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/CreateProjectStep.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/CreateProjectStep.java
@@ -190,7 +190,6 @@
   private void setProjectSettings() {
     projectConfig.updateProject(
         b -> {
-          b.setParent(config.getBaseProject(getRepository().isPrivate()));
           b.setDescription(description);
           b.setSubmitType(SubmitType.MERGE_IF_NECESSARY);
           b.setBooleanConfig(
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitCloneStep.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitCloneStep.java
index 8923b52..12e5101 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitCloneStep.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitCloneStep.java
@@ -16,6 +16,7 @@
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.GerritApi;
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
+import com.google.gerrit.extensions.api.projects.ProjectInput;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -58,6 +59,7 @@
   private final DynamicSet<ProjectDeletedListener> deletedListeners;
   private final ProjectCache projectCache;
   private final GitRepositoryManager repoManager;
+  private final String projectName;
   private final GitReferenceUpdated referenceUpdated;
   private final Provider<IdentifiedUser> identifiedUser;
 
@@ -89,7 +91,8 @@
     this.context = context;
     this.organisation = organisation;
     this.repository = repository;
-    this.destinationDirectory = prepareTargetGitDirectory(gitDir, organisation, repository);
+    this.projectName = organisation + "/" + repository;
+    this.destinationDirectory = prepareTargetGitDirectory(gitDir, this.projectName);
     this.deletedListeners = deletedListeners;
     this.projectCache = projectCache;
     this.repoManager = repoManager;
@@ -97,9 +100,8 @@
     this.identifiedUser = identifiedUser;
   }
 
-  private static File prepareTargetGitDirectory(File gitDir, String organisation, String repository)
+  private static File prepareTargetGitDirectory(File gitDir, String projectName)
       throws GitException {
-    String projectName = organisation + "/" + repository;
     File repositoryDir = new File(gitDir, projectName + ".git");
     if (repositoryDir.exists()) {
       throw new GitDestinationAlreadyExistsException(projectName);
@@ -107,11 +109,12 @@
     return repositoryDir;
   }
 
-  private String createNewProject() throws GitException {
-    String projectName = organisation + "/" + repository;
+  private void createNewProject() throws GitException {
     try (ManualRequestContext requestContext = context.openAs(config.importAccountId)) {
-      gerritApi.projects().create(projectName).get();
-      return projectName;
+      ProjectInput pi = new ProjectInput();
+      pi.name = projectName;
+      pi.parent = config.getBaseProject(getRepository().isPrivate());
+      gerritApi.projects().create(pi).get();
     } catch (ResourceConflictException e) {
       throw new GitDestinationAlreadyExistsException(projectName);
     } catch (RestApiException e) {
@@ -121,7 +124,8 @@
 
   @Override
   public void doImport(ProgressMonitor progress) throws GitException {
-    Project.NameKey projectName = Project.nameKey(createNewProject());
+    createNewProject();
+    Project.NameKey key = Project.nameKey(projectName);
     String sourceUri = getSourceUri();
     try (Git git = Git.open(destinationDirectory)) {
       FetchCommand fetch = git.fetch().setRefSpecs("refs/*:refs/*").setRemote(sourceUri);
@@ -134,7 +138,7 @@
       AccountState accountState = identifiedUser.get().state();
       for (Ref ref : git.getRepository().getRefDatabase().getRefs()) {
         referenceUpdated.fire(
-            projectName, ref.getName(), ObjectId.zeroId(), ref.getObjectId(), accountState);
+            key, ref.getName(), ObjectId.zeroId(), ref.getObjectId(), accountState);
       }
     } catch (IOException | GitAPIException e) {
       LOG.error("Unable to fetch from {} into {}", sourceUri, destinationDirectory, e);
@@ -154,7 +158,6 @@
     }
 
     try {
-      String projectName = organisation + "/" + repository;
       Project.NameKey key = Project.nameKey(projectName);
       cleanJGitCache(key);
       FileUtils.deleteDirectory(gitDirectory);
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java
index cb71e78..f706539 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java
@@ -26,6 +26,7 @@
 import com.google.gerrit.server.account.AccountImporter;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.account.externalids.ExternalIds;
+import com.google.gerrit.server.config.AuthConfig;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
@@ -79,6 +80,7 @@
   private final String repoName;
   private final int prId;
   private final GitRepositoryManager repoMgr;
+  private final AuthConfig authConfig;
   private final int jobIndex;
   private final ExternalIds externalIds;
   private PullRequestCreateChange createChange;
@@ -96,10 +98,12 @@
       GitHubRepository.Factory gitHubRepoFactory,
       ScopedProvider<GitHubLogin> ghLoginProvider,
       ExternalIds externalIds,
+      AuthConfig authConfig,
       @Assisted("index") int jobIndex,
       @Assisted("organisation") String organisation,
       @Assisted("name") String repoName,
       @Assisted int pullRequestId) {
+    this.authConfig = authConfig;
     this.jobIndex = jobIndex;
     this.repoMgr = repoMgr;
     this.ghLogin = ghLoginProvider.get();
@@ -217,8 +221,9 @@
 
   private Optional<ExternalId> externalIdByScheme(String scheme, String id) {
     try {
-      return externalIds.get(ExternalId.Key.create(scheme, id));
-    } catch (IOException | ConfigInvalidException e) {
+      return externalIds.get(
+          ExternalId.Key.create(scheme, id, authConfig.isUserNameCaseInsensitive()));
+    } catch (IOException e) {
       LOG.error("Unable to get external id for " + scheme + ":" + id, e);
       return Optional.empty();
     }
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubGroupBackend.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubGroupBackend.java
index 5f74078..9e96c2b 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubGroupBackend.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubGroupBackend.java
@@ -30,6 +30,7 @@
 import com.google.gerrit.server.account.GroupMembership;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
+import com.google.inject.Provider;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
@@ -41,12 +42,16 @@
   private static final Logger log = LoggerFactory.getLogger(GitHubGroupBackend.class);
   private final GitHubGroupMembership.Factory ghMembershipProvider;
   private final GitHubGroupsCache ghOrganisationCache;
+  private final Provider<CurrentUser> currentUserProvider;
 
   @Inject
   GitHubGroupBackend(
-      GitHubGroupMembership.Factory ghMembershipProvider, GitHubGroupsCache ghOrganisationCache) {
+      GitHubGroupMembership.Factory ghMembershipProvider,
+      GitHubGroupsCache ghOrganisationCache,
+      Provider<CurrentUser> currentUserProvider) {
     this.ghMembershipProvider = ghMembershipProvider;
     this.ghOrganisationCache = ghOrganisationCache;
+    this.currentUserProvider = currentUserProvider;
   }
 
   @Override
@@ -112,6 +117,13 @@
 
   @Override
   public GroupMembership membershipsOf(CurrentUser user) {
+    CurrentUser currentUser = currentUserProvider.get();
+    if (!currentUser.isIdentifiedUser()
+        || !currentUser.asIdentifiedUser().getAccountId().equals(user.getAccountId())) {
+      // Do not allow to perform group discovery of other users
+      return GroupMembership.EMPTY;
+    }
+
     String username = user.getUserName().orElse(null);
     if (Strings.isNullOrEmpty(username)) {
       return GroupMembership.EMPTY;
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 e2b8041..23edcbc 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
@@ -32,7 +32,9 @@
 import com.google.gerrit.server.account.AuthRequest;
 import com.google.gerrit.server.account.AuthResult;
 import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.account.externalids.ExternalIdFactory;
 import com.google.gerrit.server.account.externalids.ExternalIds;
+import com.google.gerrit.server.config.AuthConfig;
 import com.google.gerrit.server.restapi.account.AddSshKey;
 import com.google.gerrit.server.restapi.account.GetSshKeys;
 import com.google.gerrit.server.restapi.account.PutName;
@@ -68,6 +70,9 @@
   private final PutName putName;
   private final Provider<AccountsUpdate> accountsUpdateProvider;
   private final ExternalIds externalIds;
+  private final ExternalIdFactory externalIdFactory;
+  private final AuthRequest.Factory authRequestFactory;
+  private final AuthConfig authConfig;
 
   @Inject
   public AccountController(
@@ -78,7 +83,10 @@
       final PutPreferred putPreferred,
       final PutName putName,
       @ServerInitiated final Provider<AccountsUpdate> accountsUpdateProvider,
-      final ExternalIds externalIds) {
+      final ExternalIds externalIds,
+      final ExternalIdFactory externalIdFactory,
+      final AuthRequest.Factory authRequestFactory,
+      final AuthConfig authConfig) {
     this.restAddSshKey = restAddSshKey;
     this.restGetSshKeys = restGetSshKeys;
     this.accountManager = accountManager;
@@ -87,6 +95,9 @@
     this.putName = putName;
     this.accountsUpdateProvider = accountsUpdateProvider;
     this.externalIds = externalIds;
+    this.externalIdFactory = externalIdFactory;
+    this.authRequestFactory = authRequestFactory;
+    this.authConfig = authConfig;
   }
 
   @Override
@@ -120,7 +131,7 @@
     String username = req.getParameter("username");
     try {
       Id accountId = user.getAccountId();
-      AuthResult result = accountManager.link(accountId, AuthRequest.forEmail(email));
+      AuthResult result = accountManager.link(accountId, authRequestFactory.createForEmail(email));
       log.debug("Account {} linked to email {}: result = {}", accountId, email, result);
 
       putPreferred.apply(new AccountResource.Email(user, email), null);
@@ -128,11 +139,12 @@
       nameInput.name = fullName;
       putName.apply(user, nameInput);
 
-      ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, username);
+      ExternalId.Key key =
+          ExternalId.Key.create(SCHEME_USERNAME, username, authConfig.isUserNameCaseInsensitive());
       Optional<ExternalId> other;
       try {
         other = externalIds.get(key);
-      } catch (IOException | ConfigInvalidException e) {
+      } catch (IOException e) {
         throw new IllegalArgumentException(
             "Internal error while fetching username='" + username + "'");
       }
@@ -148,7 +160,7 @@
             .update(
                 "Set Username from GitHub",
                 accountId,
-                u -> u.addExternalId(ExternalId.create(key, accountId, null, null)));
+                u -> u.addExternalId(externalIdFactory.create(key, accountId, null, null)));
       } catch (Exception e) {
         throw new IllegalArgumentException(
             "Internal error while trying to set username='" + username + "'");
diff --git a/pom.xml b/pom.xml
index b88f8bd..72d4915 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.googlesource.gerrit.plugins.github</groupId>
   <artifactId>github-parent</artifactId>
-  <version>3.4.7</version>
+  <version>3.5.0.1</version>
   <name>Gerrit Code Review - GitHub integration</name>
   <url>http://www.gerritforge.com</url>
   <packaging>pom</packaging>