]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12531 drop usage of UserIdentity#getLogin and UserIdentity#setLogin (#2139)
authorJacek <jacek.poreda@sonarsource.com>
Thu, 17 Oct 2019 11:54:28 +0000 (13:54 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 17 Oct 2019 18:21:03 +0000 (20:21 +0200)
* remove login generation strategy
* add migration to remove gh login strategy + code review fixes
* support same login for new user and update login for SQ authority

33 files changed:
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
server/sonar-auth-github/src/main/java/org/sonar/auth/github/UserIdentityFactoryImpl.java
server/sonar-auth-github/src/main/java/org/sonar/auth/github/UserIdentityGenerator.java [deleted file]
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubModuleTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubSettingsTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/UserIdentityFactoryImplTest.java
server/sonar-auth-gitlab/src/test/java/org/sonar/auth/gitlab/IntegrationTest.java
server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlIdentityProvider.java
server/sonar-auth-saml/src/test/java/org/sonar/auth/saml/SamlIdentityProviderTest.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/DbVersion80.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyProperty.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/DbVersion80Test.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyPropertyTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyPropertyTest/schema.sql [new file with mode: 0644]
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/CredentialsExternalAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/HttpHeadersAuthentication.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserRegistrarImpl.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserUpdater.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/BaseContextFactoryTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/CredentialsExternalAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/HttpHeadersAuthenticationTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/InitFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuth2CallbackFilterTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuth2ContextFactoryTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/TestUserRegistrar.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserRegistrarImplOrgMembershipSyncTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/UserRegistrarImplTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UpdateLoginActionTest.java
sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java
sonar-plugin-api/src/test/java/org/sonar/api/server/authentication/UserIdentityTest.java

index 7c3f7a2ced9870ac2ca2863c4620aa6c1ea78438..df8a8eb9de5df9627345e2f4d78dae9b5f86143c 100644 (file)
@@ -26,10 +26,8 @@ import javax.annotation.Nullable;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.config.PropertyDefinition;
 
-import static java.lang.String.format;
 import static java.lang.String.valueOf;
 import static org.sonar.api.PropertyType.BOOLEAN;
-import static org.sonar.api.PropertyType.SINGLE_SELECT_LIST;
 import static org.sonar.api.PropertyType.STRING;
 
 public class GitHubSettings {
@@ -42,11 +40,6 @@ public class GitHubSettings {
   private static final String API_URL = "sonar.auth.github.apiUrl";
   private static final String WEB_URL = "sonar.auth.github.webUrl";
 
-  static final String LOGIN_STRATEGY = "sonar.auth.github.loginStrategy";
-  static final String LOGIN_STRATEGY_UNIQUE = "Unique";
-  static final String LOGIN_STRATEGY_PROVIDER_ID = "Same as GitHub login";
-  static final String LOGIN_STRATEGY_DEFAULT_VALUE = LOGIN_STRATEGY_UNIQUE;
-
   private static final String ORGANIZATIONS = "sonar.auth.github.organizations";
 
   private static final String CATEGORY = "security";
@@ -74,10 +67,6 @@ public class GitHubSettings {
     return configuration.getBoolean(ALLOW_USERS_TO_SIGN_UP).orElse(false);
   }
 
-  String loginStrategy() {
-    return configuration.get(LOGIN_STRATEGY).orElse("");
-  }
-
   boolean syncGroups() {
     return configuration.getBoolean(GROUPS_SYNC).orElse(false);
   }
@@ -138,18 +127,6 @@ public class GitHubSettings {
         .defaultValue(valueOf(true))
         .index(4)
         .build(),
-      PropertyDefinition.builder(LOGIN_STRATEGY)
-        .name("Login generation strategy")
-        .description(format("When the login strategy is set to '%s', the user's login will be auto-generated the first time so that it is unique. " +
-          "When the login strategy is set to '%s', the user's login will be the GitHub login.",
-          LOGIN_STRATEGY_UNIQUE, LOGIN_STRATEGY_PROVIDER_ID))
-        .category(CATEGORY)
-        .subCategory(SUBCATEGORY)
-        .type(SINGLE_SELECT_LIST)
-        .defaultValue(LOGIN_STRATEGY_DEFAULT_VALUE)
-        .options(LOGIN_STRATEGY_UNIQUE, LOGIN_STRATEGY_PROVIDER_ID)
-        .index(5)
-        .build(),
       PropertyDefinition.builder(GROUPS_SYNC)
         .name("Synchronize teams as groups")
         .description("For each team he belongs to, the user will be associated to a group named 'Organisation/Team' (if it exists) in SonarQube.")
index a93798a17d6c862fe982fdb5e0acf7209d1169cd..ca0fdb3e623a1d4c66c2fb267136cb8a27e7dd78 100644 (file)
@@ -24,23 +24,13 @@ import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 import org.sonar.api.server.authentication.UserIdentity;
 
-import static org.sonar.auth.github.UserIdentityGenerator.generateLogin;
-import static org.sonar.auth.github.UserIdentityGenerator.generateName;
-
 public class UserIdentityFactoryImpl implements UserIdentityFactory {
 
-  private final GitHubSettings settings;
-
-  public UserIdentityFactoryImpl(GitHubSettings settings) {
-    this.settings = settings;
-  }
-
   @Override
   public UserIdentity create(GsonUser user, @Nullable String email, @Nullable List<GsonTeam> teams) {
     UserIdentity.Builder builder = UserIdentity.builder()
       .setProviderId(user.getId())
       .setProviderLogin(user.getLogin())
-      .setLogin(generateLogin(user, settings.loginStrategy()))
       .setName(generateName(user))
       .setEmail(email);
     if (teams != null) {
@@ -51,4 +41,9 @@ public class UserIdentityFactoryImpl implements UserIdentityFactory {
     return builder.build();
   }
 
+  private static String generateName(GsonUser gson) {
+    String name = gson.getName();
+    return name == null || name.isEmpty() ? gson.getLogin() : name;
+  }
+
 }
diff --git a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/UserIdentityGenerator.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/UserIdentityGenerator.java
deleted file mode 100644 (file)
index 4b3dbdf..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.auth.github;
-
-import static java.lang.String.format;
-import static org.sonar.auth.github.GitHubSettings.LOGIN_STRATEGY_PROVIDER_ID;
-import static org.sonar.auth.github.GitHubSettings.LOGIN_STRATEGY_UNIQUE;
-
-class UserIdentityGenerator {
-
-  private UserIdentityGenerator() {
-    // Only static method
-  }
-
-  static String generateLogin(GsonUser gsonUser, String loginStrategy) {
-    switch (loginStrategy) {
-      case LOGIN_STRATEGY_PROVIDER_ID:
-        return gsonUser.getLogin();
-      case LOGIN_STRATEGY_UNIQUE:
-        return generateUniqueLogin(gsonUser);
-      default:
-        throw new IllegalStateException(format("Login strategy not supported : %s", loginStrategy));
-    }
-  }
-
-  static String generateName(GsonUser gson) {
-    String name = gson.getName();
-    return name == null || name.isEmpty() ? gson.getLogin() : name;
-  }
-
-  private static String generateUniqueLogin(GsonUser gsonUser) {
-    return format("%s@%s", gsonUser.getLogin(), GitHubIdentityProvider.KEY);
-  }
-}
index ac78fd84048f8d794d6097245d32cb0d9793c2f9..3487662348170bdcc64a44b18059eb95a50f4558 100644 (file)
@@ -29,7 +29,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.sonar.auth.github.GitHubSettings.LOGIN_STRATEGY_DEFAULT_VALUE;
 
 public class GitHubIdentityProviderTest {
 
@@ -55,7 +54,6 @@ public class GitHubIdentityProviderTest {
   public void is_enabled() {
     settings.setProperty("sonar.auth.github.clientId.secured", "id");
     settings.setProperty("sonar.auth.github.clientSecret.secured", "secret");
-    settings.setProperty("sonar.auth.github.loginStrategy", LOGIN_STRATEGY_DEFAULT_VALUE);
     settings.setProperty("sonar.auth.github.enabled", true);
     assertThat(underTest.isEnabled()).isTrue();
 
@@ -176,7 +174,6 @@ public class GitHubIdentityProviderTest {
     if (enabled) {
       settings.setProperty("sonar.auth.github.clientId.secured", "id");
       settings.setProperty("sonar.auth.github.clientSecret.secured", "secret");
-      settings.setProperty("sonar.auth.github.loginStrategy", LOGIN_STRATEGY_DEFAULT_VALUE);
       settings.setProperty("sonar.auth.github.enabled", true);
     } else {
       settings.setProperty("sonar.auth.github.enabled", false);
index 0589b7a2e274f3e885632616e79eddc9ef6d6257..8903a766e152b935e86db7909341dc3d08a7a0c4 100644 (file)
@@ -31,7 +31,7 @@ public class GitHubModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new GitHubModule().configure(container);
-    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 14);
+    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 13);
   }
 
 }
index 422990b7e85b395792b5fda356301fd89c91b5ff..4e466aa92ac08cde2c168fe4e37a99b472953ce9 100644 (file)
@@ -24,8 +24,6 @@ import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.internal.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.auth.github.GitHubSettings.LOGIN_STRATEGY_DEFAULT_VALUE;
-import static org.sonar.auth.github.GitHubSettings.LOGIN_STRATEGY_PROVIDER_ID;
 
 public class GitHubSettingsTest {
 
@@ -37,7 +35,6 @@ public class GitHubSettingsTest {
   public void is_enabled() {
     settings.setProperty("sonar.auth.github.clientId.secured", "id");
     settings.setProperty("sonar.auth.github.clientSecret.secured", "secret");
-    settings.setProperty("sonar.auth.github.loginStrategy", LOGIN_STRATEGY_DEFAULT_VALUE);
 
     settings.setProperty("sonar.auth.github.enabled", true);
     assertThat(underTest.isEnabled()).isTrue();
@@ -51,7 +48,6 @@ public class GitHubSettingsTest {
     settings.setProperty("sonar.auth.github.enabled", true);
     settings.setProperty("sonar.auth.github.clientId.secured", (String) null);
     settings.setProperty("sonar.auth.github.clientSecret.secured", "secret");
-    settings.setProperty("sonar.auth.github.loginStrategy", LOGIN_STRATEGY_DEFAULT_VALUE);
 
     assertThat(underTest.isEnabled()).isFalse();
   }
@@ -61,7 +57,6 @@ public class GitHubSettingsTest {
     settings.setProperty("sonar.auth.github.enabled", true);
     settings.setProperty("sonar.auth.github.clientId.secured", "id");
     settings.setProperty("sonar.auth.github.clientSecret.secured", (String) null);
-    settings.setProperty("sonar.auth.github.loginStrategy", LOGIN_STRATEGY_DEFAULT_VALUE);
 
     assertThat(underTest.isEnabled()).isFalse();
   }
@@ -78,12 +73,6 @@ public class GitHubSettingsTest {
     assertThat(underTest.clientSecret()).isEqualTo("secret");
   }
 
-  @Test
-  public void return_login_strategy() {
-    settings.setProperty("sonar.auth.github.loginStrategy", LOGIN_STRATEGY_PROVIDER_ID);
-    assertThat(underTest.loginStrategy()).isEqualTo(LOGIN_STRATEGY_PROVIDER_ID);
-  }
-
   @Test
   public void allow_users_to_sign_up() {
     settings.setProperty("sonar.auth.github.allowUsersToSignUp", "true");
@@ -132,31 +121,28 @@ public class GitHubSettingsTest {
   public void return_organizations_single() {
     String setting = "example";
     settings.setProperty("sonar.auth.github.organizations", setting);
-    String[] expected = new String[] {"example"};
     String[] actual = underTest.organizations();
-    assertThat(actual).isEqualTo(expected);
+    assertThat(actual).containsOnly(setting);
   }
 
   @Test
   public void return_organizations_multiple() {
     String setting = "example0,example1";
     settings.setProperty("sonar.auth.github.organizations", setting);
-    String[] expected = new String[] {"example0", "example1"};
     String[] actual = underTest.organizations();
-    assertThat(actual).isEqualTo(expected);
+    assertThat(actual).containsOnly("example0", "example1");
   }
 
   @Test
   public void return_organizations_empty_list() {
     String[] setting = null;
     settings.setProperty("sonar.auth.github.organizations", setting);
-    String[] expected = new String[] {};
     String[] actual = underTest.organizations();
-    assertThat(actual).isEqualTo(expected);
+    assertThat(actual).hasSize(0);
   }
 
   @Test
   public void definitions() {
-    assertThat(GitHubSettings.definitions()).hasSize(9);
+    assertThat(GitHubSettings.definitions()).hasSize(8);
   }
 }
index e3ef3551850d211ece69925e213601f28843766c..90c8cfbf39468ceceb23d9aa0c8f1b5f1977c689 100644 (file)
@@ -54,7 +54,7 @@ public class IntegrationTest {
   // load settings with default values
   private MapSettings settings = new MapSettings(new PropertyDefinitions(GitHubSettings.definitions()));
   private GitHubSettings gitHubSettings = new GitHubSettings(settings.asConfig());
-  private UserIdentityFactoryImpl userIdentityFactory = new UserIdentityFactoryImpl(gitHubSettings);
+  private UserIdentityFactoryImpl userIdentityFactory = new UserIdentityFactoryImpl();
   private ScribeGitHubApi scribeApi = new ScribeGitHubApi(gitHubSettings);
   private GitHubRestClient gitHubRestClient = new GitHubRestClient(gitHubSettings);
 
@@ -111,7 +111,7 @@ public class IntegrationTest {
 
     assertThat(callbackContext.csrfStateVerified.get()).isTrue();
     assertThat(callbackContext.userIdentity.getProviderId()).isEqualTo("ABCD");
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("octocat@github");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("octocat");
     assertThat(callbackContext.userIdentity.getName()).isEqualTo("monalisa octocat");
     assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("octocat@github.com");
     assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
@@ -156,7 +156,7 @@ public class IntegrationTest {
 
     assertThat(callbackContext.csrfStateVerified.get()).isTrue();
     assertThat(callbackContext.userIdentity.getProviderId()).isEqualTo("ABCD");
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("octocat@github");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("octocat");
     assertThat(callbackContext.userIdentity.getName()).isEqualTo("monalisa octocat");
     assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("octocat@github.com");
     assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
@@ -176,7 +176,7 @@ public class IntegrationTest {
 
     assertThat(callbackContext.csrfStateVerified.get()).isTrue();
     assertThat(callbackContext.userIdentity.getProviderId()).isEqualTo("ABCD");
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("octocat@github");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("octocat");
     assertThat(callbackContext.userIdentity.getName()).isEqualTo("monalisa octocat");
     assertThat(callbackContext.userIdentity.getEmail()).isNull();
     assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
@@ -294,7 +294,6 @@ public class IntegrationTest {
   @Test
   public void callback_on_successful_authentication_with_organizations_without_membership() {
     settings.setProperty("sonar.auth.github.organizations", "first_org,second_org");
-    settings.setProperty("sonar.auth.github.loginStrategy", GitHubSettings.LOGIN_STRATEGY_PROVIDER_ID);
 
     github.enqueue(newSuccessfulAccessTokenResponse());
     // response of api.github.com/user
@@ -314,27 +313,6 @@ public class IntegrationTest {
     }
   }
 
-  @Test
-  public void callback_on_successful_authentication_with_organizations_without_membership_with_unique_login_strategy() {
-    settings.setProperty("sonar.auth.github.organizations", "example");
-    settings.setProperty("sonar.auth.github.loginStrategy", GitHubSettings.LOGIN_STRATEGY_UNIQUE);
-
-    github.enqueue(newSuccessfulAccessTokenResponse());
-    // response of api.github.com/user
-    github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}"));
-    // response of api.github.com/orgs/example0/members/user
-    github.enqueue(new MockResponse().setResponseCode(404).setBody("{}"));
-
-    HttpServletRequest request = newRequest("the-verifier-code");
-    DumbCallbackContext callbackContext = new DumbCallbackContext(request);
-    try {
-      underTest.callback(callbackContext);
-      fail("exception expected");
-    } catch (UnauthorizedException e) {
-      assertThat(e.getMessage()).isEqualTo("'octocat' must be a member of at least one organization: 'example'");
-    }
-  }
-
   @Test
   public void callback_throws_ISE_if_error_when_requesting_user_profile() {
     github.enqueue(newSuccessfulAccessTokenResponse());
index cad518442211bc2a5255102d4eaffb95750ff46d..3dbe8bc612848f96b50e1f608c1d21947d27145c 100644 (file)
@@ -19,8 +19,6 @@
  */
 package org.sonar.auth.github;
 
-import java.util.Arrays;
-import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -36,56 +34,15 @@ public class UserIdentityFactoryImplTest {
   public ExpectedException expectedException = ExpectedException.none();
 
   private MapSettings settings = new MapSettings(new PropertyDefinitions(GitHubSettings.definitions()));
-  private UserIdentityFactoryImpl underTest = new UserIdentityFactoryImpl(new GitHubSettings(settings.asConfig()));
-
-  /**
-   * Keep the same login as at GitHub
-   */
-  @Test
-  public void create_for_provider_strategy() {
-    GsonUser gson = new GsonUser("ABCD", "octocat", "monalisa octocat", "octocat@github.com");
-    settings.setProperty(GitHubSettings.LOGIN_STRATEGY, GitHubSettings.LOGIN_STRATEGY_PROVIDER_ID);
-
-    UserIdentity identity = underTest.create(gson, gson.getEmail(), null);
-
-    assertThat(identity.getProviderId()).isEqualTo("ABCD");
-    assertThat(identity.getLogin()).isEqualTo("octocat");
-    assertThat(identity.getName()).isEqualTo("monalisa octocat");
-    assertThat(identity.getEmail()).isEqualTo("octocat@github.com");
-  }
+  private UserIdentityFactoryImpl underTest = new UserIdentityFactoryImpl();
 
   @Test
   public void no_email() {
     GsonUser gson = new GsonUser("ABCD", "octocat", "monalisa octocat", null);
-    settings.setProperty(GitHubSettings.LOGIN_STRATEGY, GitHubSettings.LOGIN_STRATEGY_PROVIDER_ID);
-
-    UserIdentity identity = underTest.create(gson, null, null);
-
-    assertThat(identity.getLogin()).isEqualTo("octocat");
-    assertThat(identity.getName()).isEqualTo("monalisa octocat");
-    assertThat(identity.getEmail()).isNull();
-  }
-
-  @Test
-  public void create_for_provider_strategy_with_teams() {
-    GsonUser gson = new GsonUser("ABCD", "octocat", "monalisa octocat", "octocat@github.com");
-    List<GsonTeam> teams = Arrays.asList(
-      new GsonTeam("developers", new GsonTeam.GsonOrganization("SonarSource")));
-    settings.setProperty(GitHubSettings.LOGIN_STRATEGY, GitHubSettings.LOGIN_STRATEGY_PROVIDER_ID);
-
-    UserIdentity identity = underTest.create(gson, null, teams);
-
-    assertThat(identity.getGroups()).containsOnly("SonarSource/developers");
-  }
-
-  @Test
-  public void create_for_unique_login_strategy() {
-    GsonUser gson = new GsonUser("ABCD", "octocat", "monalisa octocat", "octocat@github.com");
-    settings.setProperty(GitHubSettings.LOGIN_STRATEGY, GitHubSettings.LOGIN_STRATEGY_UNIQUE);
 
     UserIdentity identity = underTest.create(gson, null, null);
 
-    assertThat(identity.getLogin()).isEqualTo("octocat@github");
+    assertThat(identity.getProviderLogin()).isEqualTo("octocat");
     assertThat(identity.getName()).isEqualTo("monalisa octocat");
     assertThat(identity.getEmail()).isNull();
   }
@@ -107,14 +64,4 @@ public class UserIdentityFactoryImplTest {
 
     assertThat(identity.getName()).isEqualTo("octocat");
   }
-
-  @Test
-  public void throw_ISE_if_strategy_is_not_supported() {
-    settings.setProperty(GitHubSettings.LOGIN_STRATEGY, "xxx");
-
-    expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage("Login strategy not supported : xxx");
-
-    underTest.create(new GsonUser("ABCD", "octocat", "octocat", "octocat@github.com"), null, null);
-  }
 }
index 158d8457910b3365e71f12bdb878b78463109b56..c552d435e0737f4c650dd0ca2317465c884b6be2 100644 (file)
@@ -94,7 +94,6 @@ public class IntegrationTest {
     ArgumentCaptor<UserIdentity> argument = ArgumentCaptor.forClass(UserIdentity.class);
     verify(callbackContext).authenticate(argument.capture());
     assertThat(argument.getValue()).isNotNull();
-    assertThat(argument.getValue().getLogin()).isNull();
     assertThat(argument.getValue().getProviderId()).isEqualTo("123");
     assertThat(argument.getValue().getProviderLogin()).isEqualTo("toto");
     assertThat(argument.getValue().getName()).isEqualTo("Toto Toto");
index 1107d4f6acd8fb8484f1199ef11b99e0197b99c1..acd609a5fbbc70efc4d09194d3314d16f71d2101 100644 (file)
@@ -111,7 +111,6 @@ public class SamlIdentityProvider implements OAuth2IdentityProvider {
     LOGGER.trace("Attributes received : {}", auth.getAttributes());
     String login = getNonNullFirstAttribute(auth, samlSettings.getUserLogin());
     UserIdentity.Builder userIdentityBuilder = UserIdentity.builder()
-      .setLogin(login)
       .setProviderLogin(login)
       .setName(getNonNullFirstAttribute(auth, samlSettings.getUserName()));
     samlSettings.getUserEmail().ifPresent(
index 7ec3cf1a15058d3e06b81a4c6432873b383b47d5..c72a10789e54bb6262323eff5d09fdd3d046646b 100644 (file)
@@ -111,7 +111,7 @@ public class SamlIdentityProviderTest {
     underTest.callback(callbackContext);
 
     assertThat(callbackContext.redirectedToRequestedPage.get()).isTrue();
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
     assertThat(callbackContext.verifyState.get()).isTrue();
   }
 
@@ -122,7 +122,6 @@ public class SamlIdentityProviderTest {
 
     underTest.callback(callbackContext);
 
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("johndoe");
     assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
     assertThat(callbackContext.userIdentity.getEmail()).isEqualTo("johndoe@email.com");
     assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
@@ -136,7 +135,6 @@ public class SamlIdentityProviderTest {
 
     underTest.callback(callbackContext);
 
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("johndoe");
     assertThat(callbackContext.userIdentity.getName()).isEqualTo("John Doe");
     assertThat(callbackContext.userIdentity.getEmail()).isNull();
     assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
@@ -151,7 +149,7 @@ public class SamlIdentityProviderTest {
 
     underTest.callback(callbackContext);
 
-    assertThat(callbackContext.userIdentity.getLogin()).isEqualTo("johndoe");
+    assertThat(callbackContext.userIdentity.getProviderLogin()).isEqualTo("johndoe");
     assertThat(callbackContext.userIdentity.getGroups()).isEmpty();
   }
 
index bc58c94d529da81f792feea3ebee3cad9ca56517..472fe0c6012627ac6347117c8dbd61e42f417660 100644 (file)
@@ -41,11 +41,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
 import static java.util.Arrays.stream;
 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
-import static org.sonar.db.user.GroupTesting.newGroupDto;
-import static org.sonar.db.user.UserTesting.newDisabledUser;
-import static org.sonar.db.user.UserTesting.newUserDto;
-import static org.sonar.db.user.UserTesting.newUserSettingDto;
-import static org.sonar.db.user.UserTokenTesting.newUserToken;
 
 public class UserDbTester {
   private static final Set<String> PUBLIC_PERMISSIONS = ImmutableSet.of(UserRole.USER, UserRole.CODEVIEWER); // FIXME to check with Simon
@@ -117,6 +112,18 @@ public class UserDbTester {
     return Optional.ofNullable(dbClient.userDao().selectByLogin(db.getSession(), login));
   }
 
+  public Optional<UserDto> selectUserByEmail(String email) {
+    List<UserDto> users = dbClient.userDao().selectByEmail(db.getSession(), email);
+    if (users.size() > 1) {
+      return Optional.empty();
+    }
+    return Optional.of(users.get(0));
+  }
+
+  public Optional<UserDto> selectUserByExternalLoginAndIdentityProvider(String login, String identityProvider) {
+    return Optional.ofNullable(dbClient.userDao().selectByExternalLoginAndIdentityProvider(db.getSession(), login, identityProvider));
+  }
+
   // USER SETTINGS
 
   @SafeVarargs
index 5bb2ab5e9e4ba5ff1587afb765eea06276e94b28..3cc49559ff09c89d1469cb105e61b5a2ec47d3de 100644 (file)
@@ -35,6 +35,7 @@ public class DbVersion80 implements DbVersion {
       .add(3006, "Create NEW_CODE_PERIOD table", CreateNewCodePeriodTable.class)
       .add(3007, "Populate NEW_CODE_PERIOD table", PopulateNewCodePeriodTable.class)
       .add(3008, "Remove leak period properties", RemoveLeakPeriodProperties.class)
+      .add(3009, "Remove GitHub login generation strategy property", RemoveGitHubLoginGenerationStrategyProperty.class)
     ;
   }
 }
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyProperty.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyProperty.java
new file mode 100644 (file)
index 0000000..bc30f18
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v80;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+public class RemoveGitHubLoginGenerationStrategyProperty extends DataChange {
+  private static final String GH_LOGIN_STRATEGY_PROP_KEY = "sonar.auth.github.loginStrategy";
+
+  public RemoveGitHubLoginGenerationStrategyProperty(Database db) {
+    super(db);
+  }
+
+  @Override
+  protected void execute(Context context) throws SQLException {
+    context.prepareUpsert("delete from properties where prop_key='" + GH_LOGIN_STRATEGY_PROP_KEY + "'")
+      .execute()
+      .commit();
+  }
+}
index a4a6ecde6fa1d002c3cfc45405df21db7230543f..fe63e2debcb628f75e6c1c39f3020f47e919856d 100644 (file)
@@ -35,7 +35,7 @@ public class DbVersion80Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 9);
+    verifyMigrationCount(underTest, 10);
   }
 
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyPropertyTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyPropertyTest.java
new file mode 100644 (file)
index 0000000..ec9b6eb
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v80;
+
+import java.sql.SQLException;
+import java.time.Instant;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+public class RemoveGitHubLoginGenerationStrategyPropertyTest {
+  private static final String PROPERTIES_TABLE_NAME = "properties";
+
+  @Rule
+  public CoreDbTester dbTester = CoreDbTester.createForSchema(RemoveGitHubLoginGenerationStrategyPropertyTest.class, "schema.sql");
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private RemoveGitHubLoginGenerationStrategyProperty underTest = new RemoveGitHubLoginGenerationStrategyProperty(dbTester.database());
+
+  @Test
+  public void remove_github_login_strategy_property() throws SQLException {
+    insertGitHubLoginStrategy();
+
+    int propertiesCount = dbTester.countRowsOfTable(PROPERTIES_TABLE_NAME);
+    Assert.assertEquals(1, propertiesCount);
+
+    underTest.execute();
+
+    //should delete properties
+    propertiesCount = dbTester.countRowsOfTable(PROPERTIES_TABLE_NAME);
+    Assert.assertEquals(0, propertiesCount);
+
+    //should not fail if executed twice
+    underTest.execute();
+  }
+
+  private void insertGitHubLoginStrategy() {
+    dbTester.executeInsert(PROPERTIES_TABLE_NAME,
+      "prop_key", "sonar.auth.github.loginStrategy",
+      "is_empty", false,
+      "text_value", "Unique",
+      "created_at", Instant.now().toEpochMilli());
+  }
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyPropertyTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/RemoveGitHubLoginGenerationStrategyPropertyTest/schema.sql
new file mode 100644 (file)
index 0000000..d84c238
--- /dev/null
@@ -0,0 +1,11 @@
+CREATE TABLE "PROPERTIES" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROP_KEY" VARCHAR(512) NOT NULL,
+  "RESOURCE_ID" INTEGER,
+  "USER_ID" INTEGER,
+  "IS_EMPTY" BOOLEAN NOT NULL,
+  "TEXT_VALUE" VARCHAR(4000),
+  "CLOB_VALUE" CLOB,
+  "CREATED_AT" BIGINT
+);
+CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY");
index 6a0187e35c9c64c64a03d9c3f5c48f061befae63..1f427a56e41b2ada30c55666dff769e837d6f127 100644 (file)
@@ -133,7 +133,6 @@ public class CredentialsExternalAuthentication implements Startable {
   private UserDto synchronize(String userLogin, UserDetails details, HttpServletRequest request, AuthenticationEvent.Method method) {
     String name = details.getName();
     UserIdentity.Builder userIdentityBuilder = UserIdentity.builder()
-      .setLogin(userLogin)
       .setName(isEmpty(name) ? userLogin : name)
       .setEmail(trimToNull(details.getEmail()))
       .setProviderLogin(userLogin);
index 29ed2e65195b94244627a33861f85449429a6921..b0e4203678a2d8c3dfcc70133e2bd50e1041b396 100644 (file)
@@ -157,7 +157,6 @@ public class HttpHeadersAuthentication implements Startable {
     String name = getHeaderValue(headerValuesByNames, SONAR_WEB_SSO_NAME_HEADER.getKey());
     String email = getHeaderValue(headerValuesByNames, SONAR_WEB_SSO_EMAIL_HEADER.getKey());
     UserIdentity.Builder userIdentityBuilder = UserIdentity.builder()
-      .setLogin(login)
       .setName(name == null ? login : name)
       .setEmail(email)
       .setProviderLogin(login);
index 6f408e3c7fcb5a0ccc23b2655be5412b5a33c95b..8b06ed5e6a5355f961b708ba87a84a31eee4efab 100644 (file)
@@ -62,6 +62,7 @@ import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
 public class UserRegistrarImpl implements UserRegistrar {
 
   private static final Logger LOGGER = Loggers.get(UserRegistrarImpl.class);
+  private static final String SQ_AUTHORITY = "sonarqube";
 
   private final DbClient dbClient;
   private final UserUpdater userUpdater;
@@ -102,16 +103,7 @@ public class UserRegistrarImpl implements UserRegistrar {
       return user;
     }
     // Then, try with the external login, for instance when external ID has changed
-    user = dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, userIdentity.getProviderLogin(), provider.getKey());
-    if (user != null) {
-      return user;
-    }
-    // Last, try with login, for instance when external ID and external login has been updated
-    String login = userIdentity.getLogin();
-    if (login == null) {
-      return null;
-    }
-    return dbClient.userDao().selectByLogin(dbSession, login);
+    return dbClient.userDao().selectByExternalLoginAndIdentityProvider(dbSession, userIdentity.getProviderLogin(), provider.getKey());
   }
 
   private UserDto registerNewUser(DbSession dbSession, @Nullable UserDto disabledUser, UserRegistration authenticatorParameters) {
@@ -131,10 +123,6 @@ public class UserRegistrarImpl implements UserRegistrar {
         authenticatorParameters.getProvider().getKey(),
         authenticatorParameters.getUserIdentity().getProviderLogin(),
         authenticatorParameters.getUserIdentity().getProviderId()));
-    String login = authenticatorParameters.getUserIdentity().getLogin();
-    if (login != null) {
-      update.setLogin(login);
-    }
     Optional<UserDto> otherUserToIndex = detectEmailUpdate(dbSession, authenticatorParameters);
     userUpdater.updateAndCommit(dbSession, userDto, update, beforeCommit(dbSession, false, authenticatorParameters), toArray(otherUserToIndex));
     return userDto;
@@ -180,12 +168,10 @@ public class UserRegistrarImpl implements UserRegistrar {
   }
 
   private static boolean isSameUser(UserDto existingUser, UserRegistration authenticatorParameters) {
-    // Check if same login
-    return Objects.equals(existingUser.getLogin(), authenticatorParameters.getUserIdentity().getLogin()) ||
     // Check if same identity provider and same provider id or provider login
-      (Objects.equals(existingUser.getExternalIdentityProvider(), authenticatorParameters.getProvider().getKey()) &&
-        (Objects.equals(existingUser.getExternalId(), getProviderIdOrProviderLogin(authenticatorParameters.getUserIdentity()))
-          || Objects.equals(existingUser.getExternalLogin(), authenticatorParameters.getUserIdentity().getProviderLogin())));
+    return (Objects.equals(existingUser.getExternalIdentityProvider(), authenticatorParameters.getProvider().getKey()) &&
+      (Objects.equals(existingUser.getExternalId(), getProviderIdOrProviderLogin(authenticatorParameters.getUserIdentity()))
+        || Objects.equals(existingUser.getExternalLogin(), authenticatorParameters.getUserIdentity().getProviderLogin())));
   }
 
   private void syncGroups(DbSession dbSession, UserIdentity userIdentity, UserDto userDto) {
@@ -257,14 +243,15 @@ public class UserRegistrarImpl implements UserRegistrar {
         .setPublicMessage(format("'%s' users are not allowed to sign up", identityProviderKey))
         .build();
     }
+    String providerLogin = authenticatorParameters.getUserIdentity().getProviderLogin();
     return NewUser.builder()
-      .setLogin(authenticatorParameters.getUserIdentity().getLogin())
+      .setLogin(SQ_AUTHORITY.equals(identityProviderKey) ? providerLogin : null)
       .setEmail(authenticatorParameters.getUserIdentity().getEmail())
       .setName(authenticatorParameters.getUserIdentity().getName())
       .setExternalIdentity(
         new ExternalIdentity(
           identityProviderKey,
-          authenticatorParameters.getUserIdentity().getProviderLogin(),
+          providerLogin,
           authenticatorParameters.getUserIdentity().getProviderId()))
       .build();
   }
index 4c41bbd9ff72b67d58181b37c21dcae9fdc2a0f3..f4081a2482a481be6811ac0a094968931413ec05 100644 (file)
@@ -229,7 +229,7 @@ public class UserUpdater {
     dbClient.propertiesDao().selectByKeyAndMatchingValue(dbSession, DEFAULT_ISSUE_ASSIGNEE, userDto.getLogin())
       .forEach(p -> dbClient.propertiesDao().saveProperty(p.setValue(newLogin)));
     userDto.setLogin(newLogin);
-    if (userDto.isLocal()) {
+    if (userDto.isLocal() || SQ_AUTHORITY.equals(userDto.getExternalIdentityProvider())) {
       userDto.setExternalLogin(newLogin);
       userDto.setExternalId(newLogin);
     }
index de51e18f54615689ddbbd203302a24845bbd1059..dd016d5cfc1714619b999d732edbfd50efa3d45a 100644 (file)
@@ -47,7 +47,6 @@ public class BaseContextFactoryTest {
   private static final UserIdentity USER_IDENTITY = UserIdentity.builder()
     .setProviderId("ABCD")
     .setProviderLogin("johndoo")
-    .setLogin("id:johndoo")
     .setName("John")
     .setEmail("john@email.com")
     .build();
@@ -92,7 +91,6 @@ public class BaseContextFactoryTest {
     assertThat(userIdentityAuthenticator.isAuthenticated()).isTrue();
     verify(threadLocalUserSession).set(any(UserSession.class));
     verify(jwtHttpHandler).generateToken(userArgumentCaptor.capture(), eq(request), eq(response));
-    assertThat(userArgumentCaptor.getValue().getLogin()).isEqualTo(USER_IDENTITY.getLogin());
     assertThat(userArgumentCaptor.getValue().getExternalId()).isEqualTo(USER_IDENTITY.getProviderId());
     assertThat(userArgumentCaptor.getValue().getExternalLogin()).isEqualTo(USER_IDENTITY.getProviderLogin());
     assertThat(userArgumentCaptor.getValue().getExternalIdentityProvider()).isEqualTo("github");
index ee90eb0d0940b919d8e3ad86f04fb841f6cf6f13..94eb47c57de0fbc9ce6b05fe45cc7bf3db3fd4b5 100644 (file)
@@ -92,7 +92,6 @@ public class CredentialsExternalAuthenticationTest {
 
     assertThat(userIdentityAuthenticator.isAuthenticated()).isTrue();
     assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getExistingEmailStrategy()).isEqualTo(FORBID);
-    assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getLogin()).isEqualTo(LOGIN);
     assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getProviderLogin()).isEqualTo(LOGIN);
     assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getProviderId()).isNull();
     assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getName()).isEqualTo("name");
@@ -169,7 +168,6 @@ public class CredentialsExternalAuthenticationTest {
     executeAuthenticate("LOGIN");
 
     assertThat(userIdentityAuthenticator.isAuthenticated()).isTrue();
-    assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getLogin()).isEqualTo("login");
     assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getProviderLogin()).isEqualTo("login");
     verify(authenticationEvent).loginSuccess(request, "login", Source.realm(BASIC, REALM_NAME));
   }
@@ -182,7 +180,6 @@ public class CredentialsExternalAuthenticationTest {
     executeAuthenticate("LoGiN");
 
     assertThat(userIdentityAuthenticator.isAuthenticated()).isTrue();
-    assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getLogin()).isEqualTo("LoGiN");
     assertThat(userIdentityAuthenticator.getAuthenticatorParameters().getUserIdentity().getProviderLogin()).isEqualTo("LoGiN");
     verify(authenticationEvent).loginSuccess(request, "LoGiN", Source.realm(BASIC, REALM_NAME));
   }
index 0a1672b9dcc70da4563d35b77607bfe73c1759b5..ef3d77e2f35339cb99400eedbf26b92d8a0b0c96 100644 (file)
@@ -152,7 +152,7 @@ public class HttpHeadersAuthenticationTest {
   public void update_user_when_authenticating_exiting_user() {
     startWithSso();
     setNotUserInToken();
-    insertUser(newUserDto().setLogin(DEFAULT_LOGIN).setName("old name").setEmail("old email"), group1);
+    insertUser(newUserDto().setLogin(DEFAULT_LOGIN).setExternalLogin(DEFAULT_LOGIN).setExternalIdentityProvider("sonarqube").setName("old name").setEmail("old email"), group1);
     // Name, email and groups are different
     HttpServletRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUP2);
 
index c23bb1ed59a53a49751054d6732b0af012519ac2..8118282a4aad73f847dffcaafaaf8e89bf60a29e 100644 (file)
@@ -328,7 +328,6 @@ public class InitFilterTest {
     public void init(Context context) {
       throw new EmailAlreadyExistsRedirectionException(existingUser.getEmail(), existingUser, UserIdentity.builder()
         .setProviderLogin("john.github")
-        .setLogin("john.github")
         .setName(existingUser.getName())
         .setEmail(existingUser.getEmail())
         .build(), this);
index a42f29cf0595cee25d760079b781805bc50335b4..47c745b5d60789c722eb7b860adced481a302699 100644 (file)
@@ -289,7 +289,6 @@ public class OAuth2CallbackFilterTest {
     public void callback(CallbackContext context) {
       throw new EmailAlreadyExistsRedirectionException(existingUser.getEmail(), existingUser, UserIdentity.builder()
         .setProviderLogin("john.github")
-        .setLogin("john.github")
         .setName(existingUser.getName())
         .setEmail(existingUser.getEmail())
         .build(), this);
@@ -324,7 +323,6 @@ public class OAuth2CallbackFilterTest {
     public void callback(CallbackContext context) {
       super.callback(context);
       context.authenticate(UserIdentity.builder()
-        .setLogin(login)
         .setProviderLogin(login)
         .setEmail(login + "@toto.com")
         .setName("name of " + login)
index cf2eb5f19fe595e932ec0385fd820b3904992f11..8d5d6229eb472d61e8c8f7d37f956424d1de833b 100644 (file)
@@ -55,7 +55,6 @@ public class OAuth2ContextFactoryTest {
   private static final UserIdentity USER_IDENTITY = UserIdentity.builder()
     .setProviderId("ABCD")
     .setProviderLogin("johndoo")
-    .setLogin("id:johndoo")
     .setName("John")
     .setEmail("john@email.com")
     .build();
@@ -135,7 +134,6 @@ public class OAuth2ContextFactoryTest {
     verify(threadLocalUserSession).set(any(UserSession.class));
     ArgumentCaptor<UserDto> userArgumentCaptor = ArgumentCaptor.forClass(UserDto.class);
     verify(jwtHttpHandler).generateToken(userArgumentCaptor.capture(), eq(request), eq(response));
-    assertThat(userArgumentCaptor.getValue().getLogin()).isEqualTo(USER_IDENTITY.getLogin());
     assertThat(userArgumentCaptor.getValue().getExternalId()).isEqualTo(USER_IDENTITY.getProviderId());
     assertThat(userArgumentCaptor.getValue().getExternalLogin()).isEqualTo(USER_IDENTITY.getProviderLogin());
     assertThat(userArgumentCaptor.getValue().getExternalIdentityProvider()).isEqualTo(PROVIDER_KEY);
index 4244c842138ede73f1acfe2bb886fa1fd627e45f..0c45e64d5d005ab54429ac27636e0fe07b13bdd4 100644 (file)
@@ -32,7 +32,6 @@ public class TestUserRegistrar implements UserRegistrar {
     String providerId = registration.getUserIdentity().getProviderId();
     return UserTesting.newUserDto()
       .setLocal(false)
-      .setLogin(registration.getUserIdentity().getLogin())
       .setExternalLogin(registration.getUserIdentity().getProviderLogin())
       .setExternalId(providerId == null ? registration.getUserIdentity().getProviderLogin() : providerId)
       .setExternalIdentityProvider(registration.getProvider().getKey());
index c43fdb7f61679726c09fb1a985d7898f4bb5d828..b9404baaab432b22a9802993710870752a08420d 100644 (file)
@@ -63,7 +63,6 @@ public class UserRegistrarImplOrgMembershipSyncTest {
   private static UserIdentity USER_IDENTITY = UserIdentity.builder()
     .setProviderId("ABCD")
     .setProviderLogin("johndoo")
-    .setLogin(USER_LOGIN)
     .setName("John")
     .setEmail("john@email.com")
     .build();
@@ -127,7 +126,7 @@ public class UserRegistrarImplOrgMembershipSyncTest {
       .setOrganizationAlmIds(ImmutableSet.of(gitHubInstall.getOrganizationAlmId()))
       .build());
 
-    UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
+    UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), GITHUB_PROVIDER.getKey()).get();
     db.organizations().assertUserIsMemberOfOrganization(organization, user);
   }
 
@@ -147,7 +146,7 @@ public class UserRegistrarImplOrgMembershipSyncTest {
       .setOrganizationAlmIds(null)
       .build());
 
-    UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
+    UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), GITHUB_PROVIDER.getKey()).get();
     db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
   }
 
@@ -167,7 +166,7 @@ public class UserRegistrarImplOrgMembershipSyncTest {
       .setOrganizationAlmIds(ImmutableSet.of(gitHubInstall.getOrganizationAlmId()))
       .build());
 
-    UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
+    UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), BITBUCKET_PROVIDER.getKey()).get();
     db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
   }
 
@@ -192,7 +191,7 @@ public class UserRegistrarImplOrgMembershipSyncTest {
       .setOrganizationAlmIds(ImmutableSet.of(almAppInstall.getOrganizationAlmId()))
       .build());
 
-    UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
+    UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), identityProvider.getKey()).get();
     db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
   }
 
@@ -226,7 +225,11 @@ public class UserRegistrarImplOrgMembershipSyncTest {
     db.users().insertDefaultGroup(organization, "Members");
     AlmAppInstallDto gitHubInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(GITHUB));
     db.alm().insertOrganizationAlmBinding(organization, gitHubInstall, true);
-    UserDto user = db.users().insertDisabledUser(u -> u.setLogin(USER_LOGIN));
+    UserDto user = db.users().insertDisabledUser(u -> u
+      .setLogin(USER_LOGIN)
+      .setExternalId(USER_IDENTITY.getProviderId())
+      .setExternalIdentityProvider(GITHUB_PROVIDER.getKey())
+    );
 
     underTest.register(UserRegistration.builder()
       .setUserIdentity(USER_IDENTITY)
index 4673a5fce22a93087854821d598ee667c681cb3a..8feeaf668b1a97819be9d7755e067820828994b3 100644 (file)
@@ -62,12 +62,11 @@ public class UserRegistrarImplTest {
 
   private System2 system2 = new AlwaysIncreasingSystem2();
 
-  private static String USER_LOGIN = "github-johndoo";
+  private static String USER_LOGIN = "johndoo";
 
   private static UserIdentity USER_IDENTITY = UserIdentity.builder()
     .setProviderId("ABCD")
     .setProviderLogin("johndoo")
-    .setLogin(USER_LOGIN)
     .setName("John")
     .setEmail("john@email.com")
     .build();
@@ -111,14 +110,14 @@ public class UserRegistrarImplTest {
   public void authenticate_new_user() {
     organizationFlags.setEnabled(true);
 
-    underTest.register(UserRegistration.builder()
+    UserDto createdUser = underTest.register(UserRegistration.builder()
       .setUserIdentity(USER_IDENTITY)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.realm(BASIC, IDENTITY_PROVIDER.getName()))
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    UserDto user = db.users().selectUserByLogin(USER_LOGIN).get();
+    UserDto user = db.users().selectUserByLogin(createdUser.getLogin()).get();
     assertThat(user).isNotNull();
     assertThat(user.isActive()).isTrue();
     assertThat(user.getName()).isEqualTo("John");
@@ -130,6 +129,38 @@ public class UserRegistrarImplTest {
     checkGroupMembership(user);
   }
 
+  @Test
+  public void authenticate_new_user_with_sq_identity() {
+    organizationFlags.setEnabled(false);
+    GroupDto defaultGroup = insertDefaultGroup();
+
+    TestIdentityProvider sqIdentityProvider = new TestIdentityProvider()
+      .setKey("sonarqube")
+      .setName("sonarqube identity name")
+      .setEnabled(true)
+      .setAllowsUsersToSignUp(true);
+
+    UserDto createdUser = underTest.register(UserRegistration.builder()
+      .setUserIdentity(USER_IDENTITY)
+      .setProvider(sqIdentityProvider)
+      .setSource(Source.realm(BASIC, sqIdentityProvider.getName()))
+      .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
+      .build());
+
+    UserDto user = db.users().selectUserByLogin(createdUser.getLogin()).get();
+    assertThat(user).isNotNull();
+    assertThat(user.isActive()).isTrue();
+    assertThat(user.getLogin()).isEqualTo("johndoo");
+    assertThat(user.getName()).isEqualTo("John");
+    assertThat(user.getEmail()).isEqualTo("john@email.com");
+    assertThat(user.getExternalLogin()).isEqualTo("johndoo");
+    assertThat(user.getExternalIdentityProvider()).isEqualTo("sonarqube");
+    assertThat(user.getExternalId()).isEqualTo("ABCD");
+    assertThat(user.isLocal()).isFalse();
+    assertThat(user.isRoot()).isFalse();
+    checkGroupMembership(user, defaultGroup);
+  }
+
   @Test
   public void authenticate_new_user_generate_login_when_no_login_provided() {
     organizationFlags.setEnabled(true);
@@ -162,9 +193,9 @@ public class UserRegistrarImplTest {
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
 
-    authenticate(USER_LOGIN, "group1", "group2", "group3");
+    UserDto loggedInUser = authenticate(USER_LOGIN, "group1", "group2", "group3");
 
-    Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
+    Optional<UserDto> user = db.users().selectUserByLogin(loggedInUser.getLogin());
     checkGroupMembership(user.get(), group1, group2);
   }
 
@@ -185,13 +216,16 @@ public class UserRegistrarImplTest {
   @Test
   public void does_not_force_default_group_when_authenticating_new_user_if_organizations_are_enabled() {
     organizationFlags.setEnabled(true);
-    UserDto user = db.users().insertUser();
+    UserDto user = db.users().insertUser(newUserDto()
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
+    );
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto defaultGroup = insertDefaultGroup();
     db.users().insertMember(group1, user);
     db.users().insertMember(defaultGroup, user);
 
-    authenticate(user.getLogin(), "group1");
+    authenticate(user.getExternalLogin(), "group1");
 
     checkGroupMembership(user, group1);
   }
@@ -201,14 +235,14 @@ public class UserRegistrarImplTest {
     organizationFlags.setEnabled(true);
     settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), true);
 
-    underTest.register(UserRegistration.builder()
+    UserDto user = underTest.register(UserRegistration.builder()
       .setUserIdentity(USER_IDENTITY)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.local(BASIC))
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin(USER_LOGIN).get().isOnboarded()).isFalse();
+    assertThat(db.users().selectUserByLogin(user.getLogin()).get().isOnboarded()).isFalse();
   }
 
   @Test
@@ -216,14 +250,14 @@ public class UserRegistrarImplTest {
     organizationFlags.setEnabled(true);
     settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS.getKey(), false);
 
-    underTest.register(UserRegistration.builder()
+    UserDto user = underTest.register(UserRegistration.builder()
       .setUserIdentity(USER_IDENTITY)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.local(BASIC))
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin(USER_LOGIN).get().isOnboarded()).isTrue();
+    assertThat(db.users().selectUserByLogin(user.getLogin()).get().isOnboarded()).isTrue();
   }
 
   @Test
@@ -231,21 +265,20 @@ public class UserRegistrarImplTest {
     organizationFlags.setEnabled(true);
     UserIdentity newUser = UserIdentity.builder()
       .setProviderId(null)
-      .setLogin("john")
       .setProviderLogin("johndoo")
       .setName("JOhn")
       .build();
 
-    underTest.register(UserRegistration.builder()
+    UserDto user = underTest.register(UserRegistration.builder()
       .setUserIdentity(newUser)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.local(BASIC))
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin(newUser.getLogin()).get())
+    assertThat(db.users().selectUserByLogin(user.getLogin()).get())
       .extracting(UserDto::getLogin, UserDto::getExternalId, UserDto::getExternalLogin)
-      .contains("john", "johndoo", "johndoo");
+      .contains(user.getLogin(), "johndoo", "johndoo");
   }
 
   @Test
@@ -254,19 +287,18 @@ public class UserRegistrarImplTest {
     UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
     UserIdentity newUser = UserIdentity.builder()
       .setProviderLogin("johndoo")
-      .setLogin("new_login")
       .setName(existingUser.getName())
       .setEmail(existingUser.getEmail())
       .build();
 
-    underTest.register(UserRegistration.builder()
+    UserDto user = underTest.register(UserRegistration.builder()
       .setUserIdentity(newUser)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.local(BASIC))
       .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
       .build());
 
-    UserDto newUserReloaded = db.users().selectUserByLogin(newUser.getLogin()).get();
+    UserDto newUserReloaded = db.users().selectUserByLogin(user.getLogin()).get();
     assertThat(newUserReloaded.getEmail()).isEqualTo(existingUser.getEmail());
     UserDto existingUserReloaded = db.users().selectUserByLogin(existingUser.getLogin()).get();
     assertThat(existingUserReloaded.getEmail()).isNull();
@@ -278,7 +310,6 @@ public class UserRegistrarImplTest {
     UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
     UserIdentity newUser = UserIdentity.builder()
       .setProviderLogin("johndoo")
-      .setLogin("new_login")
       .setName(existingUser.getName())
       .setEmail(existingUser.getEmail())
       .build();
@@ -356,22 +387,22 @@ public class UserRegistrarImplTest {
 
   @Test
   public void authenticate_and_update_existing_user_matching_login() {
+    insertDefaultGroup();
     db.users().insertUser(u -> u
-      .setLogin(USER_LOGIN)
       .setName("Old name")
       .setEmail("Old email")
       .setExternalId("old id")
       .setExternalLogin("old identity")
       .setExternalIdentityProvider("old provide"));
 
-    underTest.register(UserRegistration.builder()
+    UserDto user = underTest.register(UserRegistration.builder()
       .setUserIdentity(USER_IDENTITY)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.local(BASIC))
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin(USER_LOGIN).get())
+    assertThat(db.users().selectUserByLogin(user.getLogin()).get())
       .extracting(UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider, UserDto::isActive)
       .contains("John", "john@email.com", "ABCD", "johndoo", "github", true);
   }
@@ -393,7 +424,6 @@ public class UserRegistrarImplTest {
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin("Old login")).isNotPresent();
     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
       .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
         UserDto::isActive)
@@ -417,15 +447,14 @@ public class UserRegistrarImplTest {
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin("Old login")).isNotPresent();
     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
-      .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
+      .extracting(UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
         UserDto::isActive)
-      .contains(USER_LOGIN, "John", "john@email.com", "ABCD", "johndoo", "github", true);
+      .contains("John", "john@email.com", "ABCD", "johndoo", "github", true);
   }
 
   @Test
-  public void authenticate_existing_user_and_update_only_login() {
+  public void authenticate_existing_user_and_login_should_not_be_updated() {
     UserDto user = db.users().insertUser(u -> u
       .setLogin("old login")
       .setName(USER_IDENTITY.getName())
@@ -441,55 +470,29 @@ public class UserRegistrarImplTest {
       .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
       .build());
 
-    assertThat(db.users().selectUserByLogin("Old login")).isNotPresent();
-    assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
-      .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
-        UserDto::isActive)
-      .containsExactlyInAnyOrder(USER_LOGIN, USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
-        IDENTITY_PROVIDER.getKey(),
-        true);
-  }
-
-  @Test
-  public void authenticate_existing_user_and_update_only_identity_provider_key() {
-    UserDto user = db.users().insertUser(u -> u
-      .setLogin(USER_LOGIN)
-      .setName(USER_IDENTITY.getName())
-      .setEmail(USER_IDENTITY.getEmail())
-      .setExternalId(USER_IDENTITY.getProviderId())
-      .setExternalLogin(USER_IDENTITY.getProviderLogin())
-      .setExternalIdentityProvider("old identity provider"));
-
-    underTest.register(UserRegistration.builder()
-      .setUserIdentity(USER_IDENTITY)
-      .setProvider(IDENTITY_PROVIDER)
-      .setSource(Source.local(BASIC))
-      .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
-      .build());
-
+    //no new user should be created
+    assertThat(db.countRowsOfTable(db.getSession(), "users")).isEqualTo(1);
     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
       .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
         UserDto::isActive)
-      .containsExactlyInAnyOrder(USER_LOGIN, USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
+      .containsExactlyInAnyOrder("old login", USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
         IDENTITY_PROVIDER.getKey(),
         true);
   }
 
   @Test
-  public void authenticate_existing_user_matching_login_when_external_id_is_null() {
+  public void authenticate_existing_user_matching_external_login_when_external_id_is_null() {
     UserDto user = db.users().insertUser(u -> u
-      .setLogin(USER_LOGIN)
       .setName("Old name")
       .setEmail("Old email")
       .setExternalId("Old id")
-      .setExternalLogin("old identity")
+      .setExternalLogin("johndoo")
       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
 
     underTest.register(UserRegistration.builder()
       .setUserIdentity(UserIdentity.builder()
         .setProviderId(null)
         .setProviderLogin("johndoo")
-        .setLogin(USER_LOGIN)
         .setName("John")
         .setEmail("john@email.com")
         .build())
@@ -526,7 +529,7 @@ public class UserRegistrarImplTest {
     assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
       .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
         UserDto::isActive)
-      .contains(user.getLogin(), user.getName(), user.getEmail(), user.getExternalId(), user.getExternalLogin(), user.getExternalIdentityProvider(), true);
+      .contains(user.getExternalLogin(), user.getName(), user.getEmail(), user.getExternalId(), user.getExternalLogin(), user.getExternalIdentityProvider(), true);
   }
 
   @Test
@@ -557,9 +560,9 @@ public class UserRegistrarImplTest {
       .setActive(false)
       .setName("Old name")
       .setEmail("Old email")
-      .setExternalId("old id")
-      .setExternalLogin("old identity")
-      .setExternalIdentityProvider("old provide"));
+      .setExternalId("Old id")
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
 
     underTest.register(UserRegistration.builder()
       .setUserIdentity(USER_IDENTITY)
@@ -582,25 +585,27 @@ public class UserRegistrarImplTest {
   public void authenticate_existing_user_when_email_already_exists_and_strategy_is_ALLOW() {
     organizationFlags.setEnabled(true);
     UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
-    UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
+    UserDto currentUser = db.users().insertUser(u -> u.setExternalLogin("johndoo").setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()).setEmail(null));
+
     UserIdentity userIdentity = UserIdentity.builder()
-      .setLogin(currentUser.getLogin())
-      .setProviderLogin("johndoo")
+      .setProviderLogin(currentUser.getExternalLogin())
       .setName("John")
       .setEmail("john@email.com")
       .build();
 
-    underTest.register(UserRegistration.builder()
+    currentUser = underTest.register(UserRegistration.builder()
       .setUserIdentity(userIdentity)
       .setProvider(IDENTITY_PROVIDER)
       .setSource(Source.local(BASIC))
       .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
       .build());
 
-    UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
-    assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
     UserDto existingUserReloaded = db.users().selectUserByLogin(existingUser.getLogin()).get();
     assertThat(existingUserReloaded.getEmail()).isNull();
+
+    UserDto currentUserReloaded = db.users().selectUserByLogin(currentUser.getLogin()).get();
+    assertThat(currentUserReloaded.getEmail()).isEqualTo("john@email.com");
+
   }
 
   @Test
@@ -609,7 +614,6 @@ public class UserRegistrarImplTest {
     UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
     UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
     UserIdentity userIdentity = UserIdentity.builder()
-      .setLogin(currentUser.getLogin())
       .setProviderLogin("johndoo")
       .setName("John")
       .setEmail("john@email.com")
@@ -631,7 +635,6 @@ public class UserRegistrarImplTest {
     UserDto existingUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
     UserDto currentUser = db.users().insertUser(u -> u.setEmail(null));
     UserIdentity userIdentity = UserIdentity.builder()
-      .setLogin(currentUser.getLogin())
       .setProviderLogin("johndoo")
       .setName("John")
       .setEmail("john@email.com")
@@ -657,7 +660,6 @@ public class UserRegistrarImplTest {
     UserDto currentUser = db.users().insertUser(u -> u.setEmail("john@email.com")
       .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
     UserIdentity userIdentity = UserIdentity.builder()
-      .setLogin(currentUser.getLogin())
       .setProviderId(currentUser.getExternalId())
       .setProviderLogin(currentUser.getExternalLogin())
       .setName("John")
@@ -679,13 +681,14 @@ public class UserRegistrarImplTest {
   public void authenticate_existing_user_and_add_new_groups() {
     organizationFlags.setEnabled(true);
     UserDto user = db.users().insertUser(newUserDto()
-      .setLogin(USER_LOGIN)
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
       .setActive(true)
       .setName("John"));
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
 
-    authenticate(USER_LOGIN, "group1", "group2", "group3");
+    authenticate(USER_IDENTITY.getProviderLogin(), "group1", "group2", "group3");
 
     checkGroupMembership(user, group1, group2);
   }
@@ -694,7 +697,8 @@ public class UserRegistrarImplTest {
   public void authenticate_existing_user_and_remove_groups() {
     organizationFlags.setEnabled(true);
     UserDto user = db.users().insertUser(newUserDto()
-      .setLogin(USER_LOGIN)
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
       .setActive(true)
       .setName("John"));
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
@@ -702,7 +706,7 @@ public class UserRegistrarImplTest {
     db.users().insertMember(group1, user);
     db.users().insertMember(group2, user);
 
-    authenticate(USER_LOGIN, "group1");
+    authenticate(USER_IDENTITY.getProviderLogin(), "group1");
 
     checkGroupMembership(user, group1);
   }
@@ -710,7 +714,10 @@ public class UserRegistrarImplTest {
   @Test
   public void authenticate_existing_user_and_remove_all_groups_expect_default_when_organizations_are_disabled() {
     organizationFlags.setEnabled(false);
-    UserDto user = db.users().insertUser();
+    UserDto user = db.users().insertUser(newUserDto()
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
+    );
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
     GroupDto defaultGroup = insertDefaultGroup();
@@ -718,7 +725,7 @@ public class UserRegistrarImplTest {
     db.users().insertMember(group2, user);
     db.users().insertMember(defaultGroup, user);
 
-    authenticate(user.getLogin());
+    authenticate(user.getExternalLogin());
 
     checkGroupMembership(user, defaultGroup);
   }
@@ -726,13 +733,16 @@ public class UserRegistrarImplTest {
   @Test
   public void does_not_force_default_group_when_authenticating_existing_user_when_organizations_are_enabled() {
     organizationFlags.setEnabled(true);
-    UserDto user = db.users().insertUser();
+    UserDto user = db.users().insertUser(newUserDto()
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
+    );
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto defaultGroup = insertDefaultGroup();
     db.users().insertMember(group1, user);
     db.users().insertMember(defaultGroup, user);
 
-    authenticate(user.getLogin(), "group1");
+    authenticate(user.getExternalLogin(), "group1");
 
     checkGroupMembership(user, group1);
   }
@@ -742,7 +752,8 @@ public class UserRegistrarImplTest {
     organizationFlags.setEnabled(true);
     OrganizationDto org = db.organizations().insert();
     UserDto user = db.users().insertUser(newUserDto()
-      .setLogin(USER_LOGIN)
+      .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey())
+      .setExternalLogin(USER_IDENTITY.getProviderLogin())
       .setActive(true)
       .setName("John"));
     String groupName = "a-group";
@@ -753,7 +764,6 @@ public class UserRegistrarImplTest {
     underTest.register(UserRegistration.builder()
       .setUserIdentity(UserIdentity.builder()
         .setProviderLogin("johndoo")
-        .setLogin(user.getLogin())
         .setName(user.getName())
         .setGroups(newHashSet(groupName))
         .build())
@@ -765,11 +775,10 @@ public class UserRegistrarImplTest {
     checkGroupMembership(user, groupInDefaultOrg);
   }
 
-  private void authenticate(String login, String... groups) {
-    underTest.register(UserRegistration.builder()
+  private UserDto authenticate(String providerLogin, String... groups) {
+    return underTest.register(UserRegistration.builder()
       .setUserIdentity(UserIdentity.builder()
-        .setProviderLogin("johndoo")
-        .setLogin(login)
+        .setProviderLogin(providerLogin)
         .setName("John")
         // No group
         .setGroups(stream(groups).collect(MoreCollectors.toSet()))
@@ -781,7 +790,7 @@ public class UserRegistrarImplTest {
   }
 
   private void checkGroupMembership(UserDto user, GroupDto... expectedGroups) {
-    assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(stream(expectedGroups).map(GroupDto::getId).collect(Collectors.toList()).toArray(new Integer[] {}));
+    assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(stream(expectedGroups).map(GroupDto::getId).collect(Collectors.toList()).toArray(new Integer[]{}));
   }
 
   private GroupDto insertDefaultGroup() {
index c1c322d9e1680c99648be8c8a9287aa50a6e61ed..301ee897045b19a29bca6cab61dca125553ec716 100644 (file)
@@ -68,7 +68,7 @@ public class UpdateLoginActionTest {
     organizationUpdater));
 
   @Test
-  public void update_login_from_sonarqube_account() {
+  public void update_login_from_sonarqube_account_when_user_is_local() {
     userSession.logIn().setSystemAdministrator();
     UserDto user = db.users().insertUser(u -> u
       .setLogin("old_login")
@@ -92,6 +92,31 @@ public class UpdateLoginActionTest {
     assertThat(userReloaded.getSalt()).isNotNull().isEqualTo(user.getSalt());
   }
 
+  @Test
+  public void update_login_from_sonarqube_account_when_user_is_not_local() {
+    userSession.logIn().setSystemAdministrator();
+    UserDto user = db.users().insertUser(u -> u
+      .setLogin("old_login")
+      .setLocal(false)
+      .setExternalIdentityProvider("sonarqube")
+      .setExternalLogin("old_login")
+      .setExternalId("old_login"));
+
+    ws.newRequest()
+      .setParam("login", user.getLogin())
+      .setParam("newLogin", "new_login")
+      .execute();
+
+    assertThat(db.getDbClient().userDao().selectByLogin(db.getSession(), "old_login")).isNull();
+    UserDto userReloaded = db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid());
+    assertThat(userReloaded.getLogin()).isEqualTo("new_login");
+    assertThat(userReloaded.getExternalLogin()).isEqualTo("new_login");
+    assertThat(userReloaded.getExternalId()).isEqualTo("new_login");
+    assertThat(userReloaded.isLocal()).isFalse();
+    assertThat(userReloaded.getCryptedPassword()).isNotNull().isEqualTo(user.getCryptedPassword());
+    assertThat(userReloaded.getSalt()).isNotNull().isEqualTo(user.getSalt());
+  }
+
   @Test
   public void update_login_from_external_account() {
     userSession.logIn().setSystemAdministrator();
index 5d398b9d5adca016ff2d2ea5d34c9c49e8bc2c32..8699cb932704ac7c58f99ec8996acd503b801333 100644 (file)
@@ -27,7 +27,6 @@ import javax.annotation.concurrent.Immutable;
 import org.sonar.api.user.UserGroupValidation;
 
 import static java.util.Objects.requireNonNull;
-import static org.apache.commons.lang.StringUtils.isBlank;
 import static org.apache.commons.lang.StringUtils.isNotBlank;
 import static org.sonar.api.utils.Preconditions.checkArgument;
 
@@ -42,8 +41,6 @@ public final class UserIdentity {
   @Nullable
   private final String id;
   private final String providerLogin;
-  @Nullable
-  private final String login;
   private final String name;
   @Nullable
   private final String email;
@@ -53,7 +50,6 @@ public final class UserIdentity {
   private UserIdentity(Builder builder) {
     this.id = builder.id;
     this.providerLogin = builder.providerLogin;
-    this.login = builder.login;
     this.name = builder.name;
     this.email = builder.email;
     this.groupsProvided = builder.groupsProvided;
@@ -86,10 +82,15 @@ public final class UserIdentity {
    *
    * Since 7.4, a unique login will be generated if result is null and the user referenced by {@link #getProviderId()}
    * or {@link #getProviderLogin()} does not already exist.
+   *
+   * @deprecated since 8.0, should not be used as it is internal managed field
+   *
+   * @return null
    */
   @CheckForNull
+  @Deprecated
   public String getLogin() {
-    return login;
+    return null;
   }
 
   /**
@@ -134,7 +135,6 @@ public final class UserIdentity {
   public static class Builder {
     private String id;
     private String providerLogin;
-    private String login;
     private String name;
     private String email;
     private boolean groupsProvided = false;
@@ -162,9 +162,11 @@ public final class UserIdentity {
 
     /**
      * @see UserIdentity#getLogin()
+     *
+     * @deprecated since 8.0, has no effect as it is internal managed field
      */
+    @Deprecated
     public Builder setLogin(@Nullable String login) {
-      this.login = login;
       return this;
     }
 
@@ -210,7 +212,6 @@ public final class UserIdentity {
     public UserIdentity build() {
       validateId(id);
       validateProviderLogin(providerLogin);
-      validateLogin(login);
       validateName(name);
       validateEmail(email);
       return new UserIdentity(this);
@@ -225,10 +226,6 @@ public final class UserIdentity {
       checkArgument(providerLogin.length() <= 255, "Provider login size is incorrect (maximum 255 characters)");
     }
 
-    private static void validateLogin(@Nullable String login) {
-      checkArgument(isBlank(login) || (login.length() <= 255 && login.length() >= 2), "User login size is incorrect (Between 2 and 255 characters)");
-    }
-
     private static void validateName(String name) {
       checkArgument(isNotBlank(name), "User name must not be blank");
       checkArgument(name.length() <= 200, "User name size is too big (200 characters max)");
index d954757300f003b04b32332896253fc1deaf433e..7b583ecaf4ee2e47c6f2e03fc8328a09e92eb80e 100644 (file)
@@ -37,14 +37,12 @@ public class UserIdentityTest {
     UserIdentity underTest = UserIdentity.builder()
       .setProviderId("4321")
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .build();
 
     assertThat(underTest.getProviderId()).isEqualTo("4321");
     assertThat(underTest.getProviderLogin()).isEqualTo("john");
-    assertThat(underTest.getLogin()).isEqualTo("1234");
     assertThat(underTest.getName()).isEqualTo("John");
     assertThat(underTest.getEmail()).isEqualTo("john@email.com");
     assertThat(underTest.shouldSyncGroups()).isFalse();
@@ -61,7 +59,6 @@ public class UserIdentityTest {
     assertThat(underTest.getProviderLogin()).isEqualTo("john");
     assertThat(underTest.getName()).isEqualTo("John");
     assertThat(underTest.getProviderId()).isNull();
-    assertThat(underTest.getLogin()).isNull();
     assertThat(underTest.getEmail()).isNull();
     assertThat(underTest.shouldSyncGroups()).isFalse();
     assertThat(underTest.getGroups()).isEmpty();
@@ -74,41 +71,15 @@ public class UserIdentityTest {
     UserIdentity.builder()
       .setProviderId(Strings.repeat("1", 256))
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .build();
   }
 
-  @Test
-  public void fail_when_login_is_too_long() {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("User login size is incorrect (Between 2 and 255 characters)");
-    UserIdentity.builder()
-      .setProviderLogin("john")
-      .setLogin(Strings.repeat("1", 256))
-      .setName("John")
-      .setEmail("john@email.com")
-      .build();
-  }
-
-  @Test
-  public void fail_when_login_is_too_small() {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("User login size is incorrect (Between 2 and 255 characters)");
-    UserIdentity.builder()
-      .setProviderLogin("john")
-      .setLogin("j")
-      .setName("John")
-      .setEmail("john@email.com")
-      .build();
-  }
-
   @Test
   public void fail_when_provider_login_is_null() {
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("Provider login must not be blank");
     UserIdentity.builder()
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .build();
@@ -120,7 +91,6 @@ public class UserIdentityTest {
     thrown.expectMessage("Provider login must not be blank");
     UserIdentity.builder()
       .setProviderLogin("")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .build();
@@ -132,7 +102,6 @@ public class UserIdentityTest {
     thrown.expectMessage("Provider login size is incorrect (maximum 255 characters)");
     UserIdentity.builder()
       .setProviderLogin(Strings.repeat("1", 256))
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .build();
@@ -144,7 +113,6 @@ public class UserIdentityTest {
     thrown.expectMessage("User name must not be blank");
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setEmail("john@email.com")
       .build();
   }
@@ -155,7 +123,6 @@ public class UserIdentityTest {
     thrown.expectMessage("User name must not be blank");
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("")
       .setEmail("john@email.com")
       .build();
@@ -167,7 +134,6 @@ public class UserIdentityTest {
     thrown.expectMessage("User name size is too big (200 characters max)");
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName(Strings.repeat("1", 201))
       .setEmail("john@email.com")
       .build();
@@ -179,7 +145,6 @@ public class UserIdentityTest {
     thrown.expectMessage("User email size is too big (100 characters max)");
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail(Strings.repeat("1", 101))
       .build();
@@ -189,7 +154,6 @@ public class UserIdentityTest {
   public void create_user_with_groups() {
     UserIdentity underTest = UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(newHashSet("admin", "user"))
@@ -206,7 +170,6 @@ public class UserIdentityTest {
 
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(null);
@@ -219,7 +182,6 @@ public class UserIdentityTest {
 
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(newHashSet(""));
@@ -232,7 +194,6 @@ public class UserIdentityTest {
 
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(newHashSet("      "));
@@ -245,7 +206,6 @@ public class UserIdentityTest {
 
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(newHashSet((String)null));
@@ -258,7 +218,6 @@ public class UserIdentityTest {
 
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(newHashSet("Anyone"));
@@ -271,7 +230,6 @@ public class UserIdentityTest {
 
     UserIdentity.builder()
       .setProviderLogin("john")
-      .setLogin("1234")
       .setName("John")
       .setEmail("john@email.com")
       .setGroups(newHashSet(Strings.repeat("group", 300)));