@@ -23,17 +23,21 @@ import java.util.Optional; | |||
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.server.ws.WebService; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.auth.github.GitHubSettings; | |||
import org.sonar.core.i18n.I18n; | |||
import org.sonar.core.platform.EditionProvider; | |||
import org.sonar.core.platform.PlatformEditionProvider; | |||
import org.sonar.core.util.SequenceUuidFactory; | |||
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.entity.EntityDto; | |||
import org.sonar.db.newcodeperiod.NewCodePeriodDto; | |||
import org.sonar.db.permission.GlobalPermission; | |||
import org.sonar.db.project.ProjectDto; | |||
@@ -59,7 +63,10 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | |||
import static org.assertj.core.api.Assertions.tuple; | |||
import static org.mockito.ArgumentMatchers.any; | |||
import static org.mockito.ArgumentMatchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.never; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; | |||
import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS; | |||
@@ -84,20 +91,22 @@ public class ImportGithubProjectActionIT { | |||
@Rule | |||
public DbTester db = DbTester.create(system2); | |||
private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); | |||
private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE, | |||
mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(), | |||
permissionTemplateService, new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(), | |||
defaultBranchNameResolver, true); | |||
private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession); | |||
private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class); | |||
private final ProjectDefaultVisibility projectDefaultVisibility = mock(ProjectDefaultVisibility.class); | |||
private PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class); | |||
private final GitHubSettings gitHubSettings = mock(GitHubSettings.class); | |||
private NewCodeDefinitionResolver newCodeDefinitionResolver = new NewCodeDefinitionResolver(db.getDbClient(), editionProvider); | |||
private final WsActionTester ws = new WsActionTester(new ImportGithubProjectAction(db.getDbClient(), userSession, | |||
projectDefaultVisibility, appClient, componentUpdater, importHelper, projectKeyGenerator, newCodeDefinitionResolver, | |||
defaultBranchNameResolver)); | |||
defaultBranchNameResolver, gitHubSettings)); | |||
@Before | |||
public void before() { | |||
@@ -129,8 +138,7 @@ public class ImportGithubProjectActionIT { | |||
Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey()); | |||
assertThat(projectDto).isPresent(); | |||
assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent(); | |||
Optional<BranchDto> mainBranch = | |||
db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get()).stream().filter(BranchDto::isMain).findAny(); | |||
Optional<BranchDto> mainBranch = db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get()).stream().filter(BranchDto::isMain).findAny(); | |||
assertThat(mainBranch).isPresent(); | |||
assertThat(mainBranch.get().getKey()).isEqualTo("default-branch"); | |||
@@ -290,6 +298,53 @@ public class ImportGithubProjectActionIT { | |||
assertThat(result.getName()).isEqualTo(repository.getName()); | |||
} | |||
@Test | |||
public void importProject_whenGithubProvisioningIsDisabled_shouldApplyPermissionTemplate() { | |||
AlmSettingDto githubAlmSetting = setupAlm(); | |||
db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid())); | |||
GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false, | |||
"octocat/" + PROJECT_KEY_NAME, | |||
"https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch"); | |||
when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository)); | |||
when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME); | |||
when(gitHubSettings.isProvisioningEnabled()).thenReturn(false); | |||
ws.newRequest() | |||
.setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey()) | |||
.setParam(PARAM_ORGANIZATION, "octocat") | |||
.setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME) | |||
.executeProtobuf(Projects.CreateWsResponse.class); | |||
ArgumentCaptor<EntityDto> projectDtoArgumentCaptor = ArgumentCaptor.forClass(EntityDto.class); | |||
verify(permissionTemplateService).applyDefaultToNewComponent(any(DbSession.class), projectDtoArgumentCaptor.capture(), eq(userSession.getUuid())); | |||
String projectKey = projectDtoArgumentCaptor.getValue().getKey(); | |||
assertThat(projectKey).isEqualTo(PROJECT_KEY_NAME); | |||
} | |||
@Test | |||
public void importProject_whenGithubProvisioningIsEnabled_shouldNotApplyPermissionTemplate() { | |||
AlmSettingDto githubAlmSetting = setupAlm(); | |||
db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid())); | |||
GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false, | |||
"octocat/" + PROJECT_KEY_NAME, | |||
"https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch"); | |||
when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository)); | |||
when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME); | |||
when(gitHubSettings.isProvisioningEnabled()).thenReturn(true); | |||
ws.newRequest() | |||
.setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey()) | |||
.setParam(PARAM_ORGANIZATION, "octocat") | |||
.setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME) | |||
.executeProtobuf(Projects.CreateWsResponse.class); | |||
verify(permissionTemplateService, never()).applyDefaultToNewComponent(any(), any(), any()); | |||
} | |||
@Test | |||
public void fail_when_not_logged_in() { | |||
TestRequest request = ws.newRequest() |
@@ -51,6 +51,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; | |||
import static org.mockito.ArgumentMatchers.any; | |||
import static org.mockito.ArgumentMatchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.never; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.api.resources.Qualifiers.APP; | |||
@@ -388,4 +389,16 @@ public class ComponentUpdaterIT { | |||
assertThat(branch).isPresent(); | |||
assertThat(branch.get().getBranchKey()).isEqualTo(DEFAULT_MAIN_BRANCH_NAME); | |||
} | |||
@Test | |||
public void createWithoutCommit_whenProjectIsManaged_doesntApplyPermissionTemplate() { | |||
String userUuid = "42"; | |||
NewComponent project = NewComponent.newComponentBuilder() | |||
.setKey(DEFAULT_PROJECT_KEY) | |||
.setName(DEFAULT_PROJECT_NAME) | |||
.build(); | |||
underTest.createWithoutCommit(db.getSession(), project, userUuid, "user-login", null, true); | |||
verify(permissionTemplateService, never()).applyDefaultToNewComponent(any(), any(), any()); | |||
} | |||
} |
@@ -29,6 +29,7 @@ import org.sonar.alm.client.github.security.UserAccessToken; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.auth.github.GitHubSettings; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.alm.pat.AlmPatDto; | |||
@@ -40,6 +41,7 @@ import org.sonar.server.almintegration.ws.ImportHelper; | |||
import org.sonar.server.almintegration.ws.ProjectKeyGenerator; | |||
import org.sonar.server.component.ComponentCreationData; | |||
import org.sonar.server.component.ComponentUpdater; | |||
import org.sonar.server.component.NewComponent; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver; | |||
import org.sonar.server.project.DefaultBranchNameResolver; | |||
@@ -76,11 +78,13 @@ public class ImportGithubProjectAction implements AlmIntegrationsWsAction { | |||
private final DefaultBranchNameResolver defaultBranchNameResolver; | |||
private final GitHubSettings gitHubSettings; | |||
@Inject | |||
public ImportGithubProjectAction(DbClient dbClient, UserSession userSession, ProjectDefaultVisibility projectDefaultVisibility, | |||
GithubApplicationClientImpl githubApplicationClient, ComponentUpdater componentUpdater, ImportHelper importHelper, | |||
ProjectKeyGenerator projectKeyGenerator, NewCodeDefinitionResolver newCodeDefinitionResolver, | |||
DefaultBranchNameResolver defaultBranchNameResolver) { | |||
DefaultBranchNameResolver defaultBranchNameResolver, GitHubSettings gitHubSettings) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.projectDefaultVisibility = projectDefaultVisibility; | |||
@@ -90,6 +94,7 @@ public class ImportGithubProjectAction implements AlmIntegrationsWsAction { | |||
this.projectKeyGenerator = projectKeyGenerator; | |||
this.newCodeDefinitionResolver = newCodeDefinitionResolver; | |||
this.defaultBranchNameResolver = defaultBranchNameResolver; | |||
this.gitHubSettings = gitHubSettings; | |||
} | |||
@Override | |||
@@ -137,7 +142,6 @@ public class ImportGithubProjectAction implements AlmIntegrationsWsAction { | |||
importHelper.checkProvisionProjectPermission(); | |||
AlmSettingDto almSettingDto = importHelper.getAlmSetting(request); | |||
String newCodeDefinitionType = request.param(PARAM_NEW_CODE_DEFINITION_TYPE); | |||
String newCodeDefinitionValue = request.param(PARAM_NEW_CODE_DEFINITION_VALUE); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
@@ -181,13 +185,19 @@ public class ImportGithubProjectAction implements AlmIntegrationsWsAction { | |||
private ComponentCreationData createProject(DbSession dbSession, Repository repo, String mainBranchName) { | |||
boolean visibility = projectDefaultVisibility.get(dbSession).isPrivate(); | |||
String uniqueProjectKey = projectKeyGenerator.generateUniqueProjectKey(repo.getFullName()); | |||
return componentUpdater.createWithoutCommit(dbSession, newComponentBuilder() | |||
.setKey(uniqueProjectKey) | |||
.setName(repo.getName()) | |||
.setPrivate(visibility) | |||
.setQualifier(PROJECT) | |||
.build(), | |||
userSession.getUuid(), userSession.getLogin(), mainBranchName); | |||
NewComponent projectComponent = newComponentBuilder() | |||
.setKey(uniqueProjectKey) | |||
.setName(repo.getName()) | |||
.setPrivate(visibility) | |||
.setQualifier(PROJECT) | |||
.build(); | |||
return componentUpdater.createWithoutCommit( | |||
dbSession, | |||
projectComponent, | |||
userSession.getUuid(), | |||
userSession.getLogin(), | |||
mainBranchName, | |||
gitHubSettings.isProvisioningEnabled()); | |||
} | |||
private void populatePRSetting(DbSession dbSession, Repository repo, ProjectDto projectDto, AlmSettingDto almSettingDto) { |
@@ -116,7 +116,12 @@ public class ComponentUpdater { | |||
*/ | |||
public ComponentCreationData createWithoutCommit(DbSession dbSession, NewComponent newComponent, | |||
@Nullable String userUuid, @Nullable String userLogin) { | |||
return createWithoutCommit(dbSession, newComponent, userUuid, userLogin, null); | |||
return createWithoutCommit(dbSession, newComponent, userUuid, userLogin, null, false); | |||
} | |||
public ComponentCreationData createWithoutCommit(DbSession dbSession, NewComponent newComponent, | |||
@Nullable String userUuid, @Nullable String userLogin, @Nullable String mainBranchName) { | |||
return createWithoutCommit(dbSession, newComponent, userUuid, userLogin, mainBranchName, false); | |||
} | |||
/** | |||
@@ -124,7 +129,7 @@ public class ComponentUpdater { | |||
* Don't forget to call commitAndIndex(...) when ready to commit. | |||
*/ | |||
public ComponentCreationData createWithoutCommit(DbSession dbSession, NewComponent newComponent, | |||
@Nullable String userUuid, @Nullable String userLogin, @Nullable String mainBranchName) { | |||
@Nullable String userUuid, @Nullable String userLogin, @Nullable String mainBranchName, boolean isManaged) { | |||
checkKeyFormat(newComponent.qualifier(), newComponent.key()); | |||
checkKeyAlreadyExists(dbSession, newComponent); | |||
@@ -141,7 +146,9 @@ public class ComponentUpdater { | |||
dbClient.projectDao().insert(dbSession, projectDto); | |||
addToFavourites(dbSession, projectDto, userUuid, userLogin); | |||
mainBranch = createMainBranch(dbSession, componentDto.uuid(), projectDto.getUuid(), mainBranchName); | |||
permissionTemplateService.applyDefaultToNewComponent(dbSession, projectDto, userUuid); | |||
if (!isManaged) { | |||
permissionTemplateService.applyDefaultToNewComponent(dbSession, projectDto, userUuid); | |||
} | |||
} else if (isPortfolio(componentDto)) { | |||
portfolioDto = toPortfolioDto(componentDto, now); | |||
dbClient.portfolioDao().insert(dbSession, portfolioDto); |