From 81f41930fc05425a2fbdcefe5673dbe927a1b296 Mon Sep 17 00:00:00 2001 From: Wojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:43:40 +0100 Subject: [PATCH] SONAR-20853 Set visibility from GitHub when creating a project via scanner. --- .../management/DelegatingManagedServices.java | 7 +++ .../management/ManagedProjectService.java | 2 + .../DelegatingManagedServicesTest.java | 22 +++++++ .../almsettings/ws/GithubProjectCreator.java | 10 +++- .../server/project/ws/ProjectCreator.java | 10 +++- .../ws/GithubProjectCreatorTest.java | 57 ++++++++++++++++++- 6 files changed, 102 insertions(+), 6 deletions(-) diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/management/DelegatingManagedServices.java b/server/sonar-server-common/src/main/java/org/sonar/server/management/DelegatingManagedServices.java index 26d0f049341..35038518b4d 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/management/DelegatingManagedServices.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/management/DelegatingManagedServices.java @@ -130,6 +130,13 @@ public class DelegatingManagedServices implements ManagedInstanceService, Manage .ifPresent(managedProjectService -> managedProjectService.queuePermissionSyncTask(submitterUuid, componentUuid, projectUuid)); } + @Override + public boolean isProjectVisibilitySynchronizationActivated() { + return findManagedProjectService() + .map(ManagedProjectService::isProjectVisibilitySynchronizationActivated) + .orElse(false); + } + private Optional findManagedProjectService() { return findManagedInstanceService() .filter(ManagedProjectService.class::isInstance) diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/management/ManagedProjectService.java b/server/sonar-server-common/src/main/java/org/sonar/server/management/ManagedProjectService.java index 9b4c3b88b80..0b50712facb 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/management/ManagedProjectService.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/management/ManagedProjectService.java @@ -30,4 +30,6 @@ public interface ManagedProjectService { boolean isProjectManaged(DbSession dbSession, String projectUuid); void queuePermissionSyncTask(String submitterUuid, String componentUuid, String projectUuid); + + boolean isProjectVisibilitySynchronizationActivated(); } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/management/DelegatingManagedServicesTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/management/DelegatingManagedServicesTest.java index 92e29cb833c..04bff1e2917 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/management/DelegatingManagedServicesTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/management/DelegatingManagedServicesTest.java @@ -278,6 +278,18 @@ public class DelegatingManagedServicesTest { verify(alwaysManagedInstanceService).queuePermissionSyncTask("userUuid", "componentUuid", "projectUuid"); } + @Test + public void isProjectVisibilitySynchronizationActivated_whenManagedInstanceServices_shouldDelegatesToRightService() { + DelegatingManagedServices managedInstanceService = new DelegatingManagedServices(Set.of(new NeverManagedInstanceService(), new AlwaysManagedInstanceService())); + + assertThat(managedInstanceService.isProjectVisibilitySynchronizationActivated()).isTrue(); + } + + @Test + public void isProjectVisibilitySynchronizationActivated_whenManagedNoInstanceServices_returnsFalse() { + assertThat(NO_MANAGED_SERVICES.isProjectVisibilitySynchronizationActivated()).isFalse(); + } + private static class NeverManagedInstanceService implements ManagedInstanceService, ManagedProjectService { @Override @@ -334,6 +346,11 @@ public class DelegatingManagedServicesTest { public void queuePermissionSyncTask(String submitterUuid, String componentUuid, String projectUuid) { } + + @Override + public boolean isProjectVisibilitySynchronizationActivated() { + return false; + } } private static class AlwaysManagedInstanceService implements ManagedInstanceService, ManagedProjectService { @@ -392,6 +409,11 @@ public class DelegatingManagedServicesTest { public void queuePermissionSyncTask(String submitterUuid, String componentUuid, String projectUuid) { } + + @Override + public boolean isProjectVisibilitySynchronizationActivated() { + return true; + } } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreator.java index df7a6b58cbd..0aeff1c330e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreator.java @@ -164,7 +164,15 @@ public class GithubProjectCreator implements DevOpsProjectCreator { private ComponentCreationData createProjectAndBindToDevOpsPlatform(DbSession dbSession, @Nullable String projectKey, AlmSettingDto almSettingDto, GithubApplicationClient.Repository repository, CreationMethod creationMethod) { String key = Optional.ofNullable(projectKey).orElse(getUniqueProjectKey(repository)); - ComponentCreationData componentCreationData = projectCreator.createProject(dbSession, key, repository.getName(), repository.getDefaultBranch(), creationMethod); + + boolean isPrivate; + if (managedProjectService.isProjectVisibilitySynchronizationActivated()) { + isPrivate = repository.isPrivate(); + } else { + isPrivate = true; + } + + ComponentCreationData componentCreationData = projectCreator.createProject(dbSession, key, repository.getName(), repository.getDefaultBranch(), creationMethod, isPrivate); ProjectDto projectDto = Optional.ofNullable(componentCreationData.projectDto()).orElseThrow(); createProjectAlmSettingDto(dbSession, repository, projectDto, almSettingDto); addScanPermissionToCurrentUser(dbSession, projectDto); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectCreator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectCreator.java index 73c913a43ed..be86eb9204c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectCreator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectCreator.java @@ -50,11 +50,13 @@ public class ProjectCreator { this.componentUpdater = componentUpdater; } - public ComponentCreationData createProject(DbSession dbSession, String projectKey, String projectName, @Nullable String mainBranchName, CreationMethod creationMethod) { + public ComponentCreationData createProject(DbSession dbSession, String projectKey, String projectName, @Nullable String mainBranchName, CreationMethod creationMethod, + @Nullable Boolean isPrivate) { + boolean visibility = isPrivate != null ? isPrivate : projectDefaultVisibility.get(dbSession).isPrivate(); NewComponent projectComponent = newComponentBuilder() .setKey(projectKey) .setName(projectName) - .setPrivate(projectDefaultVisibility.get(dbSession).isPrivate()) + .setPrivate(visibility) .setQualifier(PROJECT) .build(); ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder() @@ -67,4 +69,8 @@ public class ProjectCreator { .build(); return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters); } + + public ComponentCreationData createProject(DbSession dbSession, String projectKey, String projectName, @Nullable String mainBranchName, CreationMethod creationMethod) { + return createProject(dbSession, projectKey, projectName, mainBranchName, creationMethod, projectDefaultVisibility.get(dbSession).isPrivate()); + } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorTest.java index de98ec56e6e..372c7525f59 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorTest.java @@ -290,13 +290,55 @@ public class GithubProjectCreatorTest { ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue(); assertComponentCreationParametersContainsCorrectInformation(componentCreationParameters, "generated_orga2/repo1", SCANNER_API_DEVOPS_AUTO_CONFIG); assertThat(componentCreationParameters.isManaged()).isFalse(); - assertThat(componentCreationParameters.newComponent().isPrivate()).isFalse(); + assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue(); verify(projectAlmSettingDao).insertOrUpdate(any(), projectAlmSettingDtoCaptor.capture(), eq(ALM_SETTING_KEY), eq(REPOSITORY_NAME), eq("generated_orga2/repo1")); ProjectAlmSettingDto projectAlmSettingDto = projectAlmSettingDtoCaptor.getValue(); assertAlmSettingsDtoContainsCorrectInformation(almSettingDto, requireNonNull(componentCreationData.projectDto()), projectAlmSettingDto); } + @Test + public void createProjectAndBindToDevOpsPlatformFromScanner_whenRepoFoundOnGitHubAndVisibilitySynchronizationEnabled_successfullyCreatesProjectAndSetsVisibility() { + // given + mockPublicGithubRepository(); + + ComponentCreationData componentCreationData = mockProjectCreation("generated_orga2/repo1"); + ProjectAlmSettingDao projectAlmSettingDao = mock(); + when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao); + when(managedProjectService.isProjectVisibilitySynchronizationActivated()).thenReturn(true); + + // when + ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true), + SCANNER_API_DEVOPS_AUTO_CONFIG, null); + + // then + assertThat(actualComponentCreationData).isEqualTo(componentCreationData); + + ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue(); + assertThat(componentCreationParameters.newComponent().isPrivate()).isFalse(); + } + + @Test + public void createProjectAndBindToDevOpsPlatformFromScanner_whenRepoFoundOnGitHubAndVisibilitySynchronizationDisabled_successfullyCreatesProjectAndMakesProjectPrivate() { + // given + mockGitHubRepository(); + + ComponentCreationData componentCreationData = mockProjectCreation("generated_orga2/repo1"); + ProjectAlmSettingDao projectAlmSettingDao = mock(); + when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao); + when(managedProjectService.isProjectVisibilitySynchronizationActivated()).thenReturn(false); + + // when + ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true), + SCANNER_API_DEVOPS_AUTO_CONFIG, null); + + // then + assertThat(actualComponentCreationData).isEqualTo(componentCreationData); + + ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue(); + assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue(); + } + @Test public void createProjectAndBindToDevOpsPlatformFromApi_whenRepoFoundOnGitHub_successfullyCreatesProject() { // given @@ -316,7 +358,7 @@ public class GithubProjectCreatorTest { ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue(); assertComponentCreationParametersContainsCorrectInformation(componentCreationParameters, projectKey, ALM_IMPORT_API); assertThat(componentCreationParameters.isManaged()).isFalse(); - assertThat(componentCreationParameters.newComponent().isPrivate()).isFalse(); + assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue(); verify(projectAlmSettingDao).insertOrUpdate(any(), projectAlmSettingDtoCaptor.capture(), eq(ALM_SETTING_KEY), eq(REPOSITORY_NAME), eq(projectKey)); ProjectAlmSettingDto projectAlmSettingDto = projectAlmSettingDtoCaptor.getValue(); @@ -373,16 +415,25 @@ public class GithubProjectCreatorTest { assertThat(permissionChange.getProjectUuid()).isEqualTo(actualComponentCreationData.projectDto().getUuid()); } - private void mockGitHubRepository() { + private void mockPublicGithubRepository() { + GithubApplicationClient.Repository repository =mockGitHubRepository(); + when(repository.isPrivate()).thenReturn(false); + } + + private GithubApplicationClient.Repository mockGitHubRepository() { GithubApplicationClient.Repository repository = mock(); when(repository.getDefaultBranch()).thenReturn(MAIN_BRANCH_NAME); when(repository.getName()).thenReturn(REPOSITORY_NAME); when(repository.getFullName()).thenReturn(DEVOPS_PROJECT_DESCRIPTOR.projectIdentifier()); + when(repository.isPrivate()).thenReturn(true); when(githubApplicationClient.getRepository(DEVOPS_PROJECT_DESCRIPTOR.url(), devOpsAppInstallationToken, DEVOPS_PROJECT_DESCRIPTOR.projectIdentifier())).thenReturn( Optional.of(repository)); when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn("generated_" + DEVOPS_PROJECT_DESCRIPTOR.projectIdentifier()); + return repository; } + + private ComponentCreationData mockProjectCreation(String projectKey) { ComponentCreationData componentCreationData = mock(); ProjectDto projectDto = mockProjectDto(projectKey); -- 2.39.5