@@ -0,0 +1,45 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 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.almintegration.validator; | |||
import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.db.alm.setting.AlmSettingDto; | |||
@ServerSide | |||
public class BitbucketServerSettingsValidator { | |||
private final BitbucketServerRestClient bitbucketServerRestClient; | |||
public BitbucketServerSettingsValidator(BitbucketServerRestClient bitbucketServerRestClient) { | |||
this.bitbucketServerRestClient = bitbucketServerRestClient; | |||
} | |||
public void validate(AlmSettingDto almSettingDto) { | |||
String bitbucketUrl = almSettingDto.getUrl(); | |||
String bitbucketToken = almSettingDto.getPersonalAccessToken(); | |||
if (bitbucketUrl == null || bitbucketToken == null) { | |||
throw new IllegalArgumentException("Your global Bitbucket Server configuration is incomplete."); | |||
} | |||
bitbucketServerRestClient.validateUrl(bitbucketUrl); | |||
bitbucketServerRestClient.validateToken(bitbucketUrl, bitbucketToken); | |||
bitbucketServerRestClient.validateReadPermission(bitbucketUrl, bitbucketToken); | |||
} | |||
} |
@@ -20,6 +20,7 @@ | |||
package org.sonar.server.almintegration.ws; | |||
import org.sonar.core.platform.Module; | |||
import org.sonar.server.almintegration.validator.BitbucketServerSettingsValidator; | |||
import org.sonar.server.almintegration.validator.GithubGlobalSettingsValidator; | |||
import org.sonar.server.almintegration.validator.GitlabGlobalSettingsValidator; | |||
import org.sonar.server.almintegration.ws.azure.ImportAzureProjectAction; | |||
@@ -50,6 +51,7 @@ public class AlmIntegrationsWSModule extends Module { | |||
SearchBitbucketCloudReposAction.class, | |||
GetGithubClientIdAction.class, | |||
GithubGlobalSettingsValidator.class, | |||
BitbucketServerSettingsValidator.class, | |||
ImportGithubProjectAction.class, | |||
ListGithubOrganizationsAction.class, | |||
ListGithubRepositoriesAction.class, |
@@ -21,13 +21,13 @@ package org.sonar.server.almsettings.ws; | |||
import org.sonar.alm.client.azure.AzureDevOpsHttpClient; | |||
import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudRestClient; | |||
import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.alm.setting.AlmSettingDto; | |||
import org.sonar.server.almintegration.validator.BitbucketServerSettingsValidator; | |||
import org.sonar.server.almintegration.validator.GithubGlobalSettingsValidator; | |||
import org.sonar.server.almintegration.validator.GitlabGlobalSettingsValidator; | |||
import org.sonar.server.user.UserSession; | |||
@@ -42,20 +42,24 @@ public class ValidateAction implements AlmSettingsWsAction { | |||
private final AzureDevOpsHttpClient azureDevOpsHttpClient; | |||
private final GitlabGlobalSettingsValidator gitlabSettingsValidator; | |||
private final GithubGlobalSettingsValidator githubGlobalSettingsValidator; | |||
private final BitbucketServerRestClient bitbucketServerRestClient; | |||
private final BitbucketServerSettingsValidator bitbucketServerSettingsValidator; | |||
private final BitbucketCloudRestClient bitbucketCloudRestClient; | |||
public ValidateAction(DbClient dbClient, UserSession userSession, AlmSettingsSupport almSettingsSupport, | |||
public ValidateAction(DbClient dbClient, | |||
UserSession userSession, | |||
AlmSettingsSupport almSettingsSupport, | |||
AzureDevOpsHttpClient azureDevOpsHttpClient, | |||
GithubGlobalSettingsValidator githubGlobalSettingsValidator, GitlabGlobalSettingsValidator gitlabSettingsValidator, | |||
BitbucketServerRestClient bitbucketServerRestClient, BitbucketCloudRestClient bitbucketCloudRestClient) { | |||
GithubGlobalSettingsValidator githubGlobalSettingsValidator, | |||
GitlabGlobalSettingsValidator gitlabSettingsValidator, | |||
BitbucketServerSettingsValidator bitbucketServerSettingsValidator, | |||
BitbucketCloudRestClient bitbucketCloudRestClient) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.almSettingsSupport = almSettingsSupport; | |||
this.azureDevOpsHttpClient = azureDevOpsHttpClient; | |||
this.githubGlobalSettingsValidator = githubGlobalSettingsValidator; | |||
this.gitlabSettingsValidator = gitlabSettingsValidator; | |||
this.bitbucketServerRestClient = bitbucketServerRestClient; | |||
this.bitbucketServerSettingsValidator = bitbucketServerSettingsValidator; | |||
this.bitbucketCloudRestClient = bitbucketCloudRestClient; | |||
} | |||
@@ -93,7 +97,7 @@ public class ValidateAction implements AlmSettingsWsAction { | |||
githubGlobalSettingsValidator.validate(almSettingDto); | |||
break; | |||
case BITBUCKET: | |||
validateBitbucketServer(almSettingDto); | |||
bitbucketServerSettingsValidator.validate(almSettingDto); | |||
break; | |||
case BITBUCKET_CLOUD: | |||
validateBitbucketCloud(almSettingDto); | |||
@@ -113,12 +117,6 @@ public class ValidateAction implements AlmSettingsWsAction { | |||
} | |||
} | |||
private void validateBitbucketServer(AlmSettingDto almSettingDto) { | |||
bitbucketServerRestClient.validateUrl(almSettingDto.getUrl()); | |||
bitbucketServerRestClient.validateToken(almSettingDto.getUrl(), almSettingDto.getPersonalAccessToken()); | |||
bitbucketServerRestClient.validateReadPermission(almSettingDto.getUrl(), almSettingDto.getPersonalAccessToken()); | |||
} | |||
private void validateBitbucketCloud(AlmSettingDto almSettingDto) { | |||
bitbucketCloudRestClient.validate(almSettingDto.getClientId(), almSettingDto.getClientSecret(), almSettingDto.getAppId()); | |||
} |
@@ -0,0 +1,72 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 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.almintegration.validator; | |||
import org.junit.Test; | |||
import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient; | |||
import org.sonar.db.alm.setting.AlmSettingDto; | |||
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; | |||
import static org.mockito.ArgumentMatchers.anyString; | |||
import static org.mockito.Mockito.doThrow; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.times; | |||
import static org.mockito.Mockito.verify; | |||
import static org.sonar.db.almsettings.AlmSettingsTesting.newBitbucketAlmSettingDto; | |||
public class BitbucketServerSettingsValidatorTest { | |||
private final BitbucketServerRestClient bitbucketServerRestClient = mock(BitbucketServerRestClient.class); | |||
private final BitbucketServerSettingsValidator underTest = new BitbucketServerSettingsValidator(bitbucketServerRestClient); | |||
@Test | |||
public void validate_success() { | |||
AlmSettingDto almSettingDto = newBitbucketAlmSettingDto() | |||
.setUrl("http://abc.com") | |||
.setPersonalAccessToken("abc"); | |||
underTest.validate(almSettingDto); | |||
verify(bitbucketServerRestClient, times(1)).validateUrl("http://abc.com"); | |||
verify(bitbucketServerRestClient, times(1)).validateToken("http://abc.com", "abc"); | |||
verify(bitbucketServerRestClient, times(1)).validateReadPermission("http://abc.com", "abc"); | |||
} | |||
@Test | |||
public void validate_failure_on_incomplete_configuration() { | |||
AlmSettingDto almSettingDto = newBitbucketAlmSettingDto() | |||
.setUrl(null) | |||
.setPersonalAccessToken("abc"); | |||
assertThatThrownBy(() -> underTest.validate(almSettingDto)) | |||
.isInstanceOf(IllegalArgumentException.class); | |||
} | |||
@Test | |||
public void validate_failure_on_bitbucket_server_api_error() { | |||
doThrow(new IllegalArgumentException("error")).when(bitbucketServerRestClient).validateUrl(anyString()); | |||
AlmSettingDto almSettingDto = newBitbucketAlmSettingDto() | |||
.setUrl("http://abc.com") | |||
.setPersonalAccessToken("abc"); | |||
assertThatThrownBy(() -> underTest.validate(almSettingDto)) | |||
.isInstanceOf(IllegalArgumentException.class); | |||
} | |||
} |
@@ -24,12 +24,13 @@ import org.junit.Test; | |||
import org.mockito.ArgumentCaptor; | |||
import org.sonar.alm.client.azure.AzureDevOpsHttpClient; | |||
import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudRestClient; | |||
import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient; | |||
import org.sonar.api.resources.ResourceTypes; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.alm.setting.ALM; | |||
import org.sonar.db.alm.setting.AlmSettingDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.almintegration.validator.BitbucketServerSettingsValidator; | |||
import org.sonar.server.almintegration.validator.GithubGlobalSettingsValidator; | |||
import org.sonar.server.almintegration.validator.GitlabGlobalSettingsValidator; | |||
import org.sonar.server.almsettings.MultipleAlmFeatureProvider; | |||
@@ -61,11 +62,11 @@ public class ValidateActionTest { | |||
private final AzureDevOpsHttpClient azureDevOpsHttpClient = mock(AzureDevOpsHttpClient.class); | |||
private final GitlabGlobalSettingsValidator gitlabSettingsValidator = mock(GitlabGlobalSettingsValidator.class); | |||
private final GithubGlobalSettingsValidator githubGlobalSettingsValidator = mock(GithubGlobalSettingsValidator.class); | |||
private final BitbucketServerRestClient bitbucketServerRestClient = mock(BitbucketServerRestClient.class); | |||
private final BitbucketServerSettingsValidator bitbucketServerSettingsValidator = mock(BitbucketServerSettingsValidator.class); | |||
private final BitbucketCloudRestClient bitbucketCloudRestClient = mock(BitbucketCloudRestClient.class); | |||
private final WsActionTester ws = new WsActionTester( | |||
new ValidateAction(db.getDbClient(), userSession, almSettingsSupport, azureDevOpsHttpClient, githubGlobalSettingsValidator, gitlabSettingsValidator, | |||
bitbucketServerRestClient, bitbucketCloudRestClient)); | |||
bitbucketServerSettingsValidator, bitbucketCloudRestClient)); | |||
@Test | |||
public void fail_when_key_does_not_match_existing_alm_setting() { | |||
@@ -126,9 +127,11 @@ public class ValidateActionTest { | |||
.setParam("key", almSetting.getKey()) | |||
.execute(); | |||
verify(bitbucketServerRestClient).validateUrl(almSetting.getUrl()); | |||
verify(bitbucketServerRestClient).validateToken(almSetting.getUrl(), almSetting.getPersonalAccessToken()); | |||
verify(bitbucketServerRestClient).validateReadPermission(almSetting.getUrl(), almSetting.getPersonalAccessToken()); | |||
ArgumentCaptor<AlmSettingDto> almSettingDtoArgumentCaptor = ArgumentCaptor.forClass(AlmSettingDto.class); | |||
verify(bitbucketServerSettingsValidator).validate(almSettingDtoArgumentCaptor.capture()); | |||
assertThat(almSettingDtoArgumentCaptor.getAllValues()).hasSize(1); | |||
assertThat(almSettingDtoArgumentCaptor.getValue().getKey()).isEqualTo(almSetting.getKey()); | |||
assertThat(almSettingDtoArgumentCaptor.getValue().getAlm()).isEqualTo(ALM.BITBUCKET); | |||
} | |||
@Test |