소스 검색

SONAR-20700 add ProjectCreator to reuse logic

tags/10.3.0.82913
Aurelien Poscia 7 달 전
부모
커밋
ab910ad053
13개의 변경된 파일160개의 추가작업 그리고 113개의 파일을 삭제
  1. 7
    2
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java
  2. 5
    3
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java
  3. 10
    10
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java
  4. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectAction.java
  5. 2
    2
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreationParameters.java
  6. 7
    28
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreator.java
  7. 17
    21
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreatorFactory.java
  8. 7
    25
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java
  9. 70
    0
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectCreator.java
  10. 1
    0
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java
  11. 13
    13
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorFactoryTest.java
  12. 19
    7
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorTest.java
  13. 1
    1
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java

+ 7
- 2
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java 파일 보기

@@ -53,6 +53,7 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.almsettings.ws.GithubProjectCreatorFactory;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.IndexersImpl;
@@ -60,6 +61,7 @@ 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.management.ManagedInstanceService;
import org.sonar.server.management.ManagedProjectService;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.permission.GroupPermissionChanger;
@@ -133,11 +135,14 @@ public class ImportGithubProjectActionIT {
private final NewCodeDefinitionResolver newCodeDefinitionResolver = new NewCodeDefinitionResolver(db.getDbClient(), editionProvider);

private final ManagedProjectService managedProjectService = mock(ManagedProjectService.class);
private final ManagedInstanceService managedInstanceService = mock(ManagedInstanceService.class);

private final GithubPermissionConverter githubPermissionConverter = mock();

private final ProjectCreator projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, managedInstanceService, componentUpdater);

private final GithubProjectCreatorFactory gitHubProjectCreatorFactory = new GithubProjectCreatorFactory(db.getDbClient(),
null, appClient, projectDefaultVisibility, projectKeyGenerator, userSession, componentUpdater, gitHubSettings, githubPermissionConverter, userPermissionUpdater, permissionService,
null, appClient, projectKeyGenerator, userSession, projectCreator, gitHubSettings, githubPermissionConverter, userPermissionUpdater, permissionService,
managedProjectService);
private final WsActionTester ws = new WsActionTester(new ImportGithubProjectAction(db.getDbClient(), userSession,
componentUpdater, importHelper, newCodeDefinitionResolver, defaultBranchNameResolver, gitHubProjectCreatorFactory));
@@ -323,7 +328,7 @@ public class ImportGithubProjectActionIT {
public void importProject_whenGithubProvisioningIsEnabled_shouldNotApplyPermissionTemplate() {
AlmSettingDto githubAlmSetting = setupUserWithPatAndAlmSettings();

when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);
when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);
mockGithubDevOpsAppInteractions();
mockGithubAuthAppInteractions();


+ 5
- 3
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java 파일 보기

@@ -58,6 +58,7 @@ import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.Visibility;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.tester.UserSessionRule;

import static java.util.Collections.emptyMap;
@@ -108,11 +109,12 @@ public class BranchReportSubmitterIT {
private final BranchSupport branchSupport = spy(new BranchSupport(branchSupportDelegate));

private final DevOpsProjectCreatorFactory devOpsProjectCreatorFactory = new GithubProjectCreatorFactory(db.getDbClient(), null,
null, projectDefaultVisibility, null, userSession, componentUpdater, null, null, null, null, null);
null, null, userSession, null, null, null, null, null, null);

private final ManagedInstanceService managedInstanceService = mock();
private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), branchSupport,
projectDefaultVisibility, devOpsProjectCreatorFactory, managedInstanceService);
private final ProjectCreator projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, managedInstanceService, componentUpdater);
private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, projectCreator, componentUpdater, permissionTemplateService, db.getDbClient(), branchSupport,
devOpsProjectCreatorFactory, managedInstanceService);

@Before
public void before() {

+ 10
- 10
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java 파일 보기

@@ -56,6 +56,7 @@ import org.sonar.server.almsettings.ws.DevOpsProjectDescriptor;
import org.sonar.server.almsettings.ws.GithubProjectCreationParameters;
import org.sonar.server.almsettings.ws.GithubProjectCreator;
import org.sonar.server.almsettings.ws.GithubProjectCreatorFactory;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.es.TestIndexers;
import org.sonar.server.exceptions.BadRequestException;
@@ -123,20 +124,20 @@ public class ReportSubmitterIT {
private final PermissionService permissionService = new PermissionServiceImpl(mock());
private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), mock(System2.class), permissionTemplateService,
new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, mock(PermissionUpdater.class), permissionService);

