Browse Source

SONAR-20082 Set public permissions on managed projects at creation

tags/10.2.0.77647
Antoine Vigneau 10 months ago
parent
commit
e1cf911008

+ 3
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectActionIT.java View File

@@ -51,7 +51,9 @@ import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -93,7 +95,7 @@ public class ImportAzureProjectActionIT {

private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
defaultBranchNameResolver);
defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));

private final Encryption encryption = mock(Encryption.class);
private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);

+ 3
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketcloud/ImportBitbucketCloudRepoActionIT.java View File

@@ -51,7 +51,9 @@ import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -93,7 +95,7 @@ public class ImportBitbucketCloudRepoActionIT {
DefaultBranchNameResolver defaultBranchNameResolver = mock(DefaultBranchNameResolver.class);
private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
defaultBranchNameResolver);
defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));

private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);

+ 3
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketserver/ImportBitbucketServerProjectActionIT.java View File

@@ -55,7 +55,9 @@ import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -100,7 +102,7 @@ public class ImportBitbucketServerProjectActionIT {

private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
defaultBranchNameResolver);
defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));

private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);

+ 20
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java View File

@@ -20,12 +20,14 @@
package org.sonar.server.almintegration.ws.github;

import java.util.Optional;
import java.util.Set;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.alm.client.github.GithubApplicationClient;
import org.sonar.alm.client.github.GithubApplicationClientImpl;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
import org.sonar.auth.github.GitHubSettings;
@@ -37,6 +39,7 @@ import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.permission.GlobalPermission;
@@ -45,12 +48,22 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.IndexersImpl;
import org.sonar.server.es.TestIndexers;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.GroupPermissionChanger;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionServiceImpl;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.permission.UserPermissionChanger;
import org.sonar.server.permission.index.FooIndexDefinition;
import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -92,9 +105,15 @@ public class ImportGithubProjectActionIT {
@Rule
public DbTester db = DbTester.create(system2);
private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
public EsTester es = EsTester.createCustom(new FooIndexDefinition());
private final PermissionUpdater<UserPermissionChange> userPermissionUpdater = new PermissionUpdater(
new IndexersImpl(new PermissionIndexer(db.getDbClient(), es.client())),
Set.of(new UserPermissionChanger(db.getDbClient(), new SequenceUuidFactory()),
new GroupPermissionChanger(db.getDbClient(), new SequenceUuidFactory())));
private final PermissionService permissionService = new PermissionServiceImpl(new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT));
private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
permissionTemplateService, new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
defaultBranchNameResolver);
defaultBranchNameResolver, userPermissionUpdater, permissionService);

private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);

+ 3
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/gitlab/ImportGitLabProjectActionIT.java View File

@@ -44,7 +44,9 @@ import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.es.TestIndexers;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -84,7 +86,7 @@ public class ImportGitLabProjectActionIT {

private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
defaultBranchNameResolver);
defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));

private final GitlabHttpClient gitlabHttpClient = mock(GitlabHttpClient.class);
private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);

+ 4
- 2
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java View File

@@ -38,8 +38,8 @@ import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.component.ProjectData;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
@@ -48,7 +48,9 @@ import org.sonar.server.es.TestIndexers;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -93,7 +95,7 @@ public class ReportSubmitterIT {
private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);

private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), mock(System2.class), permissionTemplateService,
new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver);
new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));
private final BranchSupport ossEditionBranchSupport = new BranchSupport(null);

private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), ossEditionBranchSupport,

+ 45
- 7
server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentUpdaterIT.java View File

@@ -19,7 +19,9 @@
*/
package org.sonar.server.component;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Rule;
@@ -28,20 +30,32 @@ import org.sonar.api.config.Configuration;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.core.util.SequenceUuidFactory;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.Indexers;
import org.sonar.server.es.IndexersImpl;
import org.sonar.server.es.TestIndexers;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.permission.GroupPermissionChanger;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionServiceImpl;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.permission.UserPermissionChanger;
import org.sonar.server.permission.index.FooIndexDefinition;
import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.project.DefaultBranchNameResolver;

