]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9018 Create a "members" group when creating an organization
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 4 Apr 2017 12:02:21 +0000 (14:02 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 13 Apr 2017 09:51:55 +0000 (11:51 +0200)
server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationCreation.java
server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationCreationImpl.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/EnableSupportAction.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/usergroups/DefaultGroupCreator.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/usergroups/DefaultGroupCreatorImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/usergroups/package-info.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/organization/OrganizationCreationImplTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/EnableSupportActionTest.java
server/sonar-server/src/test/java/org/sonar/server/usergroups/DefaultGroupCreatorImplTest.java [new file with mode: 0644]

index 50904435bbcb52afac4d5b9b5543a0bda0a7c88e..f71841b2463a4f4ed9288d1ef87e997c5d23bec3 100644 (file)
@@ -27,6 +27,7 @@ import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.DbSession;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.user.UserDto;
+import org.sonar.server.usergroups.DefaultGroupCreatorImpl;
 
 import static java.util.Objects.requireNonNull;
 
@@ -45,7 +46,8 @@ public interface OrganizationCreation {
    * <ol>
    *   <li>create an ungarded organization with the specified details</li>
    *   <li>create a group called {@link #OWNERS_GROUP_NAME Owners} with all organization wide permissions</li>
-   *   <li>make the specified user a member of this group</li>
+   *   <li>create a group called {@link DefaultGroupCreatorImpl#DEFAULT_GROUP_NAME members} with browse permissions</li>
+   *   <li>make the specified user a member of these groups</li>
    *   <li>create a default template for the organization
    *       <ul>
    *         <li>name is {@link #PERM_TEMPLATE_NAME Default template}</li>
@@ -57,8 +59,8 @@ public interface OrganizationCreation {
    *       <li>group {@link #OWNERS_GROUP_NAME Owners} : {@link UserRole#ADMIN ADMIN}</li>
    *       <li>group {@link #OWNERS_GROUP_NAME Owners} : {@link UserRole#ISSUE_ADMIN ISSUE_ADMIN}</li>
    *       <li>group {@link #OWNERS_GROUP_NAME Owners} : {@link GlobalPermissions#SCAN_EXECUTION SCAN_EXECUTION}</li>
-   *       <li>anyone : {@link UserRole#USER USER}</li>
-   *       <li>anyone : {@link UserRole#CODEVIEWER CODEVIEWER}</li>
+   *       <li>group {@link DefaultGroupCreatorImpl#DEFAULT_GROUP_NAME members} : {@link UserRole#USER USER}</li>
+   *       <li>group {@link DefaultGroupCreatorImpl#DEFAULT_GROUP_NAME members} : {@link UserRole#CODEVIEWER CODEVIEWER}</li>
    *     </ul>
    *   </li>
    * </ol>
@@ -86,6 +88,8 @@ public interface OrganizationCreation {
    *       <li>url and avatar: null</li>
    *     </ul>
    *   </li>
+   *   <li>create a group called {@link DefaultGroupCreatorImpl#DEFAULT_GROUP_NAME members} with browse permissions</li>
+   *   <li>make the specified user a member of this group</li>
    *   <li>give all organization wide permissions to the user</li>
    *   <li>create a default template for the organization
    *       <ul>
@@ -99,8 +103,8 @@ public interface OrganizationCreation {
    *       <li>project creator : {@link UserRole#ADMIN ADMIN}</li>
    *       <li>project creator : {@link UserRole#ISSUE_ADMIN ISSUE_ADMIN}</li>
    *       <li>project creator : {@link GlobalPermissions#SCAN_EXECUTION SCAN_EXECUTION}</li>
-   *       <li>anyone : {@link UserRole#USER USER}</li>
-   *       <li>anyone : {@link UserRole#CODEVIEWER CODEVIEWER}</li>
+   *       <li>group {@link DefaultGroupCreatorImpl#DEFAULT_GROUP_NAME members} : {@link UserRole#USER USER}</li>
+   *       <li>group {@link DefaultGroupCreatorImpl#DEFAULT_GROUP_NAME members} : {@link UserRole#CODEVIEWER CODEVIEWER}</li>
    *     </ul>
    *   </li>
    * </ol>
index 211141d711e93a3a2df988cbc72429d6a9e9ee8b..51b76f3239831b09a30816845524ca6144f4757f 100644 (file)
@@ -29,9 +29,7 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.web.UserRole;
 import org.sonar.core.config.CorePropertyDefinitions;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -52,10 +50,16 @@ import org.sonar.server.qualityprofile.DefinedQProfileCreation;
 import org.sonar.server.qualityprofile.DefinedQProfileRepository;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
 import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.usergroups.DefaultGroupCreator;
 
 import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
 import static java.util.Objects.requireNonNull;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.CODEVIEWER;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.permission.OrganizationPermission.SCAN;
 import static org.sonar.server.organization.OrganizationCreation.NewOrganization.newOrganizationBuilder;
 
 public class OrganizationCreationImpl implements OrganizationCreation {
@@ -68,12 +72,14 @@ public class OrganizationCreationImpl implements OrganizationCreation {
   private final Settings settings;
   private final DefinedQProfileRepository definedQProfileRepository;
   private final DefinedQProfileCreation definedQProfileCreation;
+  private final DefaultGroupCreator defaultGroupCreator;
   private final ActiveRuleIndexer activeRuleIndexer;
   private final UserIndexer userIndexer;
 
   public OrganizationCreationImpl(DbClient dbClient, System2 system2, UuidFactory uuidFactory,
     OrganizationValidation organizationValidation, Settings settings, UserIndexer userIndexer,
-    DefinedQProfileRepository definedQProfileRepository, DefinedQProfileCreation definedQProfileCreation, ActiveRuleIndexer activeRuleIndexer) {
+    DefinedQProfileRepository definedQProfileRepository, DefinedQProfileCreation definedQProfileCreation, DefaultGroupCreator defaultGroupCreator,
+    ActiveRuleIndexer activeRuleIndexer) {
     this.dbClient = dbClient;
     this.system2 = system2;
     this.uuidFactory = uuidFactory;
@@ -82,6 +88,7 @@ public class OrganizationCreationImpl implements OrganizationCreation {
     this.userIndexer = userIndexer;
     this.definedQProfileRepository = definedQProfileRepository;
     this.definedQProfileCreation = definedQProfileCreation;
+    this.defaultGroupCreator = defaultGroupCreator;
     this.activeRuleIndexer = activeRuleIndexer;
   }
 
@@ -96,10 +103,12 @@ public class OrganizationCreationImpl implements OrganizationCreation {
     OrganizationDto organization = insertOrganization(dbSession, newOrganization, dto -> {
     });
     insertOrganizationMember(dbSession, organization, userCreator.getId());
-    GroupDto group = insertOwnersGroup(dbSession, organization);
-    insertDefaultTemplate(dbSession, organization, group);
+    GroupDto ownerGroup = insertOwnersGroup(dbSession, organization);
+    GroupDto defaultGroup = defaultGroupCreator.create(dbSession, organization.getUuid());
+    insertDefaultTemplateOnGroups(dbSession, organization, ownerGroup, defaultGroup);
     List<ActiveRuleChange> activeRuleChanges = insertQualityProfiles(dbSession, organization);
-    addCurrentUserToGroup(dbSession, group, userCreator.getId());
+    addCurrentUserToGroup(dbSession, ownerGroup, userCreator.getId());
+    addCurrentUserToGroup(dbSession, defaultGroup, userCreator.getId());
 
     dbSession.commit();
 
@@ -129,11 +138,13 @@ public class OrganizationCreationImpl implements OrganizationCreation {
 
     OrganizationDto organization = insertOrganization(dbSession, newOrganization,
       dto -> dto.setGuarded(true).setUserId(newUser.getId()));
+    insertOrganizationMember(dbSession, organization, newUser.getId());
+    GroupDto defaultGroup = defaultGroupCreator.create(dbSession, organization.getUuid());
     OrganizationPermission.all()
       .forEach(p -> insertUserPermissions(dbSession, newUser, organization, p));
-    insertPersonalOrgDefaultTemplate(dbSession, organization);
-    insertOrganizationMember(dbSession, organization, newUser.getId());
+    insertPersonalOrgDefaultTemplate(dbSession, organization, defaultGroup);
     List<ActiveRuleChange> activeRuleChanges = insertQualityProfiles(dbSession, organization);
+    addCurrentUserToGroup(dbSession, defaultGroup, newUser.getId());
 
     dbSession.commit();
 
@@ -189,7 +200,7 @@ public class OrganizationCreationImpl implements OrganizationCreation {
     return dbClient.organizationDao().selectByKey(dbSession, key).isPresent();
   }
 
-  private void insertDefaultTemplate(DbSession dbSession, OrganizationDto organizationDto, GroupDto group) {
+  private void insertDefaultTemplateOnGroups(DbSession dbSession, OrganizationDto organizationDto, GroupDto ownerGroup, GroupDto defaultGroup) {
     Date now = new Date(system2.now());
     PermissionTemplateDto permissionTemplateDto = dbClient.permissionTemplateDao().insert(
       dbSession,
@@ -201,11 +212,11 @@ public class OrganizationCreationImpl implements OrganizationCreation {
         .setCreatedAt(now)
         .setUpdatedAt(now));
 
-    insertGroupPermission(dbSession, permissionTemplateDto, UserRole.ADMIN, group);
-    insertGroupPermission(dbSession, permissionTemplateDto, UserRole.ISSUE_ADMIN, group);
-    insertGroupPermission(dbSession, permissionTemplateDto, GlobalPermissions.SCAN_EXECUTION, group);
-    insertGroupPermission(dbSession, permissionTemplateDto, UserRole.USER, null);
-    insertGroupPermission(dbSession, permissionTemplateDto, UserRole.CODEVIEWER, null);
+    insertGroupPermission(dbSession, permissionTemplateDto, ADMIN, ownerGroup);
+    insertGroupPermission(dbSession, permissionTemplateDto, ISSUE_ADMIN, ownerGroup);
+    insertGroupPermission(dbSession, permissionTemplateDto, SCAN.getKey(), ownerGroup);
+    insertGroupPermission(dbSession, permissionTemplateDto, USER, defaultGroup);
+    insertGroupPermission(dbSession, permissionTemplateDto, CODEVIEWER, defaultGroup);
 
     dbClient.organizationDao().setDefaultTemplates(
       dbSession,
@@ -213,7 +224,7 @@ public class OrganizationCreationImpl implements OrganizationCreation {
       new DefaultTemplates().setProjectUuid(permissionTemplateDto.getUuid()));
   }
 
-  private void insertPersonalOrgDefaultTemplate(DbSession dbSession, OrganizationDto organizationDto) {
+  private void insertPersonalOrgDefaultTemplate(DbSession dbSession, OrganizationDto organizationDto, GroupDto defaultGroup) {
     long now = system2.now();
     Date dateNow = new Date(now);
     PermissionTemplateDto permissionTemplateDto = dbClient.permissionTemplateDao().insert(
@@ -226,11 +237,11 @@ public class OrganizationCreationImpl implements OrganizationCreation {
         .setCreatedAt(dateNow)
         .setUpdatedAt(dateNow));
 
-    insertProjectCreatorPermission(dbSession, permissionTemplateDto, UserRole.ADMIN, now);
-    insertProjectCreatorPermission(dbSession, permissionTemplateDto, UserRole.ISSUE_ADMIN, now);
-    insertProjectCreatorPermission(dbSession, permissionTemplateDto, OrganizationPermission.SCAN.getKey(), now);
-    insertGroupPermission(dbSession, permissionTemplateDto, UserRole.USER, null);
-    insertGroupPermission(dbSession, permissionTemplateDto, UserRole.CODEVIEWER, null);
+    insertProjectCreatorPermission(dbSession, permissionTemplateDto, ADMIN, now);
+    insertProjectCreatorPermission(dbSession, permissionTemplateDto, ISSUE_ADMIN, now);
+    insertProjectCreatorPermission(dbSession, permissionTemplateDto, SCAN.getKey(), now);
+    insertGroupPermission(dbSession, permissionTemplateDto, USER, defaultGroup);
+    insertGroupPermission(dbSession, permissionTemplateDto, CODEVIEWER, defaultGroup);
 
     dbClient.organizationDao().setDefaultTemplates(
       dbSession,
index a887cf94cae43e5487659dcb28a93d5a7c4083c5..e2245de20d9b1506a1c7e93fd85a3f1f5be353cc 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.server.organization.ws;
 
 import java.util.List;
-import java.util.Optional;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -35,8 +34,8 @@ import org.sonar.db.user.UserGroupDto;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.organization.OrganizationFlags;
 import org.sonar.server.user.UserSession;
+import org.sonar.server.usergroups.DefaultGroupCreator;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 public class EnableSupportAction implements OrganizationsWsAction {
@@ -46,13 +45,15 @@ public class EnableSupportAction implements OrganizationsWsAction {
   private final DbClient dbClient;
   private final DefaultOrganizationProvider defaultOrganizationProvider;
   private final OrganizationFlags organizationFlags;
+  private final DefaultGroupCreator defaultGroupCreator;
 
   public EnableSupportAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider,
-    OrganizationFlags organizationFlags) {
+    OrganizationFlags organizationFlags, DefaultGroupCreator defaultGroupCreator) {
     this.userSession = userSession;
     this.dbClient = dbClient;
     this.defaultOrganizationProvider = defaultOrganizationProvider;
     this.organizationFlags = organizationFlags;
+    this.defaultGroupCreator = defaultGroupCreator;
   }
 
   @Override
@@ -96,20 +97,12 @@ public class EnableSupportAction implements OrganizationsWsAction {
 
   private void createDefaultMembersGroup(DbSession dbSession) {
     String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
-    String membersGroupName = "Members";
-    Optional<GroupDto> existingMembersGroup = dbClient.groupDao().selectByName(dbSession, defaultOrganizationUuid, membersGroupName);
-    checkArgument(!existingMembersGroup.isPresent(), "The group '%s' already exist", membersGroupName);
-    GroupDto members = new GroupDto()
-      .setName(membersGroupName)
-      .setDescription("All members of the organization")
-      .setOrganizationUuid(defaultOrganizationUuid);
-    dbClient.groupDao().insert(dbSession, members);
     int sonarUsersGroupId = dbClient.organizationDao().getDefaultGroupId(dbSession, defaultOrganizationUuid)
       .orElseThrow(() -> new IllegalStateException(String.format("Default group doesn't exist on default organization '%s'", defaultOrganizationProvider.get().getKey())));
+    GroupDto members = defaultGroupCreator.create(dbSession, defaultOrganizationUuid);
     copySonarUsersGroupPermissionsToMembersGroup(dbSession, sonarUsersGroupId, members);
     copySonarUsersGroupPermissionTemplatesToMembersGroup(dbSession, sonarUsersGroupId, members);
     associateMembersOfDefaultOrganizationToGroup(dbSession, members);
-    dbClient.organizationDao().setDefaultGroupId(dbSession, defaultOrganizationUuid, members);
   }
 
   private void associateMembersOfDefaultOrganizationToGroup(DbSession dbSession, GroupDto membersGroup) {
index b837d3c75d5c2b3ac2db221719795dbe56f37229..5b48802e51ea1513654016c0b574a5a12afd7349 100644 (file)
@@ -206,6 +206,7 @@ import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexDefinition;
 import org.sonar.server.user.index.UserIndexer;
 import org.sonar.server.user.ws.UsersWsModule;
+import org.sonar.server.usergroups.DefaultGroupCreatorImpl;
 import org.sonar.server.usergroups.ws.UserGroupsModule;
 import org.sonar.server.usertoken.UserTokenModule;
 import org.sonar.server.util.TypeValidationModule;
@@ -352,6 +353,7 @@ public class PlatformLevel4 extends PlatformLevel {
 
       // groups
       UserGroupsModule.class,
+      DefaultGroupCreatorImpl.class,
 
       // permissions
       DefaultTemplatesResolverImpl.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/DefaultGroupCreator.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/DefaultGroupCreator.java
new file mode 100644 (file)
index 0000000..5ac5022
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.usergroups;
+
+import org.sonar.db.DbSession;
+import org.sonar.db.user.GroupDto;
+
+public interface DefaultGroupCreator {
+
+  /**
+   * Create the default group on the given organization
+   */
+  GroupDto create(DbSession dbSession, String organizationUuid);
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/DefaultGroupCreatorImpl.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/DefaultGroupCreatorImpl.java
new file mode 100644 (file)
index 0000000..6b10d60
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.usergroups;
+
+import java.util.Optional;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.user.GroupDto;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class DefaultGroupCreatorImpl implements DefaultGroupCreator {
+
+  static final String DEFAULT_GROUP_NAME = "Members";
+  private final DbClient dbClient;
+
+  public DefaultGroupCreatorImpl(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  public GroupDto create(DbSession dbSession, String organizationUuid) {
+    Optional<GroupDto> existingMembersGroup = dbClient.groupDao().selectByName(dbSession, organizationUuid, DEFAULT_GROUP_NAME);
+    checkArgument(!existingMembersGroup.isPresent(), "The group '%s' already exist on organization '%s'", DEFAULT_GROUP_NAME, organizationUuid);
+
+    GroupDto defaultGroup = new GroupDto()
+      .setName(DEFAULT_GROUP_NAME)
+      .setDescription("All members of the organization")
+      .setOrganizationUuid(organizationUuid);
+    dbClient.groupDao().insert(dbSession, defaultGroup);
+    dbClient.organizationDao().setDefaultGroupId(dbSession, organizationUuid, defaultGroup);
+    return defaultGroup;
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/package-info.java
new file mode 100644 (file)
index 0000000..f37cd95
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.usergroups;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index 5b865fb2207ad73318ca4a8b8a336d6beff703cc..f2af9f33a45eb9c3a5203ccff319abe5bfee8183 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.organization;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -58,6 +59,8 @@ import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexDefinition;
 import org.sonar.server.user.index.UserIndexer;
 import org.sonar.server.user.index.UserQuery;
+import org.sonar.server.usergroups.DefaultGroupCreator;
+import org.sonar.server.usergroups.DefaultGroupCreatorImpl;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
@@ -75,8 +78,6 @@ public class OrganizationCreationImplTest {
   private static final String SLUG_OF_A_LOGIN = "slug-of-a-login";
   private static final String STRING_64_CHARS = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
   private static final String A_NAME = "a name";
-  private static final int ANYONE_GROUP_ID = 0;
-
 
   private OrganizationCreation.NewOrganization FULL_POPULATED_NEW_ORGANIZATION = newOrganizationBuilder()
     .setName("a-name")
@@ -109,9 +110,10 @@ public class OrganizationCreationImplTest {
   private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
   private UserIndex userIndex = new UserIndex(es.client());
   private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class);
+  private DefaultGroupCreator defaultGroupCreator = new DefaultGroupCreatorImpl(dbClient);
 
   private OrganizationCreationImpl underTest = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation, settings, userIndexer,
-    definedQProfileRepositoryRule, definedQProfileCreationRule, activeRuleIndexer);
+    definedQProfileRepositoryRule, definedQProfileCreationRule, defaultGroupCreator, activeRuleIndexer);
 
   private UserDto someUser;
 
@@ -218,6 +220,17 @@ public class OrganizationCreationImplTest {
     verifyGroupOwners(user, FULL_POPULATED_NEW_ORGANIZATION.getKey(), FULL_POPULATED_NEW_ORGANIZATION.getName());
   }
 
+  @Test
+  public void create_creates_members_group_and_add_current_user_to_it() throws OrganizationCreation.KeyConflictException {
+    UserDto user = dbTester.users().insertUser();
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    definedQProfileRepositoryRule.initialize();
+
+    underTest.create(dbSession, user, FULL_POPULATED_NEW_ORGANIZATION);
+
+    verifyMembersGroup(user, FULL_POPULATED_NEW_ORGANIZATION.getKey());
+  }
+
   @Test
   public void create_does_not_require_description_url_and_avatar_to_be_non_null() throws OrganizationCreation.KeyConflictException {
     mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
@@ -247,6 +260,7 @@ public class OrganizationCreationImplTest {
 
     OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, FULL_POPULATED_NEW_ORGANIZATION.getKey()).get();
     GroupDto ownersGroup = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Owners").get();
+    int defaultGroupId = dbClient.organizationDao().getDefaultGroupId(dbSession, organization.getUuid()).get();
     PermissionTemplateDto defaultTemplate = dbClient.permissionTemplateDao().selectByName(dbSession, organization.getUuid(), "default template");
     assertThat(defaultTemplate.getName()).isEqualTo("Default template");
     assertThat(defaultTemplate.getDescription()).isEqualTo("Default permission template of organization " + FULL_POPULATED_NEW_ORGANIZATION.getName());
@@ -257,7 +271,7 @@ public class OrganizationCreationImplTest {
       .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getPermission)
       .containsOnly(
         tuple(ownersGroup.getId(), UserRole.ADMIN), tuple(ownersGroup.getId(), UserRole.ISSUE_ADMIN), tuple(ownersGroup.getId(), GlobalPermissions.SCAN_EXECUTION),
-        tuple(ANYONE_GROUP_ID, UserRole.USER), tuple(ANYONE_GROUP_ID, UserRole.CODEVIEWER));
+        tuple(defaultGroupId, UserRole.USER), tuple(defaultGroupId, UserRole.CODEVIEWER));
   }
 
   @Test
@@ -388,7 +402,7 @@ public class OrganizationCreationImplTest {
   }
 
   @Test
-  public void createForUser_does_not_create_any_group() throws OrganizationCreation.KeyConflictException {
+  public void createForUser_creates_members_group_and_add_current_user_to_it() throws OrganizationCreation.KeyConflictException {
     UserDto user = dbTester.users().insertUser(dto -> dto.setLogin(A_LOGIN).setName(A_NAME));
     when(organizationValidation.generateKeyFrom(A_LOGIN)).thenReturn(SLUG_OF_A_LOGIN);
     mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
@@ -397,29 +411,7 @@ public class OrganizationCreationImplTest {
 
     underTest.createForUser(dbSession, user);
 
-    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, SLUG_OF_A_LOGIN).get();
-    assertThat(dbClient.groupDao().selectByOrganizationUuid(dbSession, organization.getUuid())).isEmpty();
-  }
-
-  private void verifyGroupOwners(UserDto user, String organizationKey, String organizationName) {
-    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, organizationKey).get();
-    List<GroupDto> groups = dbClient.groupDao().selectByOrganizationUuid(dbSession, organization.getUuid());
-    assertThat(groups)
-      .extracting(GroupDto::getName)
-      .containsOnly("Owners");
-    GroupDto groupDto = groups.iterator().next();
-    assertThat(groupDto.getDescription()).isEqualTo("Owners of organization " + organizationName);
-    assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId()))
-      .containsOnly(GlobalPermissions.ALL.toArray(new String[GlobalPermissions.ALL.size()]));
-    List<UserMembershipDto> members = dbClient.groupMembershipDao().selectMembers(
-      dbSession,
-      UserMembershipQuery.builder()
-        .organizationUuid(organization.getUuid())
-        .groupId(groupDto.getId())
-        .membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
-    assertThat(members)
-      .extracting(UserMembershipDto::getLogin)
-      .containsOnly(user.getLogin());
+    verifyMembersGroup(user, SLUG_OF_A_LOGIN);
   }
 
   @Test
@@ -433,6 +425,7 @@ public class OrganizationCreationImplTest {
     underTest.createForUser(dbSession, user);
 
     OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, SLUG_OF_A_LOGIN).get();
+    int defaultGroupId = dbClient.organizationDao().getDefaultGroupId(dbSession, organization.getUuid()).get();
     PermissionTemplateDto defaultTemplate = dbClient.permissionTemplateDao().selectByName(dbSession, organization.getUuid(), "default template");
     assertThat(defaultTemplate.getName()).isEqualTo("Default template");
     assertThat(defaultTemplate.getDescription()).isEqualTo("Default permission template of organization " + A_NAME);
@@ -441,7 +434,7 @@ public class OrganizationCreationImplTest {
     assertThat(defaultTemplates.getViewUuid()).isNull();
     assertThat(dbClient.permissionTemplateDao().selectGroupPermissionsByTemplateId(dbSession, defaultTemplate.getId()))
       .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getPermission)
-      .containsOnly(tuple(ANYONE_GROUP_ID, UserRole.USER), tuple(ANYONE_GROUP_ID, UserRole.CODEVIEWER));
+      .containsOnly(tuple(defaultGroupId, UserRole.USER), tuple(defaultGroupId, UserRole.CODEVIEWER));
     assertThat(dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(dbSession, Collections.singletonList(defaultTemplate.getId())))
       .extracting(PermissionTemplateCharacteristicDto::getWithProjectCreator, PermissionTemplateCharacteristicDto::getPermission)
       .containsOnly(
@@ -531,14 +524,14 @@ public class OrganizationCreationImplTest {
 
     OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, SLUG_OF_A_LOGIN).get();
     assertThat(definedQProfileCreationRule.getCallLogs())
-        .hasSize(4)
-        .extracting(DefinedQProfileCreationRule.CallLog::getOrganizationDto)
-        .extracting(OrganizationDto::getUuid)
-        .containsOnly(organization.getUuid());
+      .hasSize(4)
+      .extracting(DefinedQProfileCreationRule.CallLog::getOrganizationDto)
+      .extracting(OrganizationDto::getUuid)
+      .containsOnly(organization.getUuid());
     assertThat(definedQProfileCreationRule.getCallLogs())
-        .extracting(DefinedQProfileCreationRule.CallLog::getDefinedQProfile)
-        .extracting(DefinedQProfile::getName)
-        .containsExactly(definedQProfile1.getName(), definedQProfile2.getName(), definedQProfile3.getName(), definedQProfile4.getName());
+      .extracting(DefinedQProfileCreationRule.CallLog::getDefinedQProfile)
+      .extracting(DefinedQProfile::getName)
+      .containsExactly(definedQProfile1.getName(), definedQProfile2.getName(), definedQProfile3.getName(), definedQProfile4.getName());
     verify(activeRuleIndexer).index(Arrays.asList(changes[2], changes[1], changes[4], changes[3], changes[0]));
     verifyNoMoreInteractions(activeRuleIndexer);
   }
@@ -555,4 +548,46 @@ public class OrganizationCreationImplTest {
     when(uuidFactory.create()).thenReturn(orgUuid);
     when(system2.now()).thenReturn(orgDate);
   }
+
+  private void verifyGroupOwners(UserDto user, String organizationKey, String organizationName) {
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, organizationKey).get();
+    Optional<GroupDto> groupOpt = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Owners");
+    assertThat(groupOpt).isPresent();
+    GroupDto groupDto = groupOpt.get();
+    assertThat(groupDto.getDescription()).isEqualTo("Owners of organization " + organizationName);
+
+    assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId()))
+      .containsOnly(GlobalPermissions.ALL.toArray(new String[GlobalPermissions.ALL.size()]));
+    List<UserMembershipDto> members = dbClient.groupMembershipDao().selectMembers(
+      dbSession,
+      UserMembershipQuery.builder()
+        .organizationUuid(organization.getUuid())
+        .groupId(groupDto.getId())
+        .membership(UserMembershipQuery.IN).build(),
+      0, Integer.MAX_VALUE);
+    assertThat(members)
+      .extracting(UserMembershipDto::getLogin)
+      .containsOnly(user.getLogin());
+  }
+
+  private void verifyMembersGroup(UserDto user, String organizationKey) {
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, organizationKey).get();
+    Optional<GroupDto> groupOpt = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Members");
+    assertThat(groupOpt).isPresent();
+    GroupDto groupDto = groupOpt.get();
+    assertThat(groupDto.getDescription()).isEqualTo("All members of the organization");
+
+    assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId())).isEmpty();
+    List<UserMembershipDto> members = dbClient.groupMembershipDao().selectMembers(
+      dbSession,
+      UserMembershipQuery.builder()
+        .organizationUuid(organization.getUuid())
+        .groupId(groupDto.getId())
+        .membership(UserMembershipQuery.IN).build(),
+      0, Integer.MAX_VALUE);
+    assertThat(members)
+      .extracting(UserMembershipDto::getLogin)
+      .containsOnly(user.getLogin());
+  }
+
 }
index d7690f017faab445cecc92ef6688993aea0febca..f008fb6e8ae5f3e2e89c4ff42f190138c2cd8f06 100644 (file)
@@ -62,6 +62,7 @@ import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexDefinition;
 import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.usergroups.DefaultGroupCreatorImpl;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.MediaTypes;
@@ -101,7 +102,7 @@ public class CreateActionTest {
   private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
   private UserIndex userIndex = new UserIndex(es.client());
   private OrganizationCreation organizationCreation = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation, settings, userIndexer,
-      mock(DefinedQProfileRepository.class), mock(DefinedQProfileCreation.class), mock(ActiveRuleIndexer.class));
+    mock(DefinedQProfileRepository.class), mock(DefinedQProfileCreation.class), new DefaultGroupCreatorImpl(dbClient), mock(ActiveRuleIndexer.class));
   private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone().setEnabled(true);
 
   private UserDto user;
@@ -488,7 +489,35 @@ public class CreateActionTest {
       UserMembershipQuery.builder()
         .organizationUuid(organization.getUuid())
         .groupId(groupDto.getId())
-        .membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
+        .membership(UserMembershipQuery.IN).build(),
+      0, Integer.MAX_VALUE);
+    assertThat(members)
+      .extracting(UserMembershipDto::getLogin)
+      .containsOnly(user.getLogin());
+  }
+
+  @Test
+  public void request_creates_members_group_and_add_current_user_to_it() {
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    UserDto user = dbTester.users().insertUser();
+    userSession.logIn(user).setSystemAdministrator();
+
+    executeRequest("orgFoo");
+
+    DbSession dbSession = dbTester.getSession();
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, "orgfoo").get();
+    Optional<GroupDto> groupDtoOptional = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Members");
+    assertThat(groupDtoOptional).isNotEmpty();
+    GroupDto groupDto = groupDtoOptional.get();
+    assertThat(groupDto.getDescription()).isEqualTo("All members of the organization");
+    assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId())).isEmpty();
+    List<UserMembershipDto> members = dbClient.groupMembershipDao().selectMembers(
+      dbSession,
+      UserMembershipQuery.builder()
+        .organizationUuid(organization.getUuid())
+        .groupId(groupDto.getId())
+        .membership(UserMembershipQuery.IN).build(),
+      0, Integer.MAX_VALUE);
     assertThat(members)
       .extracting(UserMembershipDto::getLogin)
       .containsOnly(user.getLogin());
@@ -504,6 +533,7 @@ public class CreateActionTest {
 
     OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, "orgfoo").get();
     GroupDto ownersGroup = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Owners").get();
+    GroupDto defaultGroup = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Members").get();
     PermissionTemplateDto defaultTemplate = dbClient.permissionTemplateDao().selectByName(dbSession, organization.getUuid(), "default template");
     assertThat(defaultTemplate.getName()).isEqualTo("Default template");
     assertThat(defaultTemplate.getDescription()).isEqualTo("Default permission template of organization orgFoo");
@@ -514,7 +544,7 @@ public class CreateActionTest {
       .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getPermission)
       .containsOnly(
         tuple(ownersGroup.getId(), UserRole.ADMIN), tuple(ownersGroup.getId(), UserRole.ISSUE_ADMIN), tuple(ownersGroup.getId(), GlobalPermissions.SCAN_EXECUTION),
-        tuple(0, UserRole.USER), tuple(0, UserRole.CODEVIEWER));
+        tuple(defaultGroup.getId(), UserRole.USER), tuple(defaultGroup.getId(), UserRole.CODEVIEWER));
   }
 
   @Test
index 38e85f3e46c6f45a4583bc7729092e28cf2ed323..074b6c22c471ddbc1d1f7c61e1885ecea72bd866 100644 (file)
@@ -42,6 +42,7 @@ import org.sonar.server.organization.OrganizationFlags;
 import org.sonar.server.organization.OrganizationFlagsImpl;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.usergroups.DefaultGroupCreatorImpl;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
 
@@ -60,7 +61,8 @@ public class EnableSupportActionTest {
 
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
   private OrganizationFlags organizationFlags = new OrganizationFlagsImpl(db.getDbClient());
-  private EnableSupportAction underTest = new EnableSupportAction(userSession, db.getDbClient(), defaultOrganizationProvider, organizationFlags);
+  private EnableSupportAction underTest = new EnableSupportAction(userSession, db.getDbClient(), defaultOrganizationProvider, organizationFlags,
+    new DefaultGroupCreatorImpl(db.getDbClient()));
   private WsActionTester tester = new WsActionTester(underTest);
 
   @Test
@@ -123,7 +125,8 @@ public class EnableSupportActionTest {
     int defaultGroupId = db.getDbClient().organizationDao().getDefaultGroupId(db.getSession(), defaultOrganization.getUuid()).get();
     assertThat(defaultGroupId).isNotEqualTo(sonarUsersGroup.getId());
     List<GroupPermissionDto> result = new ArrayList<>();
-    db.getDbClient().groupPermissionDao().selectAllPermissionsByGroupId(db.getSession(), defaultOrganization.getUuid(), defaultGroupId, context -> result.add((GroupPermissionDto) context.getResultObject()));
+    db.getDbClient().groupPermissionDao().selectAllPermissionsByGroupId(db.getSession(), defaultOrganization.getUuid(), defaultGroupId,
+      context -> result.add((GroupPermissionDto) context.getResultObject()));
     assertThat(result).extracting(GroupPermissionDto::getResourceId, GroupPermissionDto::getRole).containsOnly(
       tuple(null, "user"), tuple(project.getId(), "codeviewer"));
   }
@@ -152,6 +155,7 @@ public class EnableSupportActionTest {
   @Test
   public void throw_IAE_when_members_group_already_exists() throws Exception {
     UserDto user = db.users().insertUser();
+    db.users().insertDefaultGroup(db.getDefaultOrganization(), "sonar-users");
     db.users().insertGroup(db.getDefaultOrganization(), "Members");
     logInAsSystemAdministrator(user.getLogin());
 
@@ -161,7 +165,6 @@ public class EnableSupportActionTest {
     call();
   }
 
-
   @Test
   public void throw_UnauthorizedException_if_not_logged_in() {
     userSession.anonymous();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/DefaultGroupCreatorImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/DefaultGroupCreatorImplTest.java
new file mode 100644 (file)
index 0000000..3366cc5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.usergroups;
+
+import java.util.Optional;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.template.PermissionTemplateDto;
+import org.sonar.db.user.GroupDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DefaultGroupCreatorImplTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @Rule
+  public DbTester db = DbTester.create();
+
+  private DefaultGroupCreator underTest = new DefaultGroupCreatorImpl(db.getDbClient());
+
+  @Test
+  public void create_default_group() throws Exception {
+    OrganizationDto organizationDto = db.organizations().insert();
+
+    underTest.create(db.getSession(), organizationDto.getUuid());
+
+    Optional<Integer> defaultGroupId = db.getDbClient().organizationDao().getDefaultGroupId(db.getSession(), organizationDto.getUuid());
+    assertThat(defaultGroupId).isPresent();
+    assertThat(db.getDbClient().groupDao().selectById(db.getSession(), defaultGroupId.get()))
+      .extracting(GroupDto::getName, GroupDto::getDescription)
+      .containsOnly("Members", "All members of the organization");
+  }
+
+  @Test
+  public void fail_with_IAE_when_default_group_already_exist() throws Exception {
+    OrganizationDto organizationDto = db.organizations().insert();
+    PermissionTemplateDto permissionTemplate = db.permissionTemplates().insertTemplate();
+    db.organizations().setDefaultTemplates(organizationDto, permissionTemplate.getUuid(), null);
+    db.users().insertGroup(organizationDto, "Members");
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage(String.format("The group '%s' already exist on organization '%s'", "Members", organizationDto.getUuid()));
+
+    underTest.create(db.getSession(), organizationDto.getUuid());
+  }
+
+}