]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8152 make current user "owner" in api/organizations/create 1319/head
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 19 Oct 2016 08:38:40 +0000 (10:38 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 20 Oct 2016 15:18:44 +0000 (17:18 +0200)
by creating a group "Owners" with all global permissions and make current user a member of this group

server/sonar-server/src/main/java/org/sonar/server/organization/ws/CreateAction.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java
server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java

index c08e4f2be834be977cf88fb5907cdac1abffaf17..f7d81eaf234a701621bc5ab59c1015c141e8fa3a 100644 (file)
@@ -26,15 +26,20 @@ import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 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;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.GroupPermissionDto;
+import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.UserGroupDto;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Organizations.CreateWsResponse;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.Math.min;
+import static java.lang.String.format;
 import static org.sonar.core.util.Slug.slugify;
 import static org.sonar.server.organization.ws.OrganizationsWsSupport.KEY_MAX_LENGTH;
 import static org.sonar.server.organization.ws.OrganizationsWsSupport.KEY_MIN_LENGTH;
@@ -46,6 +51,8 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class CreateAction implements OrganizationsAction {
   private static final String ACTION = "create";
+  private static final String OWNERS_GROUP_NAME = "Owners";
+  private static final String OWNERS_GROUP_DESCRIPTION_PATTERN = "Owners of organization %s";
 
   private final Settings settings;
   private final UserSession userSession;
@@ -103,12 +110,41 @@ public class CreateAction implements OrganizationsAction {
 
       OrganizationDto dto = createOrganizationDto(request, name, key);
       dbClient.organizationDao().insert(dbSession, dto);
+      GroupDto group = createOwnersGroup(dbSession, dto);
+      addCurrentUserToGroup(dbSession, group);
       dbSession.commit();
 
       writeResponse(request, response, dto);
     }
   }
 
+  /**
+   * Owners group has an hard coded name, a description based on the organization's name and has all global permissions.
+   */
+  private GroupDto createOwnersGroup(DbSession dbSession, OrganizationDto organization) {
+    GroupDto group = dbClient.groupDao().insert(dbSession, new GroupDto()
+      .setOrganizationUuid(organization.getUuid())
+      .setName(OWNERS_GROUP_NAME)
+      .setDescription(format(OWNERS_GROUP_DESCRIPTION_PATTERN, organization.getName())));
+    GlobalPermissions.ALL.forEach(permission -> addPermissionToGroup(dbSession, group, permission));
+    return group;
+  }
+
+  private void addPermissionToGroup(DbSession dbSession, GroupDto group, String permission) {
+    dbClient.groupPermissionDao().insert(
+      dbSession,
+      new GroupPermissionDto()
+        .setOrganizationUuid(group.getOrganizationUuid())
+        .setGroupId(group.getId())
+        .setRole(permission));
+  }
+
+  private void addCurrentUserToGroup(DbSession dbSession, GroupDto group) {
+    dbClient.userGroupDao().insert(
+      dbSession,
+      new UserGroupDto().setGroupId(group.getId()).setUserId(userSession.getUserId().longValue()));
+  }
+
   @CheckForNull
   private static String getAndCheckKey(Request request) {
     String rqstKey = request.param(PARAM_KEY);
index d29369ad2ee004fd77eaec60de832d9c5b107a27..be8eb8c27f5a437f9e133ca7c774ff10b1903245 100644 (file)
@@ -21,6 +21,8 @@ package org.sonar.server.organization.ws;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Optional;
 import javax.annotation.Nullable;
 import org.apache.commons.io.IOUtils;
 import org.junit.Rule;
@@ -30,10 +32,16 @@ import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
+import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.core.util.Uuids;
+import org.sonar.db.DbSession;
 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.db.user.UserMembershipDto;
+import org.sonar.db.user.UserMembershipQuery;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.UserSessionRule;
@@ -76,7 +84,7 @@ public class CreateActionTest {
     assertThat(action.key()).isEqualTo("create");
     assertThat(action.isPost()).isTrue();
     assertThat(action.description()).isEqualTo("Create an organization.<br />" +
-        "Requires 'Administer System' permission unless any logged in user is allowed to create an organization (see appropriate setting).");
+      "Requires 'Administer System' permission unless any logged in user is allowed to create an organization (see appropriate setting).");
     assertThat(action.isInternal()).isTrue();
     assertThat(action.since()).isEqualTo("6.2");
     assertThat(action.handler()).isEqualTo(underTest);
@@ -417,6 +425,30 @@ public class CreateActionTest {
     verifyResponseAndDb(response, SOME_UUID, "foo", "bar", null, null, avatar, SOME_DATE);
   }
 
+  @Test
+  public void request_creates_owners_group_with_all_permissions_for_new_organization_and_add_current_user_to_it() {
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    UserDto user = dbTester.users().makeRoot(dbTester.users().insertUser());
+    userSession.login(user).setRoot();
+
+    executeRequest("orgFoo");
+
+    DbSession dbSession = dbTester.getSession();
+    OrganizationDto organization = dbTester.getDbClient().organizationDao().selectByKey(dbSession, "orgfoo").get();
+    Optional<GroupDto> groupDtoOptional = dbTester.getDbClient().groupDao().selectByName(dbSession, organization.getUuid(), "Owners");
+    assertThat(groupDtoOptional).isNotEmpty();
+    GroupDto groupDto = groupDtoOptional.get();
+    assertThat(groupDto.getDescription()).isEqualTo("Owners of organization orgFoo");
+    assertThat(dbTester.getDbClient().groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId()))
+      .containsOnly(GlobalPermissions.ALL.toArray(new String[GlobalPermissions.ALL.size()]));
+    List<UserMembershipDto> members = dbTester.getDbClient().groupMembershipDao().selectMembers(
+      dbSession,
+      UserMembershipQuery.builder().groupId(groupDto.getId()).membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
+    assertThat(members)
+      .extracting(UserMembershipDto::getLogin)
+      .containsOnly(user.getLogin());
+  }
+
   private void makeUserRoot() {
     userSession.login().setRoot();
   }
index df409a00c58cbd4a96278757435f98b137c0b306..5439d9410652058f5824640d67fa993cd81d8cf6 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.tester;
 
 import java.util.Objects;
+import org.sonar.db.user.UserDto;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
@@ -37,6 +38,14 @@ public class MockUserSession extends AbstractMockUserSession<MockUserSession> {
     setName(login + " name");
   }
 
+  public MockUserSession(UserDto userDto) {
+    super(MockUserSession.class);
+    checkArgument(!userDto.getLogin().isEmpty());
+    this.login = userDto.getLogin();
+    setUserId(userDto.getId().intValue());
+    setName(userDto.getName());
+  }
+
   @Override
   public boolean isLoggedIn() {
     return true;
index 8370eee75911593d1112d3b93786c3177fd39b8c..bda0e4395cb836157dff1489cfd6880c90f42f31 100644 (file)
@@ -29,6 +29,7 @@ import javax.annotation.Nullable;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
+import org.sonar.db.user.UserDto;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSession;
 
@@ -112,6 +113,14 @@ public class UserSessionRule implements TestRule, UserSession {
     return this;
   }
 
+  /**
+   * Log in with the specified login
+   */
+  public UserSessionRule login(UserDto userDto) {
+    setCurrentUserSession(new MockUserSession(userDto));
+    return this;
+  }
+
   /**
    * Disconnect/go anonymous
    */