import static java.util.stream.IntStream.rangeClosed;
@@ -63,6 +77,8 @@ public class ComponentUpdaterIT {

private static final String DEFAULT_PROJECT_KEY = "project-key";
private static final String DEFAULT_PROJECT_NAME = "project-name";
private static final String DEFAULT_USER_UUID = "user-uuid";
public static final String DEFAULT_USER_LOGIN = "user-login";

private final System2 system2 = System2.INSTANCE;

@@ -74,13 +90,18 @@ public class ComponentUpdaterIT {
private final TestIndexers projectIndexers = new TestIndexers();
private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
private final DefaultBranchNameResolver defaultBranchNameResolver = mock(DefaultBranchNameResolver.class);

private final Configuration config = mock(Configuration.class);
public EsTester es = EsTester.createCustom(new FooIndexDefinition());
private final PermissionUpdater<UserPermissionChange> userPermissionUpdater = new PermissionUpdater(
new IndexersImpl(new PermissionIndexer(db.getDbClient(), es.client())),
Set.of(new UserPermissionChanger(db.getDbClient(), new SequenceUuidFactory()),
new GroupPermissionChanger(db.getDbClient(), new SequenceUuidFactory())));
private final PermissionService permissionService = new PermissionServiceImpl(new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT));

private final ComponentUpdater underTest = new ComponentUpdater(db.getDbClient(), i18n, system2,
permissionTemplateService,
new FavoriteUpdater(db.getDbClient()),
projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver);
projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, userPermissionUpdater, permissionService);

@Before
public void before() {
@@ -203,14 +224,13 @@ public class ComponentUpdaterIT {

@Test
public void apply_default_permission_template() {
String userUuid = "42";
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.build();
ProjectDto dto = underTest.create(db.getSession(), project, userUuid, "user-login").projectDto();
ProjectDto dto = underTest.create(db.getSession(), project, DEFAULT_USER_UUID, DEFAULT_USER_LOGIN).projectDto();

verify(permissionTemplateService).applyDefaultToNewComponent(db.getSession(), dto, userUuid);
verify(permissionTemplateService).applyDefaultToNewComponent(db.getSession(), dto, DEFAULT_USER_UUID);
}

@Test
@@ -392,13 +412,31 @@ public class ComponentUpdaterIT {

@Test
public void createWithoutCommit_whenProjectIsManaged_doesntApplyPermissionTemplate() {
String userUuid = "42";
UserDto userDto = db.users().insertUser();
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.build();
underTest.createWithoutCommit(db.getSession(), project, userUuid, "user-login", null, true);
underTest.createWithoutCommit(db.getSession(), project, userDto.getUuid(), userDto.getLogin(), null, true);

verify(permissionTemplateService, never()).applyDefaultToNewComponent(any(), any(), any());
}

@Test
public void createWithoutCommit_whenProjectIsManagedAndPrivate_applyPublicPermissionsToCreator() {
UserDto userDto = db.users().insertUser();
NewComponent newComponent = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(true)
.build();

DbSession session = db.getSession();
ComponentCreationData componentCreationData = underTest.createWithoutCommit(session, newComponent, userDto.getUuid(), userDto.getLogin(), null, true);

List<String> permissions = db.getDbClient().userPermissionDao().selectEntityPermissionsOfUser(session, userDto.getUuid(), componentCreationData.projectDto().getUuid());
assertThat(permissions)
.containsExactlyInAnyOrder(UserRole.USER, UserRole.CODEVIEWER);
}

}

+ 3
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/CreateActionIT.java View File

@@ -45,7 +45,9 @@ import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
@@ -107,7 +109,7 @@ public class CreateActionIT {
new CreateAction(
db.getDbClient(), userSession,
new ComponentUpdater(db.getDbClient(), i18n, system2, permissionTemplateService, new FavoriteUpdater(db.getDbClient()),
projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver),
projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class)),
projectDefaultVisibility, defaultBranchNameResolver, newCodeDefinitionResolver));

