]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8192 set root flag in UserIdentityAuthenticator
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 17 Oct 2016 10:28:47 +0000 (12:28 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 19 Oct 2016 12:45:13 +0000 (14:45 +0200)
depending upon whether groups of the user have or not System Administer permision and whether, when it already exists, the user has user permission "System Administer"

server/sonar-server/src/main/java/org/sonar/server/authentication/UserIdentityAuthenticator.java
server/sonar-server/src/test/java/org/sonar/server/authentication/UserIdentityAuthenticatorTest.java
sonar-db/src/test/java/org/sonar/db/user/RootFlagAssertions.java
sonar-db/src/test/java/org/sonar/db/user/UserDbTester.java

index 07de4b5d8dfdcad3ad8aa6c72fb951145695621a..1653c01626eb98c6a82f24830ef85f44bfdc7ad3 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.db.DbSession;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserGroupDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.user.ExternalIdentity;
 import org.sonar.server.user.NewUser;
 import org.sonar.server.user.UpdateUser;
@@ -52,10 +53,12 @@ public class UserIdentityAuthenticator {
 
   private final DbClient dbClient;
   private final UserUpdater userUpdater;
+  private final DefaultOrganizationProvider defaultOrganizationProvider;
 
-  public UserIdentityAuthenticator(DbClient dbClient, UserUpdater userUpdater) {
+  public UserIdentityAuthenticator(DbClient dbClient, UserUpdater userUpdater, DefaultOrganizationProvider defaultOrganizationProvider) {
     this.dbClient = dbClient;
     this.userUpdater = userUpdater;
+    this.defaultOrganizationProvider = defaultOrganizationProvider;
   }
 
   public UserDto authenticate(UserIdentity user, IdentityProvider provider) {
@@ -96,6 +99,7 @@ public class UserIdentityAuthenticator {
       .setExternalIdentity(new ExternalIdentity(provider.getKey(), user.getProviderLogin())));
     UserDto newUser = dbClient.userDao().selectOrFailByLogin(dbSession, userLogin);
     syncGroups(dbSession, user, newUser);
+    updateRootFlag(dbSession, newUser);
     return newUser;
   }
 
@@ -106,6 +110,7 @@ public class UserIdentityAuthenticator {
       .setExternalIdentity(new ExternalIdentity(provider.getKey(), user.getProviderLogin()))
       .setPassword(null));
     syncGroups(dbSession, user, userDto);
+    updateRootFlag(dbSession, userDto);
   }
 
   private void syncGroups(DbSession dbSession, UserIdentity userIdentity, UserDto userDto) {
@@ -144,6 +149,11 @@ public class UserIdentityAuthenticator {
       });
   }
 
+  private void updateRootFlag(DbSession dbSession, UserDto userDto) {
+    dbClient.userDao().updateRootFlagFromPermissions(dbSession, userDto.getId(), defaultOrganizationProvider.get().getUuid());
+    dbSession.commit();
+  }
+
   private enum GroupDtoToName implements Function<GroupDto, String> {
     INSTANCE;
 
index 0d6e3034320ca543925ab08eebaabb13b3c33a45..fb612c5bf71f393001e784daba88eb70f01f61a0 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.server.authentication;
 
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.Optional;
 import org.junit.Before;
 import org.junit.Rule;
@@ -30,7 +30,9 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.server.authentication.UnauthorizedException;
 import org.sonar.api.server.authentication.UserIdentity;
 import org.sonar.api.utils.System2;
+import org.sonar.core.util.stream.Collectors;
 import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.organization.DefaultOrganizationProvider;
@@ -39,7 +41,6 @@ import org.sonar.server.user.NewUserNotifier;
 import org.sonar.server.user.UserUpdater;
 import org.sonar.server.user.index.UserIndexer;
 
-import static com.google.common.collect.Sets.newHashSet;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.sonar.db.user.UserTesting.newUserDto;
@@ -64,10 +65,8 @@ public class UserIdentityAuthenticatorTest {
   @Rule
   public ExpectedException thrown = ExpectedException.none();
 
-  private System2 system2 = mock(System2.class);
-
   @Rule
-  public DbTester db = DbTester.create(system2);
+  public DbTester db = DbTester.create(System2.INSTANCE);
 
   private Settings settings = new MapSettings();
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
@@ -76,9 +75,9 @@ public class UserIdentityAuthenticatorTest {
     settings,
     db.getDbClient(),
     mock(UserIndexer.class),
-    system2,
+    System2.INSTANCE,
     defaultOrganizationProvider);
-  private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater);
+  private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater, defaultOrganizationProvider);
   private GroupDto defaultGroup;
 
   @Before
@@ -107,13 +106,7 @@ public class UserIdentityAuthenticatorTest {
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
 
-    underTest.authenticate(UserIdentity.builder()
-      .setProviderLogin("johndoo")
-      .setLogin(USER_LOGIN)
-      .setName("John")
-      // group3 doesn't exist in db, it will be ignored
-      .setGroups(newHashSet("group1", "group2", "group3"))
-      .build(), IDENTITY_PROVIDER);
+    authenticate(USER_LOGIN, "group1", "group2", "group3");
 
     Optional<UserDto> user = db.users().selectUserByLogin(USER_LOGIN);
     assertThat(user).isPresent();
@@ -170,13 +163,7 @@ public class UserIdentityAuthenticatorTest {
     GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
     GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
 
-    underTest.authenticate(UserIdentity.builder()
-      .setProviderLogin("johndoo")
-      .setLogin(USER_LOGIN)
-      .setName("John")
-      // group3 doesn't exist in db, it will be ignored
-      .setGroups(newHashSet("group1", "group2", "group3"))
-      .build(), IDENTITY_PROVIDER);
+    authenticate(USER_LOGIN, "group1", "group2", "group3");
 
     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId(), group2.getId());
   }
@@ -192,13 +179,7 @@ public class UserIdentityAuthenticatorTest {
     db.users().insertMember(group1, user);
     db.users().insertMember(group2, user);
 
-    underTest.authenticate(UserIdentity.builder()
-      .setProviderLogin("johndoo")
-      .setLogin(USER_LOGIN)
-      .setName("John")
-      // Only group1 is returned by the id provider => group2 will be removed
-      .setGroups(newHashSet("group1"))
-      .build(), IDENTITY_PROVIDER);
+    authenticate(USER_LOGIN, "group1");
 
     assertThat(db.users().selectGroupIdsOfUser(user)).containsOnly(group1.getId());
   }
@@ -214,17 +195,139 @@ public class UserIdentityAuthenticatorTest {
     db.users().insertMember(group1, user);
     db.users().insertMember(group2, user);
 
-    underTest.authenticate(UserIdentity.builder()
-      .setProviderLogin("johndoo")
-      .setLogin(USER_LOGIN)
-      .setName("John")
-      // No group => group1 and group2 will be removed
-      .setGroups(Collections.emptySet())
-      .build(), IDENTITY_PROVIDER);
+    authenticate(USER_LOGIN);
 
     assertThat(db.users().selectGroupIdsOfUser(user)).isEmpty();
   }
 
+  @Test
+  public void authenticate_new_user_and_add_it_to_no_group_sets_root_flag_to_false() {
+    authenticate(USER_LOGIN);
+
+    db.rootFlag().verify(USER_LOGIN, false);
+  }
+
+  @Test
+  public void authenticate_new_user_and_add_it_to_admin_group_of_default_organization_sets_root_flag_to_true() {
+    GroupDto adminGroup = db.users().insertAdminGroup(db.getDefaultOrganization());
+
+    authenticate(USER_LOGIN, adminGroup.getName());
+
+    db.rootFlag().verify(USER_LOGIN, true);
+  }
+
+  @Test
+  public void authenticate_new_user_and_add_it_to_admin_group_of_other_organization_does_not_set_root_flag_to_true() {
+    OrganizationDto otherOrganization = db.organizations().insert();
+    GroupDto adminGroup = db.users().insertAdminGroup(otherOrganization);
+
+    authenticate(USER_LOGIN, adminGroup.getName());
+
+    db.rootFlag().verify(USER_LOGIN, false);
+  }
+
+  @Test
+  public void authenticate_existing_user_and_add_it_to_no_group_sets_root_flag_to_false() {
+    UserDto userDto = db.users().insertUser();
+
+    authenticate(userDto.getLogin());
+
+    db.rootFlag().verify(userDto, false);
+  }
+
+  @Test
+  public void authenticate_existing_user_and_add_it_to_admin_group_of_default_organization_sets_root_flag_to_true() {
+    GroupDto adminGroup = db.users().insertAdminGroup(db.getDefaultOrganization());
+    UserDto userDto = db.users().insertUser();
+
+    authenticate(userDto.getLogin(), adminGroup.getName());
+
+    db.rootFlag().verify(userDto, true);
+  }
+
+  @Test
+  public void authenticate_existing_user_and_add_it_to_admin_group_of_other_organization_sets_root_flag_to_false() {
+    OrganizationDto otherOrganization = db.organizations().insert();
+    GroupDto adminGroup = db.users().insertAdminGroup(otherOrganization);
+    UserDto userDto = db.users().insertUser();
+
+    authenticate(userDto.getLogin(), adminGroup.getName());
+
+    db.rootFlag().verify(userDto, false);
+  }
+
+  @Test
+  public void authenticate_existing_user_and_remove_it_from_admin_group_of_default_organization_sets_root_flag_to_false() {
+    GroupDto adminGroup = db.users().insertAdminGroup(db.getDefaultOrganization());
+    UserDto userDto = db.users().makeRoot(db.users().insertUser());
+    db.users().insertMembers(adminGroup, userDto);
+
+    authenticate(userDto.getLogin());
+
+    db.rootFlag().verify(userDto, false);
+  }
+
+  @Test
+  public void authenticate_existing_user_with_user_permission_admin_on_default_organization_with_no_group_does_not_set_root_flag_to_false() {
+    UserDto rootUser = db.users().insertRootByUserPermission();
+
+    authenticate(rootUser.getLogin());
+
+
+    db.rootFlag().verify(rootUser, true);
+  }
+
+  @Test
+  public void authenticate_existing_user_with_user_permission_admin_on_default_organization_with_non_admin_groups_does_not_set_root_flag_to_false() {
+    OrganizationDto otherOrganization = db.organizations().insert();
+    GroupDto defaultOrgGroup = db.users().insertGroup(db.getDefaultOrganization());
+    GroupDto otherOrgGroup = db.users().insertGroup(otherOrganization);
+    UserDto rootUser = db.users().insertRootByUserPermission();
+
+    authenticate(rootUser.getLogin(), defaultOrgGroup.getName(), otherOrgGroup.getName());
+
+    db.rootFlag().verify(rootUser, true);
+  }
+
+  @Test
+  public void authenticate_user_multiple_times_sets_root_flag_to_true_only_if_at_least_one_group_is_admin() {
+    GroupDto defaultAdminGroup = db.users().insertAdminGroup(db.getDefaultOrganization(), "admin_of_default");
+    GroupDto defaultSomeGroup = db.users().insertGroup(db.getDefaultOrganization(), "some_group_of_default");
+    OrganizationDto otherOrganization = db.organizations().insert();
+    GroupDto otherAdminGroup = db.users().insertAdminGroup(otherOrganization, "admin_of_other");
+    GroupDto otherSomeGroup = db.users().insertGroup(otherOrganization, "some_group_of_other");
+
+    authenticate(USER_LOGIN, defaultAdminGroup.getName(), defaultSomeGroup.getName(), otherAdminGroup.getName(), otherSomeGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, true);
+
+    authenticate(USER_LOGIN, defaultAdminGroup.getName(), defaultSomeGroup.getName(), otherAdminGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, true);
+
+    authenticate(USER_LOGIN, otherAdminGroup.getName(), defaultAdminGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, true);
+
+    authenticate(USER_LOGIN, otherAdminGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, false);
+
+    authenticate(USER_LOGIN, otherAdminGroup.getName(), otherSomeGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, false);
+
+    authenticate(USER_LOGIN, otherAdminGroup.getName(), otherSomeGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, false);
+
+    authenticate(USER_LOGIN, otherAdminGroup.getName(), defaultAdminGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, true);
+
+    authenticate(USER_LOGIN, defaultSomeGroup.getName(), defaultAdminGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, true);
+
+    authenticate(USER_LOGIN, otherSomeGroup.getName(), defaultAdminGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, true);
+
+    authenticate(USER_LOGIN, otherSomeGroup.getName(), defaultSomeGroup.getName());
+    db.rootFlag().verify(USER_LOGIN, false);
+  }
+
   @Test
   public void fail_to_authenticate_new_user_when_allow_users_to_signup_is_false() throws Exception {
     TestIdentityProvider identityProvider = new TestIdentityProvider()
@@ -251,4 +354,14 @@ public class UserIdentityAuthenticatorTest {
     underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER);
   }
 
+  private void authenticate(String login, String... groups) {
+    underTest.authenticate(UserIdentity.builder()
+      .setProviderLogin("johndoo")
+      .setLogin(login)
+      .setName("John")
+      // No group
+      .setGroups(Arrays.stream(groups).collect(Collectors.toSet()))
+      .build(), IDENTITY_PROVIDER);
+  }
+
 }
