Browse Source

SONARCLOUD-213 clarify "scan" in org vs project permissions

tags/7.5
Simon Brandhof 5 years ago
parent
commit
cf489b9db9

+ 7
- 8
server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java View File

@@ -44,7 +44,6 @@ import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
@@ -767,21 +766,21 @@ public class AuthorizationDaoTest {
public void selectOrganizationUuidsOfUserWithGlobalPermission_returns_empty_set_if_user_does_not_have_permission_at_all() {
db.users().insertPermissionOnUser(user, ADMINISTER_QUALITY_GATES);
// user is not part of this group
db.users().insertPermissionOnGroup(group1, SCAN_EXECUTION);
db.users().insertPermissionOnGroup(group1, SCAN);

Set<String> orgUuids = underTest.selectOrganizationUuidsOfUserWithGlobalPermission(dbSession, user.getId(), SCAN_EXECUTION);
Set<String> orgUuids = underTest.selectOrganizationUuidsOfUserWithGlobalPermission(dbSession, user.getId(), SCAN.getKey());

assertThat(orgUuids).isEmpty();
}

@Test
public void selectOrganizationUuidsOfUserWithGlobalPermission_returns_organizations_on_which_user_has_permission() {
db.users().insertPermissionOnGroup(group1, SCAN_EXECUTION);
db.users().insertPermissionOnGroup(group1, SCAN);
db.users().insertPermissionOnGroup(group2, QUALITY_GATE_ADMIN);
db.users().insertMember(group1, user);
db.users().insertMember(group2, user);

Set<String> orgUuids = underTest.selectOrganizationUuidsOfUserWithGlobalPermission(dbSession, user.getId(), SCAN_EXECUTION);
Set<String> orgUuids = underTest.selectOrganizationUuidsOfUserWithGlobalPermission(dbSession, user.getId(), SCAN.getKey());

assertThat(orgUuids).containsExactly(group1.getOrganizationUuid());
}
@@ -789,12 +788,12 @@ public class AuthorizationDaoTest {
@Test
public void selectOrganizationUuidsOfUserWithGlobalPermission_handles_user_permissions_and_group_permissions() {
// organization: through group membership
db.users().insertPermissionOnGroup(group1, SCAN_EXECUTION);
db.users().insertPermissionOnGroup(group1, SCAN);
db.users().insertMember(group1, user);

// org2 : direct user permission
OrganizationDto org2 = db.organizations().insert();
db.users().insertPermissionOnUser(org2, user, SCAN_EXECUTION);
db.users().insertPermissionOnUser(org2, user, SCAN);

// org3 : another permission QUALITY_GATE_ADMIN
OrganizationDto org3 = db.organizations().insert();
@@ -803,7 +802,7 @@ public class AuthorizationDaoTest {
// exclude project permission
db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, db.components().insertPrivateProject());

Set<String> orgUuids = underTest.selectOrganizationUuidsOfUserWithGlobalPermission(dbSession, user.getId(), SCAN_EXECUTION);
Set<String> orgUuids = underTest.selectOrganizationUuidsOfUserWithGlobalPermission(dbSession, user.getId(), SCAN.getKey());

assertThat(orgUuids).containsOnly(organization.getUuid(), org2.getUuid());
}

+ 7
- 9
server/sonar-db-dao/src/test/java/org/sonar/db/permission/GroupPermissionDaoTest.java View File

@@ -47,9 +47,7 @@ import static org.sonar.api.security.DefaultGroups.ANYONE;
import static org.sonar.api.web.UserRole.ADMIN;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
import static org.sonar.db.permission.OrganizationPermission.SCAN;
@@ -220,11 +218,11 @@ public class GroupPermissionDaoTest {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto anotherProject = db.components().insertPrivateProject();

db.users().insertProjectPermissionOnGroup(group1, SCAN_EXECUTION, project);
db.users().insertProjectPermissionOnGroup(group1, PROVISIONING, project);
db.users().insertProjectPermissionOnGroup(group1, SCAN.getKey(), project);
db.users().insertProjectPermissionOnGroup(group1, PROVISION_PROJECTS.getKey(), project);

db.users().insertProjectPermissionOnGroup(group1, SYSTEM_ADMIN, anotherProject);
db.users().insertProjectPermissionOnGroup(group3, SCAN_EXECUTION, anotherProject);
db.users().insertProjectPermissionOnGroup(group1, ADMIN, anotherProject);
db.users().insertProjectPermissionOnGroup(group3, UserRole.SCAN, anotherProject);
db.users().insertPermissionOnGroup(group2, SCAN);

PermissionQuery.Builder builderOnComponent = newQuery().setComponentUuid(project.uuid());
@@ -291,13 +289,13 @@ public class GroupPermissionDaoTest {

assertThat(underTest.selectByGroupIds(dbSession, organizationDto.getUuid(), asList(group3.getId()), null))
.extracting(GroupPermissionDto::getGroupId, GroupPermissionDto::getRole, GroupPermissionDto::getResourceId)
.containsOnly(tuple(group3.getId(), SYSTEM_ADMIN, null));
.containsOnly(tuple(group3.getId(), ADMINISTER.getKey(), null));

assertThat(underTest.selectByGroupIds(dbSession, organizationDto.getUuid(), asList(ANYONE_ID), null))
.extracting(GroupPermissionDto::getGroupId, GroupPermissionDto::getRole, GroupPermissionDto::getResourceId)
.containsOnly(
tuple(0, SCAN_EXECUTION, null),
tuple(0, PROVISIONING, null));
tuple(0, SCAN.getKey(), null),
tuple(0, PROVISION_PROJECTS.getKey(), null));

assertThat(underTest.selectByGroupIds(dbSession, organizationDto.getUuid(), asList(group1.getId(), group2.getId(), ANYONE_ID), null)).hasSize(3);
assertThat(underTest.selectByGroupIds(dbSession, organizationDto.getUuid(), asList(MISSING_ID), null)).isEmpty();

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java View File

@@ -32,6 +32,7 @@ import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -48,7 +49,6 @@ import org.sonar.server.user.UserSession;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.util.stream.MoreCollectors.index;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.server.ws.WsUtils.checkRequest;
@@ -74,7 +74,7 @@ public class ProjectDataLoader {
String pullRequest = query.getPullRequest();
ComponentDto mainModule = componentFinder.getByKey(session, moduleKey);
checkRequest(isProjectOrModule(mainModule), "Key '%s' belongs to a component which is not a Project", moduleKey);
boolean hasScanPerm = userSession.hasComponentPermission(SCAN_EXECUTION, mainModule) ||
boolean hasScanPerm = userSession.hasComponentPermission(UserRole.SCAN, mainModule) ||
userSession.hasPermission(OrganizationPermission.SCAN, mainModule.getOrganizationUuid());
boolean hasBrowsePerm = userSession.hasComponentPermission(USER, mainModule);
checkPermission(query.isIssuesMode(), hasScanPerm, hasBrowsePerm);

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/branch/pr/ws/ListAction.java View File

@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.BranchDto;
@@ -50,7 +51,6 @@ import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
@@ -125,7 +125,7 @@ public class ListAction implements PullRequestWsAction {

private void checkPermission(ComponentDto component) {
if (userSession.hasComponentPermission(USER, component) ||
userSession.hasComponentPermission(SCAN_EXECUTION, component) ||
userSession.hasComponentPermission(UserRole.SCAN, component) ||
userSession.hasPermission(OrganizationPermission.SCAN, component.getOrganizationUuid())) {
return;
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/branch/ws/ListAction.java View File

@@ -33,6 +33,7 @@ import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.BranchDto;
@@ -55,7 +56,6 @@ import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
@@ -175,7 +175,7 @@ public class ListAction implements BranchWsAction {

private void checkPermission(ComponentDto component) {
if (!userSession.hasComponentPermission(USER, component) &&
!userSession.hasComponentPermission(SCAN_EXECUTION, component) &&
!userSession.hasComponentPermission(UserRole.SCAN, component) &&
!userSession.hasPermission(SCAN, component.getOrganizationUuid())) {
throw insufficientPrivilegesException();
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java View File

@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.ce.queue.CeQueue;
import org.sonar.ce.queue.CeTaskSubmit;
import org.sonar.ce.task.CeTask;
@@ -48,7 +49,6 @@ import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.defaultIfBlank;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.server.component.NewComponent.newComponentBuilder;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;

@@ -96,7 +96,7 @@ public class ReportSubmitter {
// they don't have the direct permission on the project.
// That means that dropping the permission on the project does not have any effects
// if user has still the permission on the organization
if (!userSession.hasComponentPermission(SCAN_EXECUTION, project) &&
if (!userSession.hasComponentPermission(UserRole.SCAN, project) &&
!userSession.hasPermission(OrganizationPermission.SCAN, project.getOrganizationUuid())) {
throw insufficientPrivilegesException();
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java View File

@@ -32,6 +32,7 @@ import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import org.sonar.core.util.Uuids;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
@@ -45,7 +46,6 @@ import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.Ce;

import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
import static org.sonar.server.ws.WsUtils.writeProtobuf;

@@ -126,7 +126,7 @@ public class TaskAction implements CeWsAction {
String orgUuid = component.get().getOrganizationUuid();
if (!userSession.hasPermission(OrganizationPermission.ADMINISTER, orgUuid) &&
!userSession.hasPermission(OrganizationPermission.SCAN, orgUuid) &&
!userSession.hasComponentPermission(SCAN_EXECUTION, component.get())) {
!userSession.hasComponentPermission(UserRole.SCAN, component.get())) {
throw insufficientPrivilegesException();
}


+ 2
- 3
server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationUpdater.java View File

@@ -24,7 +24,6 @@ import java.util.function.Consumer;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
@@ -60,7 +59,7 @@ public interface OrganizationUpdater {
* <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 UserRole#SECURITYHOTSPOT_ADMIN SECURITYHOTSPOT_ADMIN}</li>
* <li>group {@link #OWNERS_GROUP_NAME Owners} : {@link GlobalPermissions#SCAN_EXECUTION SCAN_EXECUTION}</li>
* <li>group {@link #OWNERS_GROUP_NAME Owners} : {@link UserRole#SCAN SCAN}</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>
@@ -105,7 +104,7 @@ public interface OrganizationUpdater {
* <li>project creator : {@link UserRole#ADMIN ADMIN}</li>
* <li>project creator : {@link UserRole#ISSUE_ADMIN ISSUE_ADMIN}</li>
* <li>project creator : {@link UserRole#SECURITYHOTSPOT_ADMIN SECURITYHOTSPOT_ADMIN}</li>
* <li>project creator : {@link GlobalPermissions#SCAN_EXECUTION SCAN_EXECUTION}</li>
* <li>project creator : {@link UserRole#SCAN SCAN}</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>

+ 1
- 2
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionServiceImpl.java View File

@@ -26,7 +26,6 @@ import javax.annotation.concurrent.Immutable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.permission.OrganizationPermission;

import static java.util.stream.Collectors.toList;
@@ -35,7 +34,7 @@ import static java.util.stream.Collectors.toList;
public class PermissionServiceImpl implements PermissionService {

private static final List<String> ALL_PROJECT_PERMISSIONS = ImmutableList.of(
UserRole.ADMIN, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermissions.SCAN_EXECUTION, UserRole.USER);
UserRole.ADMIN, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, UserRole.SCAN, UserRole.USER);

private static final List<OrganizationPermission> ALL_GLOBAL_PERMISSIONS = ImmutableList.copyOf(OrganizationPermission.values());


+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java View File

@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.process.ProcessProperties;
@@ -36,7 +37,6 @@ import static java.lang.String.format;
import static java.util.Arrays.stream;
import static org.sonar.api.PropertyType.LICENSE;
import static org.sonar.api.web.UserRole.ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_PULL_REQUEST;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
@@ -70,7 +70,7 @@ public class SettingsWsSupport {
}

boolean isVisible(String key, @Nullable PropertyDefinition definition, Optional<ComponentDto> component) {
return hasPermission(OrganizationPermission.SCAN, SCAN_EXECUTION, component) || (verifySecuredSetting(key, definition, component) && (verifyLicenseSetting(key, definition)));
return hasPermission(OrganizationPermission.SCAN, UserRole.SCAN, component) || (verifySecuredSetting(key, definition, component) && (verifyLicenseSetting(key, definition)));
}

static boolean isSecured(String key) {

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java View File

@@ -42,6 +42,7 @@ import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -60,7 +61,6 @@ import static org.sonar.api.CoreProperties.SERVER_ID;
import static org.sonar.api.CoreProperties.SERVER_STARTTIME;
import static org.sonar.api.PropertyType.PROPERTY_SET;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
import static org.sonar.server.setting.ws.PropertySetExtractor.extractPropertySetKeys;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH;
@@ -160,7 +160,7 @@ public class ValuesAction implements SettingsWsAction {
}
ComponentDto component = componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, valuesRequest.getBranch(), valuesRequest.getPullRequest());
if (!userSession.hasComponentPermission(USER, component) &&
!userSession.hasComponentPermission(SCAN_EXECUTION, component) &&
!userSession.hasComponentPermission(UserRole.SCAN, component) &&
!userSession.hasPermission(OrganizationPermission.SCAN, component.getOrganizationUuid())) {
throw insufficientPrivilegesException();
}

+ 6
- 0
sonar-plugin-api/src/main/java/org/sonar/api/web/UserRole.java View File

@@ -51,10 +51,16 @@ public @interface UserRole {
*/
String SECURITYHOTSPOT_ADMIN = "securityhotspotadmin";

/**
* @since 7.5
*/
String SCAN = "scan";

String[] value() default {};

/**
* Permissions which are implicitly available for any user, any group and to group "AnyOne" on public components.
* @since 7.5
*/
Set<String> PUBLIC_PERMISSIONS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(UserRole.USER, UserRole.CODEVIEWER)));


Loading…
Cancel
Save