private final ManagedProjectService managedProjectService = mock();
private final ManagedInstanceService managedInstanceService = mock();
private final ProjectCreator projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, managedInstanceService, componentUpdater);
private final GithubProjectCreatorFactory githubProjectCreatorFactory = new GithubProjectCreatorFactory(db.getDbClient(), githubGlobalSettingsValidator,
githubApplicationClient, projectDefaultVisibility, projectKeyGenerator, userSession, componentUpdater, gitHubSettings, null, permissionUpdater, permissionService,
githubApplicationClient, projectKeyGenerator, userSession, projectCreator, gitHubSettings, null, permissionUpdater, permissionService,
managedProjectService);

private final DevOpsProjectCreatorFactory devOpsProjectCreatorFactory = new DelegatingDevOpsProjectCreatorFactory(Set.of(githubProjectCreatorFactory));

private final DevOpsProjectCreatorFactory devOpsProjectCreatorFactorySpy = spy(devOpsProjectCreatorFactory);

private final ManagedInstanceService managedInstanceService = mock();

private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), ossEditionBranchSupport,
projectDefaultVisibility, devOpsProjectCreatorFactorySpy, managedInstanceService);
private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, projectCreator, componentUpdater, permissionTemplateService, db.getDbClient(),
ossEditionBranchSupport, devOpsProjectCreatorFactorySpy, managedInstanceService);

@Before
public void before() {
@@ -313,7 +314,8 @@ public class ReportSubmitterIT {

@Test
public void submit_whenReportIsForANewProjectWithoutDevOpsMetadataAndAutoProvisioningOn_shouldCreateLocalProject() {
userSession.addPermission(GlobalPermission.SCAN).addPermission(PROVISION_PROJECTS);
UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(GlobalPermission.SCAN).addPermission(PROVISION_PROJECTS);
when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), any(), eq(PROJECT_KEY))).thenReturn(true);
mockSuccessfulPrepareSubmitCall();
@@ -367,11 +369,9 @@ public class ReportSubmitterIT {
mockGithubRepository();

DevOpsProjectDescriptor projectDescriptor = new DevOpsProjectDescriptor(ALM.GITHUB, "apiUrl", "orga/repo");
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(projectDescriptor, almSettingDto, true,
managedInstanceService.isInstanceExternallyManaged(), userSession, mock(),
null);
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(projectDescriptor, almSettingDto, userSession, mock(), null);
DevOpsProjectCreator devOpsProjectCreator = spy(new GithubProjectCreator(db.getDbClient(), githubApplicationClient, null, projectKeyGenerator,
componentUpdater, permissionUpdater, permissionService, managedProjectService, githubProjectCreationParameters));
permissionUpdater, permissionService, managedProjectService, projectCreator, githubProjectCreationParameters));
doReturn(Optional.of(devOpsProjectCreator)).when(devOpsProjectCreatorFactorySpy).getDevOpsProjectCreator(any(), eq(characteristics));
return devOpsProjectCreator;
}

+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectAction.java 파일 보기

