From: Sébastien Lesaint Date: Wed, 19 Oct 2016 08:38:40 +0000 (+0200) Subject: SONAR-8152 make current user "owner" in api/organizations/create X-Git-Tag: 6.2-RC1~317 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F1319%2Fhead;p=sonarqube.git SONAR-8152 make current user "owner" in api/organizations/create by creating a group "Owners" with all global permissions and make current user a member of this group --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/CreateAction.java index c08e4f2be83..f7d81eaf234 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/CreateAction.java @@ -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); diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java index d29369ad2ee..be8eb8c27f5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java @@ -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.
" + - "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 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 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(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java b/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java index df409a00c58..5439d941065 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java +++ b/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java @@ -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 { 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; diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java b/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java index 8370eee7591..bda0e4395cb 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java @@ -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 */