index 344d5dcb7cedd80750bf2a2a67a370bc3d5648d2..af7abd8f7c70e6c39cafd15fdbba86dbe364a6a6 100644 (file)
@@ -51,6 +51,12 @@ public class RootFlagAssertions {
       .isEqualTo(root);
     assertThat(dto.getUpdatedAt())
       .as("UpdatedAt of user '%s' has changed since insertion", userDto.getLogin())
-      .isNotEqualTo(userDto);
+      .isNotEqualTo(userDto.getUpdatedAt());
+  }
+
+  public void verify(String login, boolean root) {
+    assertThat(db.getDbClient().userDao().selectByLogin(db.getSession(), login).isRoot())
+      .as("Root flag of user '%s' is '%s'", login, root)
+      .isEqualTo(root);
   }
 }
index 31ef077d935516b034cf67a866257d2bfd8dcc5e..3f8e9f63dfb94a3348a65fa0ff134f3663707e0f 100644 (file)
@@ -172,6 +172,16 @@ public class UserDbTester {
     return groupDto;
   }
 
+  /**
+   * Creates a group with the specified name in the specified organization with {@link GlobalPermissions#SYSTEM_ADMIN}
+   * permission.
+   */
+  public GroupDto insertAdminGroup(OrganizationDto organizationDto, String name) {
+    GroupDto groupDto = insertGroup(organizationDto, name);
+    insertPermissionOnGroup(groupDto, SYSTEM_ADMIN);
+    return groupDto;
+  }
+
   /**
    * Create group in specified organization
    */