@@ -142,7 +142,7 @@ public class ImportGithubProjectAction implements AlmIntegrationsWsAction {
String url = requireNonNull(almSettingDto.getUrl(), "DevOps Platform url cannot be null");
DevOpsProjectDescriptor devOpsProjectDescriptor = new DevOpsProjectDescriptor(ALM.GITHUB, url, repositoryKey);

DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(dbSession, almSettingDto, accessToken, devOpsProjectDescriptor);
DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(almSettingDto, accessToken, devOpsProjectDescriptor);
CreationMethod creationMethod = getCreationMethod(ALM_IMPORT, userSession.isAuthenticatedBrowserSession());
ComponentCreationData componentCreationData = devOpsProjectCreator.createProjectAndBindToDevOpsPlatform(dbSession, creationMethod, null);


+ 2
- 2
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreationParameters.java 파일 보기

@@ -25,7 +25,7 @@ import org.sonar.alm.client.github.security.AccessToken;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.server.user.UserSession;

public record GithubProjectCreationParameters(DevOpsProjectDescriptor devOpsProjectDescriptor, AlmSettingDto almSettingDto, boolean projectsArePrivateByDefault,
boolean isProvisioningEnabled, UserSession userSession, AccessToken devOpsAppInstallationToken,
public record GithubProjectCreationParameters(DevOpsProjectDescriptor devOpsProjectDescriptor, AlmSettingDto almSettingDto, UserSession userSession,
AccessToken devOpsAppInstallationToken,
@Nullable AppInstallationToken authAppInstallationToken) {
}

+ 7
- 28
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreator.java 파일 보기

@@ -44,20 +44,16 @@ import org.sonar.db.user.UserIdDto;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.common.permission.Operation;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.management.ManagedProjectService;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.user.UserSession;

import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toSet;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.utils.Preconditions.checkState;
import static org.sonar.server.component.NewComponent.newComponentBuilder;

public class GithubProjectCreator implements DevOpsProjectCreator {

@@ -65,10 +61,10 @@ public class GithubProjectCreator implements DevOpsProjectCreator {
private final GithubApplicationClient githubApplicationClient;
private final GithubPermissionConverter githubPermissionConverter;
private final ProjectKeyGenerator projectKeyGenerator;
private final ComponentUpdater componentUpdater;
private final PermissionUpdater<UserPermissionChange> permissionUpdater;
private final PermissionService permissionService;
private final ManagedProjectService managedProjectService;
private final ProjectCreator projectCreator;
private final GithubProjectCreationParameters githubProjectCreationParameters;
private final DevOpsProjectDescriptor devOpsProjectDescriptor;
private final UserSession userSession;
@@ -79,17 +75,17 @@ public class GithubProjectCreator implements DevOpsProjectCreator {
private final AppInstallationToken authAppInstallationToken;

public GithubProjectCreator(DbClient dbClient, GithubApplicationClient githubApplicationClient, GithubPermissionConverter githubPermissionConverter,
ProjectKeyGenerator projectKeyGenerator, ComponentUpdater componentUpdater, PermissionUpdater<UserPermissionChange> permissionUpdater, PermissionService permissionService,
ManagedProjectService managedProjectService, GithubProjectCreationParameters githubProjectCreationParameters) {
ProjectKeyGenerator projectKeyGenerator, PermissionUpdater<UserPermissionChange> permissionUpdater, PermissionService permissionService,
ManagedProjectService managedProjectService, ProjectCreator projectCreator, GithubProjectCreationParameters githubProjectCreationParameters) {

this.dbClient = dbClient;
this.githubApplicationClient = githubApplicationClient;
this.githubPermissionConverter = githubPermissionConverter;
this.projectKeyGenerator = projectKeyGenerator;
this.componentUpdater = componentUpdater;
this.permissionUpdater = permissionUpdater;
this.permissionService = permissionService;
this.managedProjectService = managedProjectService;
this.projectCreator = projectCreator;
this.githubProjectCreationParameters = githubProjectCreationParameters;
userSession = githubProjectCreationParameters.userSession();
almSettingDto = githubProjectCreationParameters.almSettingDto();
@@ -167,7 +163,8 @@ public class GithubProjectCreator implements DevOpsProjectCreator {

private ComponentCreationData createProjectAndBindToDevOpsPlatform(DbSession dbSession, @Nullable String projectKey, AlmSettingDto almSettingDto,
GithubApplicationClient.Repository repository, CreationMethod creationMethod) {
ComponentCreationData componentCreationData = createProject(dbSession, projectKey, repository, creationMethod);
String key = Optional.ofNullable(projectKey).orElse(getUniqueProjectKey(repository));
ComponentCreationData componentCreationData = projectCreator.createProject(dbSession, key, repository.getName(), repository.getDefaultBranch(), creationMethod);
ProjectDto projectDto = Optional.ofNullable(componentCreationData.projectDto()).orElseThrow();
createProjectAlmSettingDto(dbSession, repository, projectDto, almSettingDto);
addScanPermissionToCurrentUser(dbSession, projectDto);
@@ -188,24 +185,6 @@ public class GithubProjectCreator implements DevOpsProjectCreator {
managedProjectService.queuePermissionSyncTask(userUuid, mainBranchDto.getUuid(), projectDto.getUuid());
}

private ComponentCreationData createProject(DbSession dbSession, @Nullable String projectKey, GithubApplicationClient.Repository repository, CreationMethod creationMethod) {
NewComponent projectComponent = newComponentBuilder()
.setKey(Optional.ofNullable(projectKey).orElse(getUniqueProjectKey(repository)))
.setName(repository.getName())
.setPrivate(githubProjectCreationParameters.projectsArePrivateByDefault())
.setQualifier(PROJECT)
.build();
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(projectComponent)
.userLogin(userSession.getLogin())
.userUuid(userSession.getUuid())
.mainBranchName(repository.getDefaultBranch())
.isManaged(githubProjectCreationParameters.isProvisioningEnabled())
.creationMethod(creationMethod)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private String getUniqueProjectKey(GithubApplicationClient.Repository repository) {
return projectKeyGenerator.generateUniqueProjectKey(repository.getFullName());
}

+ 17
- 21
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubProjectCreatorFactory.java 파일 보기

@@ -36,12 +36,11 @@ import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.management.ManagedProjectService;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.user.UserSession;

import static java.lang.String.format;
@@ -55,10 +54,9 @@ public class GithubProjectCreatorFactory implements DevOpsProjectCreatorFactory
private final DbClient dbClient;
private final GithubGlobalSettingsValidator githubGlobalSettingsValidator;
private final GithubApplicationClient githubApplicationClient;
private final ProjectDefaultVisibility projectDefaultVisibility;
private final ProjectKeyGenerator projectKeyGenerator;
private final ProjectCreator projectCreator;
private final UserSession userSession;
private final ComponentUpdater componentUpdater;
private final GitHubSettings gitHubSettings;
private final GithubPermissionConverter githubPermissionConverter;
private final PermissionUpdater<UserPermissionChange> permissionUpdater;
@@ -67,16 +65,15 @@ public class GithubProjectCreatorFactory implements DevOpsProjectCreatorFactory
private final ManagedProjectService managedProjectService;

public GithubProjectCreatorFactory(DbClient dbClient, GithubGlobalSettingsValidator githubGlobalSettingsValidator,
GithubApplicationClient githubApplicationClient, ProjectDefaultVisibility projectDefaultVisibility, ProjectKeyGenerator projectKeyGenerator, UserSession userSession,
ComponentUpdater componentUpdater, GitHubSettings gitHubSettings, GithubPermissionConverter githubPermissionConverter,
GithubApplicationClient githubApplicationClient, ProjectKeyGenerator projectKeyGenerator, UserSession userSession,
ProjectCreator projectCreator, GitHubSettings gitHubSettings, GithubPermissionConverter githubPermissionConverter,
PermissionUpdater<UserPermissionChange> permissionUpdater, PermissionService permissionService, ManagedProjectService managedProjectService) {
this.dbClient = dbClient;
this.githubGlobalSettingsValidator = githubGlobalSettingsValidator;
this.githubApplicationClient = githubApplicationClient;
this.projectDefaultVisibility = projectDefaultVisibility;
this.projectKeyGenerator = projectKeyGenerator;
this.userSession = userSession;
this.componentUpdater = componentUpdater;
this.projectCreator = projectCreator;
this.gitHubSettings = gitHubSettings;
this.githubPermissionConverter = githubPermissionConverter;
this.permissionUpdater = permissionUpdater;
@@ -95,40 +92,39 @@ public class GithubProjectCreatorFactory implements DevOpsProjectCreatorFactory

return dbClient.almSettingDao().selectByAlm(dbSession, ALM.GITHUB).stream()
.filter(almSettingDto -> devOpsProjectDescriptor.url().equals(almSettingDto.getUrl()))
.map(almSettingDto -> findInstallationIdAndCreateDevOpsProjectCreator(dbSession, devOpsProjectDescriptor, almSettingDto))
.map(almSettingDto -> findInstallationIdAndCreateDevOpsProjectCreator(devOpsProjectDescriptor, almSettingDto))
.flatMap(Optional::stream)
.findFirst();

}

private Optional<DevOpsProjectCreator> findInstallationIdAndCreateDevOpsProjectCreator(DbSession dbSession, DevOpsProjectDescriptor devOpsProjectDescriptor,
private Optional<DevOpsProjectCreator> findInstallationIdAndCreateDevOpsProjectCreator(DevOpsProjectDescriptor devOpsProjectDescriptor,
AlmSettingDto almSettingDto) {
GithubAppConfiguration githubAppConfiguration = githubGlobalSettingsValidator.validate(almSettingDto);
return findInstallationIdToAccessRepo(githubAppConfiguration, devOpsProjectDescriptor.projectIdentifier())
.map(installationId -> generateAppInstallationToken(githubAppConfiguration, installationId))
.map(appInstallationToken -> createGithubProjectCreator(dbSession, devOpsProjectDescriptor, almSettingDto, appInstallationToken));
.map(appInstallationToken -> createGithubProjectCreator(devOpsProjectDescriptor, almSettingDto, appInstallationToken));
}

private GithubProjectCreator createGithubProjectCreator(DbSession dbSession, DevOpsProjectDescriptor devOpsProjectDescriptor, AlmSettingDto almSettingDto,
private GithubProjectCreator createGithubProjectCreator(DevOpsProjectDescriptor devOpsProjectDescriptor, AlmSettingDto almSettingDto,
AppInstallationToken appInstallationToken) {
LOG.info("DevOps configuration {} auto-detected for project {}", almSettingDto.getKey(), devOpsProjectDescriptor.projectIdentifier());
Optional<AppInstallationToken> authAppInstallationToken = getAuthAppInstallationTokenIfNecessary(devOpsProjectDescriptor);

GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(devOpsProjectDescriptor,
almSettingDto, projectDefaultVisibility.get(dbSession).isPrivate(), gitHubSettings.isProvisioningEnabled(), userSession, appInstallationToken,
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(devOpsProjectDescriptor, almSettingDto, userSession, appInstallationToken,
authAppInstallationToken.orElse(null));
return new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, componentUpdater, permissionUpdater, permissionService,
managedProjectService, githubProjectCreationParameters);
return new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, permissionUpdater, permissionService,
managedProjectService, projectCreator, githubProjectCreationParameters);
}

public DevOpsProjectCreator getDevOpsProjectCreator(DbSession dbSession, AlmSettingDto almSettingDto, AccessToken accessToken,
public DevOpsProjectCreator getDevOpsProjectCreator(AlmSettingDto almSettingDto, AccessToken accessToken,
DevOpsProjectDescriptor devOpsProjectDescriptor) {

Optional<AppInstallationToken> authAppInstallationToken = getAuthAppInstallationTokenIfNecessary(devOpsProjectDescriptor);
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(devOpsProjectDescriptor,
almSettingDto, projectDefaultVisibility.get(dbSession).isPrivate(), gitHubSettings.isProvisioningEnabled(), userSession, accessToken, authAppInstallationToken.orElse(null));
return new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, componentUpdater, permissionUpdater, permissionService,
managedProjectService, githubProjectCreationParameters
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(devOpsProjectDescriptor, almSettingDto, userSession, accessToken,
authAppInstallationToken.orElse(null));
return new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, permissionUpdater, permissionService,
managedProjectService, projectCreator, githubProjectCreationParameters
);
}


+ 7
- 25
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java 파일 보기

@@ -40,14 +40,12 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.server.almsettings.ws.DevOpsProjectCreator;
import org.sonar.server.almsettings.ws.DevOpsProjectCreatorFactory;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.user.UserSession;

import static java.lang.String.format;
@@ -55,7 +53,6 @@ import static org.apache.commons.lang.StringUtils.defaultIfBlank;
import static org.sonar.db.permission.GlobalPermission.SCAN;
import static org.sonar.db.project.CreationMethod.SCANNER_API;
import static org.sonar.db.project.CreationMethod.SCANNER_API_DEVOPS_AUTO_CONFIG;
import static org.sonar.server.component.NewComponent.newComponentBuilder;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;

@ServerSide
@@ -63,24 +60,25 @@ public class ReportSubmitter {

private final CeQueue queue;
private final UserSession userSession;

private final ProjectCreator projectCreator;
private final ComponentUpdater componentUpdater;
private final PermissionTemplateService permissionTemplateService;
private final DbClient dbClient;
private final BranchSupport branchSupport;
private final ProjectDefaultVisibility projectDefaultVisibility;
private final DevOpsProjectCreatorFactory devOpsProjectCreatorFactory;
private final ManagedInstanceService managedInstanceService;

public ReportSubmitter(CeQueue queue, UserSession userSession, ComponentUpdater componentUpdater,
PermissionTemplateService permissionTemplateService, DbClient dbClient, BranchSupport branchSupport, ProjectDefaultVisibility projectDefaultVisibility,
public ReportSubmitter(CeQueue queue, UserSession userSession, ProjectCreator projectCreator, ComponentUpdater componentUpdater,
PermissionTemplateService permissionTemplateService, DbClient dbClient, BranchSupport branchSupport,
DevOpsProjectCreatorFactory devOpsProjectCreatorFactory, ManagedInstanceService managedInstanceService) {
this.queue = queue;
this.userSession = userSession;
this.projectCreator = projectCreator;
this.componentUpdater = componentUpdater;
this.permissionTemplateService = permissionTemplateService;
this.dbClient = dbClient;
this.branchSupport = branchSupport;
this.projectDefaultVisibility = projectDefaultVisibility;
this.devOpsProjectCreatorFactory = devOpsProjectCreatorFactory;
this.managedInstanceService = managedInstanceService;
}
@@ -174,7 +172,7 @@ public class ReportSubmitter {
if (devOpsProjectCreator != null) {
return devOpsProjectCreator.createProjectAndBindToDevOpsPlatform(dbSession, SCANNER_API_DEVOPS_AUTO_CONFIG, projectKey);
}
return createProject(dbSession, componentKey.getKey(), defaultIfBlank(projectName, projectKey));
return projectCreator.createProject(dbSession, componentKey.getKey(), defaultIfBlank(projectName, projectKey), null, SCANNER_API);
}

private void throwIfCurrentUserWouldNotHaveScanPermission(String projectKey, DbSession dbSession, @Nullable DevOpsProjectCreator devOpsProjectCreator) {
@@ -193,22 +191,6 @@ public class ReportSubmitter {
return permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(dbSession, userSession.getUuid(), projectKey);
}

private ComponentCreationData createProject(DbSession dbSession, String projectKey, String projectName) {
NewComponent newProject = newComponentBuilder()
.setKey(projectKey)
.setName(defaultIfBlank(projectName, projectKey))
.setQualifier(Qualifiers.PROJECT)
.setPrivate(projectDefaultVisibility.get(dbSession).isPrivate())
.build();
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userLogin(userSession.getLogin())
.userUuid(userSession.getUuid())
.creationMethod(SCANNER_API)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private CeTask submitReport(DbSession dbSession, InputStream reportInput, ComponentDto branch, BranchDto mainBranch, Map<String, String> characteristics) {
CeTaskSubmit.Builder submit = queue.prepareSubmit();


+ 70
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectCreator.java 파일 보기

@@ -0,0 +1,70 @@
/*
* SonarQube
* Copyright (C) 2009-2023 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.project.ws;

import javax.annotation.Nullable;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbSession;
import org.sonar.db.project.CreationMethod;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.user.UserSession;

import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.server.component.NewComponent.newComponentBuilder;

@ServerSide
public class ProjectCreator {

private final UserSession userSession;
private final ProjectDefaultVisibility projectDefaultVisibility;
private final ManagedInstanceService managedInstanceService;
private final ComponentUpdater componentUpdater;

public ProjectCreator(UserSession userSession, ProjectDefaultVisibility projectDefaultVisibility, ManagedInstanceService managedInstanceService,
ComponentUpdater componentUpdater) {
this.userSession = userSession;
this.projectDefaultVisibility = projectDefaultVisibility;
this.managedInstanceService = managedInstanceService;
this.componentUpdater = componentUpdater;
}

public ComponentCreationData createProject(DbSession dbSession, String projectKey, String projectName, @Nullable String mainBranchName, CreationMethod creationMethod) {
NewComponent projectComponent = newComponentBuilder()
.setKey(projectKey)
.setName(projectName)
.setPrivate(projectDefaultVisibility.get(dbSession).isPrivate())
.setQualifier(PROJECT)
.build();
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(projectComponent)
.userLogin(userSession.getLogin())
.userUuid(userSession.getUuid())
.mainBranchName(mainBranchName)
.isManaged(managedInstanceService.isInstanceExternallyManaged())
.creationMethod(creationMethod)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}
}

+ 1
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java 파일 보기

@@ -36,6 +36,7 @@ public class ProjectsWsModule extends Module {
ProjectFinder.class,
ProjectLifeCycleListenersImpl.class,
ProjectsWs.class,
ProjectCreator.class,
CreateAction.class,
BulkDeleteAction.class,
DeleteAction.class,

+ 13
- 13
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorFactoryTest.java 파일 보기

@@ -38,12 +38,12 @@ import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.management.ManagedProjectService;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.user.UserSession;

import static org.assertj.core.api.Assertions.assertThat;
@@ -75,8 +75,6 @@ public class GithubProjectCreatorFactoryTest {
private GithubGlobalSettingsValidator githubGlobalSettingsValidator;
@Mock
private GithubApplicationClient githubApplicationClient;
@Mock
private ComponentUpdater componentUpdater;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private DbClient dbClient;
@Mock
@@ -99,6 +97,8 @@ public class GithubProjectCreatorFactoryTest {
private PermissionUpdater<UserPermissionChange> permissionUpdater;
@Mock
private ManagedProjectService managedProjectService;
@Mock
private ProjectCreator projectCreator;

@InjectMocks
private GithubProjectCreatorFactory githubProjectCreatorFactory;
@@ -153,7 +153,7 @@ public class GithubProjectCreatorFactoryTest {

DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(dbSession, VALID_GITHUB_PROJECT_COORDINATES).orElseThrow();

GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(almSettingDto, false, false);
GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(almSettingDto, false);
assertThat(devOpsProjectCreator).usingRecursiveComparison().isEqualTo(expectedGithubProjectCreator);
}

@@ -174,7 +174,7 @@ public class GithubProjectCreatorFactoryTest {

DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(dbSession, VALID_GITHUB_PROJECT_COORDINATES).orElseThrow();

GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(almSettingDto, true, true);
GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(almSettingDto, true);
assertThat(devOpsProjectCreator).usingRecursiveComparison().isEqualTo(expectedGithubProjectCreator);
}

@@ -188,7 +188,7 @@ public class GithubProjectCreatorFactoryTest {

DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(dbSession, VALID_GITHUB_PROJECT_COORDINATES).orElseThrow();

GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(matchingAlmSettingDto, false, false);
GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(matchingAlmSettingDto, false);
assertThat(devOpsProjectCreator).usingRecursiveComparison().isEqualTo(expectedGithubProjectCreator);
}

@@ -198,9 +198,9 @@ public class GithubProjectCreatorFactoryTest {

mockSuccessfulGithubInteraction();

DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(dbSession, mockAlmSettingDto, appInstallationToken, GITHUB_PROJECT_DESCRIPTOR);
DevOpsProjectCreator devOpsProjectCreator = githubProjectCreatorFactory.getDevOpsProjectCreator(mockAlmSettingDto, appInstallationToken, GITHUB_PROJECT_DESCRIPTOR);

GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(mockAlmSettingDto, false, false);
GithubProjectCreator expectedGithubProjectCreator = getExpectedGithubProjectCreator(mockAlmSettingDto, false);
assertThat(devOpsProjectCreator).usingRecursiveComparison().isEqualTo(expectedGithubProjectCreator);
}

@@ -209,13 +209,13 @@ public class GithubProjectCreatorFactoryTest {
when(githubApplicationClient.createAppInstallationToken(any(), eq(APP_INSTALLATION_ID))).thenReturn(Optional.of(appInstallationToken));
}

private GithubProjectCreator getExpectedGithubProjectCreator(AlmSettingDto almSettingDto, boolean projectsArePrivateByDefault, boolean isInstanceManaged) {
private GithubProjectCreator getExpectedGithubProjectCreator(AlmSettingDto almSettingDto, boolean isInstanceManaged) {
DevOpsProjectDescriptor devOpsProjectDescriptor = new DevOpsProjectDescriptor(ALM.GITHUB, almSettingDto.getUrl(), GITHUB_REPO_FULL_NAME);
AppInstallationToken authAppInstallToken = isInstanceManaged ? authAppInstallationToken : null;
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(devOpsProjectDescriptor,
almSettingDto, projectsArePrivateByDefault, isInstanceManaged, userSession, appInstallationToken, authAppInstallToken);
return new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, componentUpdater, permissionUpdater, permissionService,
managedProjectService, githubProjectCreationParameters);
GithubProjectCreationParameters githubProjectCreationParameters = new GithubProjectCreationParameters(devOpsProjectDescriptor, almSettingDto, userSession, appInstallationToken,
authAppInstallToken);
return new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, permissionUpdater, permissionService,
managedProjectService, projectCreator, githubProjectCreationParameters);
}

private AlmSettingDto mockAlmSettingDto(boolean repoAccess) {

+ 19
- 7
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GithubProjectCreatorTest.java 파일 보기

@@ -55,11 +55,14 @@ import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.management.ManagedProjectService;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionServiceImpl;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.project.ProjectDefaultVisibility;
import org.sonar.server.project.ws.ProjectCreator;
import org.sonar.server.user.UserSession;

import static java.util.Objects.requireNonNull;
@@ -110,9 +113,14 @@ public class GithubProjectCreatorTest {
private final PermissionService permissionService = new PermissionServiceImpl(mock());
@Mock
private PermissionUpdater<UserPermissionChange> permissionUpdater;

@Mock
private ManagedProjectService managedProjectService;
@Mock
private ManagedInstanceService managedInstanceService;

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private ProjectDefaultVisibility projectDefaultVisibility;
private ProjectCreator projectCreator;

private GithubProjectCreator githubProjectCreator;

@@ -135,8 +143,10 @@ public class GithubProjectCreatorTest {
when(githubProjectCreationParameters.authAppInstallationToken()).thenReturn(authAppInstallationToken);
when(githubProjectCreationParameters.almSettingDto()).thenReturn(almSettingDto);

githubProjectCreator = new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator, componentUpdater,
permissionUpdater, permissionService, managedProjectService, githubProjectCreationParameters);
projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, managedInstanceService, componentUpdater);
githubProjectCreator = new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator,
permissionUpdater, permissionService, managedProjectService, projectCreator, githubProjectCreationParameters);

}

@Test
@@ -146,6 +156,7 @@ public class GithubProjectCreatorTest {
assertThatIllegalStateException().isThrownBy(() -> githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform())
.withMessage("An auth app token is required in case repository permissions checking is necessary.");
}

@Test
public void isScanAllowedUsingPermissionsFromDevopsPlatform_whenUserIsNotAGitHubUser_returnsFalse() {
assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isFalse();
@@ -213,7 +224,8 @@ public class GithubProjectCreatorTest {

private void mockGithubCollaboratorsFromApi(GsonRepositoryCollaborator... repositoryCollaborators) {
Set<GsonRepositoryCollaborator> collaborators = Arrays.stream(repositoryCollaborators).collect(toSet());
when(githubApplicationClient.getRepositoryCollaborators(DEVOPS_PROJECT_DESCRIPTOR.url(), authAppInstallationToken, ORGANIZATION_NAME, REPOSITORY_NAME)).thenReturn(collaborators);
when(githubApplicationClient.getRepositoryCollaborators(DEVOPS_PROJECT_DESCRIPTOR.url(), authAppInstallationToken, ORGANIZATION_NAME, REPOSITORY_NAME)).thenReturn(
collaborators);
}

private GsonRepositoryTeam mockGithubTeam(String name, int id, String role, String... sqPermissions) {
@@ -317,8 +329,8 @@ public class GithubProjectCreatorTest {
@Test
public void createProjectAndBindToDevOpsPlatformFromApi_whenRepoFoundOnGitHubAutoProvisioningOnAndRepoPrivate_successfullyCreatesProject() {
// given
when(githubProjectCreationParameters.projectsArePrivateByDefault()).thenReturn(true);
when(githubProjectCreationParameters.isProvisioningEnabled()).thenReturn(true);
when(projectDefaultVisibility.get(any()).isPrivate()).thenReturn(true);
when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);

String projectKey = "customProjectKey";
mockGitHubRepository();
@@ -347,7 +359,7 @@ public class GithubProjectCreatorTest {
}

private void verifyProjectSyncTaskWasCreated(ComponentCreationData componentCreationData) {
String projectUuid = requireNonNull( componentCreationData.projectDto()).getUuid();
String projectUuid = requireNonNull(componentCreationData.projectDto()).getUuid();
String mainBranchUuid = requireNonNull(componentCreationData.mainBranchDto()).getUuid();
verify(managedProjectService).queuePermissionSyncTask(USER_UUID, mainBranchUuid, projectUuid);
}

+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java 파일 보기

@@ -29,6 +29,6 @@ public class ProjectsWsModuleTest {
public void verify_count_of_added_components_on_SonarQube() {
ListContainer container = new ListContainer();
new ProjectsWsModule().configure(container);
assertThat(container.getAddedObjects()).hasSize(13);
assertThat(container.getAddedObjects()).hasSize(14);
}
}

Loading…
취소
저장