@Before

+ 31
- 5
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java View File

@@ -19,7 +19,6 @@
*/
package org.sonar.server.component;

import com.google.common.annotations.VisibleForTesting;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
@@ -39,13 +38,19 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.portfolio.PortfolioDto;
import org.sonar.db.portfolio.PortfolioDto.SelectionMode;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.Indexers;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.permission.PermissionChange;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.springframework.beans.factory.annotation.Autowired;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.singletonList;
import static org.sonar.api.web.UserRole.PUBLIC_PERMISSIONS;
import static org.sonar.core.component.ComponentKeys.ALLOWED_CHARACTERS_MESSAGE;
import static org.sonar.core.component.ComponentKeys.isValidProjectKey;
import static org.sonar.server.exceptions.BadRequestException.checkRequest;
@@ -64,11 +69,13 @@ public class ComponentUpdater {
private final Indexers indexers;
private final UuidFactory uuidFactory;
private final DefaultBranchNameResolver defaultBranchNameResolver;
private final PermissionUpdater<UserPermissionChange> userPermissionUpdater;
private final PermissionService permissionService;

@Autowired
public ComponentUpdater(DbClient dbClient, I18n i18n, System2 system2,
PermissionTemplateService permissionTemplateService, FavoriteUpdater favoriteUpdater,
Indexers indexers, UuidFactory uuidFactory, DefaultBranchNameResolver defaultBranchNameResolver) {
Indexers indexers, UuidFactory uuidFactory, DefaultBranchNameResolver defaultBranchNameResolver, PermissionUpdater<UserPermissionChange> userPermissionUpdater,
PermissionService permissionService) {
this.dbClient = dbClient;
this.i18n = i18n;
this.system2 = system2;
@@ -77,6 +84,8 @@ public class ComponentUpdater {
this.indexers = indexers;
this.uuidFactory = uuidFactory;
this.defaultBranchNameResolver = defaultBranchNameResolver;
this.userPermissionUpdater = userPermissionUpdater;
this.permissionService = permissionService;
}

/**
@@ -135,7 +144,9 @@ public class ComponentUpdater {
dbClient.projectDao().insert(dbSession, projectDto);
addToFavourites(dbSession, projectDto, userUuid, userLogin);
mainBranch = createMainBranch(dbSession, componentDto.uuid(), projectDto.getUuid(), mainBranchName);
if (!isManaged) {
if (isManaged) {
applyPublicPermissionsForCreator(dbSession, projectDto, userUuid);
} else {
permissionTemplateService.applyDefaultToNewComponent(dbSession, projectDto, userUuid);
}
} else if (isPortfolio(componentDto)) {
@@ -149,6 +160,21 @@ public class ComponentUpdater {
return new ComponentCreationData(componentDto, portfolioDto, mainBranch, projectDto);
}

private void applyPublicPermissionsForCreator(DbSession dbSession, ProjectDto projectDto, @Nullable String userUuid) {
if (userUuid != null) {
UserDto userDto = dbClient.userDao().selectByUuid(dbSession, userUuid);
checkState(userDto != null, "User with uuid '%s' doesn't exist", userUuid);
userPermissionUpdater.apply(dbSession,
PUBLIC_PERMISSIONS.stream()
.map(permission -> toUserPermissionChange(permission, projectDto, userDto))
.collect(Collectors.toSet()));
}
}

private UserPermissionChange toUserPermissionChange(String permission, ProjectDto projectDto, UserDto userDto) {
return new UserPermissionChange(PermissionChange.Operation.ADD, permission, projectDto, userDto, permissionService);
}

private void addToFavourites(DbSession dbSession, ProjectDto projectDto, @Nullable String userUuid, @Nullable String userLogin) {
if (permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, projectDto)) {
favoriteUpdater.add(dbSession, projectDto, userUuid, userLogin, false);

Loading…
Cancel
Save