From 75f33409de08a80bd46749b2fa0958bab6bd3bbe Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Thu, 17 Nov 2016 11:18:29 +0100 Subject: [PATCH] SONAR-8363 Mark just created projects as favorite when there's a project creator permission --- .../test/java/it/analysis/FavoriteTest.java | 58 ++++++++++++++++--- .../DefaultRubyComponentService.java | 2 +- .../computation/queue/ReportSubmitter.java | 8 ++- .../permission/PermissionTemplateService.java | 11 ++++ .../DefaultRubyComponentServiceTest.java | 16 ++--- .../queue/ReportSubmitterTest.java | 17 ++++++ 6 files changed, 94 insertions(+), 18 deletions(-) diff --git a/it/it-tests/src/test/java/it/analysis/FavoriteTest.java b/it/it-tests/src/test/java/it/analysis/FavoriteTest.java index 8ee6eaaad2b..f066888a61a 100644 --- a/it/it-tests/src/test/java/it/analysis/FavoriteTest.java +++ b/it/it-tests/src/test/java/it/analysis/FavoriteTest.java @@ -23,13 +23,18 @@ package it.analysis; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarScanner; import it.Category3Suite; +import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.sonarqube.ws.MediaTypes; +import org.sonarqube.ws.WsPermissions; import org.sonarqube.ws.client.GetRequest; import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateWsRequest; +import org.sonarqube.ws.client.permission.RemoveProjectCreatorFromTemplateWsRequest; +import org.sonarqube.ws.client.permission.SearchTemplatesWsRequest; import static com.sonar.orchestrator.container.Server.ADMIN_LOGIN; import static com.sonar.orchestrator.container.Server.ADMIN_PASSWORD; @@ -49,32 +54,71 @@ public class FavoriteTest { orchestrator.resetData(); } + @After + public void tearDown() { + removeProjectCreatorPermission(); + } + @BeforeClass public static void classSetUp() { adminWsClient = newAdminWsClient(orchestrator); } @Test - public void project_as_favorite_when_authenticated_and_first_analysis() { - SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample")) - .setProperty("sonar.login", ADMIN_LOGIN) - .setProperty("sonar.password", ADMIN_PASSWORD); + public void project_as_favorite_when_authenticated_and_first_analysis_and_a_project_creator_permission() { + SonarScanner sampleProject = createScannerWithUserCredentials(); + addProjectCreatorPermission(); + orchestrator.executeBuild(sampleProject); String response = adminWsClient.wsConnector().call(new GetRequest("api/favourites").setMediaType(MediaTypes.JSON)).content(); assertThat(response).contains(PROJECT_KEY); } + @Test + public void no_project_as_favorite_when_no_project_creator_permission() { + SonarScanner sampleProject = createScannerWithUserCredentials(); + + orchestrator.executeBuild(sampleProject); + + String response = adminWsClient.wsConnector().call(new GetRequest("api/favourites").setMediaType(MediaTypes.JSON)).content(); + assertThat(response).doesNotContain(PROJECT_KEY); + } + @Test public void no_project_as_favorite_when_second_analysis() { SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample")); orchestrator.executeBuild(sampleProject); - sampleProject - .setProperty("sonar.login", ADMIN_LOGIN) - .setProperty("sonar.password", ADMIN_PASSWORD); + sampleProject = createScannerWithUserCredentials(); + addProjectCreatorPermission(); + orchestrator.executeBuild(sampleProject); String response = adminWsClient.wsConnector().call(new GetRequest("api/favourites").setMediaType(MediaTypes.JSON)).content(); assertThat(response).doesNotContain(PROJECT_KEY); } + + private static SonarScanner createScannerWithUserCredentials() { + return SonarScanner.create(projectDir("shared/xoo-sample")) + .setProperty("sonar.login", ADMIN_LOGIN) + .setProperty("sonar.password", ADMIN_PASSWORD); + } + + private void addProjectCreatorPermission() { + WsPermissions.SearchTemplatesWsResponse permissionTemplates = adminWsClient.permissions().searchTemplates(new SearchTemplatesWsRequest()); + assertThat(permissionTemplates.getDefaultTemplatesCount()).isEqualTo(1); + adminWsClient.permissions().addProjectCreatorToTemplate(AddProjectCreatorToTemplateWsRequest.builder() + .setTemplateId(permissionTemplates.getDefaultTemplates(0).getTemplateId()) + .setPermission("admin") + .build()); + } + + private void removeProjectCreatorPermission() { + WsPermissions.SearchTemplatesWsResponse permissionTemplates = adminWsClient.permissions().searchTemplates(new SearchTemplatesWsRequest()); + assertThat(permissionTemplates.getDefaultTemplatesCount()).isEqualTo(1); + adminWsClient.permissions().removeProjectCreatorFromTemplate(RemoveProjectCreatorFromTemplateWsRequest.builder() + .setTemplateId(permissionTemplates.getDefaultTemplates(0).getTemplateId()) + .setPermission("admin") + .build()); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java index 7f5399a64f7..d1019e52006 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java @@ -85,7 +85,7 @@ public class DefaultRubyComponentService implements RubyComponentService { public long createComponent(DbSession dbSession, String key, @Nullable String branch, String name, @Nullable String qualifier) { ComponentDto provisionedComponent = componentService.create(dbSession, NewComponent.create(key, name).setQualifier(qualifier).setBranch(branch)); permissionTemplateService.applyDefaultPermissionTemplate(dbSession, provisionedComponent.getKey()); - if (Qualifiers.PROJECT.equals(provisionedComponent.qualifier())) { + if (Qualifiers.PROJECT.equals(provisionedComponent.qualifier()) && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, provisionedComponent)) { favoriteService.put(dbSession, provisionedComponent.getId()); dbSession.commit(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java index 6997d28bf35..64e16746c8a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java @@ -53,7 +53,7 @@ public class ReportSubmitter { private final FavoriteService favoriteService; public ReportSubmitter(CeQueue queue, UserSession userSession, - ComponentService componentService, PermissionTemplateService permissionTemplateService, DbClient dbClient, FavoriteService favoriteService) { + ComponentService componentService, PermissionTemplateService permissionTemplateService, DbClient dbClient, FavoriteService favoriteService) { this.queue = queue; this.userSession = userSession; this.componentService = componentService; @@ -87,8 +87,10 @@ public class ReportSubmitter { newProject.setQualifier(Qualifiers.PROJECT); // "provisioning" permission is check in ComponentService ComponentDto project = componentService.create(dbSession, newProject); - favoriteService.put(dbSession, project.getId()); - dbSession.commit(); + if (permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, project)) { + favoriteService.put(dbSession, project.getId()); + dbSession.commit(); + } permissionTemplateService.applyDefault(dbSession, project, projectCreatorUserId); diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java index c3c1dba76a9..b0bb18c690f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java @@ -50,6 +50,7 @@ import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.sonar.api.security.DefaultGroups.isAnyone; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey; import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; @@ -155,6 +156,16 @@ public class PermissionTemplateService { indexProjectPermissions(dbSession, asList(component.uuid())); } + public boolean hasDefaultTemplateWithPermissionOnProjectCreator(DbSession dbSession, ComponentDto component) { + PermissionTemplateDto template = findDefaultTemplate(dbSession, component); + return hasProjectCreatorPermission(dbSession, template); + } + + private boolean hasProjectCreatorPermission(DbSession dbSession, @Nullable PermissionTemplateDto template) { + return template != null && dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(dbSession, singletonList(template.getId())).stream() + .anyMatch(PermissionTemplateCharacteristicDto::getWithProjectCreator); + } + private void indexProjectPermissions(DbSession dbSession, List projectUuids) { permissionIndexer.index(dbSession, projectUuids); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java index 2955d6d959b..636243d7426 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java @@ -48,6 +48,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; public class DefaultRubyComponentServiceTest { @@ -76,27 +77,27 @@ public class DefaultRubyComponentServiceTest { ComponentDbTester componentDb = new ComponentDbTester(db); - DefaultRubyComponentService service = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService, favoriteService); + DefaultRubyComponentService underTest = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService, favoriteService); @Test public void find_by_key() { ComponentDto componentDto = componentDb.insertProject(); - assertThat(service.findByKey(componentDto.getKey())).isNotNull(); + assertThat(underTest.findByKey(componentDto.getKey())).isNotNull(); } @Test public void find_by_uuid() { ComponentDto componentDto = componentDb.insertProject(); - assertThat(service.findByUuid(componentDto.uuid())).isNotNull(); + assertThat(underTest.findByUuid(componentDto.uuid())).isNotNull(); } @Test public void not_find_by_uuid() { componentDb.insertProject(); - assertThat(service.findByUuid("UNKNOWN")).isNull(); + assertThat(underTest.findByUuid("UNKNOWN")).isNull(); } @Test @@ -105,8 +106,9 @@ public class DefaultRubyComponentServiceTest { String componentKey = "new-project"; String componentName = "New Project"; String qualifier = Qualifiers.PROJECT; + when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true); - Long result = service.createComponent(componentKey, componentName, qualifier); + Long result = underTest.createComponent(componentKey, componentName, qualifier); ComponentDto project = dbClient.componentDao().selectOrFailByKey(dbSession, componentKey); assertThat(project.key()).isEqualTo(componentKey); @@ -120,7 +122,7 @@ public class DefaultRubyComponentServiceTest { @Test(expected = BadRequestException.class) public void should_throw_if_malformed_key1() { userSession.login("john").setGlobalPermissions(PROVISIONING); - service.createComponent("1234", "New Project", Qualifiers.PROJECT); + underTest.createComponent("1234", "New Project", Qualifiers.PROJECT); } @Test @@ -130,7 +132,7 @@ public class DefaultRubyComponentServiceTest { Map map = newHashMap(); map.put("qualifiers", qualifiers); - List resourceDtos = service.findProvisionedProjects(map); + List resourceDtos = underTest.findProvisionedProjects(map); assertThat(resourceDtos).hasSize(1); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java index d8609659c74..4ac952e8572 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java @@ -113,6 +113,7 @@ public class ReportSubmitterTest { when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(createdProject); when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) .thenReturn(true); + when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true); underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); @@ -133,6 +134,22 @@ public class ReportSubmitterTest { })); } + @Test + public void no_favorite_when_no_project_creator_permission_on_permission_template() { + userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); + + when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + ComponentDto createdProject = new ComponentDto().setId(23L).setUuid(PROJECT_UUID).setKey(PROJECT_KEY); + when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(createdProject); + when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) + .thenReturn(true); + when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(false); + + underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); + + verifyZeroInteractions(favoriteService); + } + @Test public void submit_a_report_on_new_project_with_global_scan_permission() { userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); -- 2.39.5