]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15323 - Allow encryption of Global DevOps Platform Settings
authorBelen Pruvost <belen.pruvost@sonarsource.com>
Wed, 25 Aug 2021 11:37:19 +0000 (13:37 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 30 Aug 2021 20:08:19 +0000 (20:08 +0000)
31 files changed:
server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java
server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/AlmSettingDaoTest.java
server/sonar-db-dao/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker [new file with mode: 0644]
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsTesting.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/validator/BitbucketServerSettingsValidator.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/validator/GithubGlobalSettingsValidator.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/validator/GitlabGlobalSettingsValidator.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ListGithubOrganizationsAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/UpdateAzureAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/UpdateBitbucketAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/UpdateBitbucketCloudAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/UpdateGithubAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/UpdateGitlabAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ValidateAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/validator/BitbucketServerSettingsValidatorTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/validator/GithubGlobalSettingsValidatorTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/validator/GitlabGlobalSettingsValidatorTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/azure/SearchAzureReposActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/github/ListGithubOrganizationsActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/CreateAzureActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/CreateBitbucketActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/CreateBitbucketCloudActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/CreateGithubActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/CreateGitlabActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/UpdateAzureActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/UpdateBitbucketActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/UpdateBitbucketCloudActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/UpdateGithubActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/UpdateGitlabActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ValidateActionTest.java

index 94a74ff68ed2308f4e801c198c95eee723404616..a6fa5aca298a71f440939053a1158e9736f6f4aa 100644 (file)
@@ -21,6 +21,9 @@ package org.sonar.db.alm.setting;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
+import org.sonar.api.config.internal.Encryption;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
 
 public class AlmSettingDto {
 
@@ -142,7 +145,10 @@ public class AlmSettingDto {
   }
 
   @CheckForNull
-  public String getPrivateKey() {
+  public String getDecryptedPrivateKey(Encryption encryption) {
+    if (!isNullOrEmpty(privateKey) && encryption.isEncrypted(privateKey)) {
+      return encryption.decrypt(privateKey);
+    }
     return privateKey;
   }
 
@@ -152,7 +158,10 @@ public class AlmSettingDto {
   }
 
   @CheckForNull
-  public String getPersonalAccessToken() {
+  public String getDecryptedPersonalAccessToken(Encryption encryption) {
+    if (!isNullOrEmpty(personalAccessToken) && encryption.isEncrypted(personalAccessToken)) {
+      return encryption.decrypt(personalAccessToken);
+    }
     return personalAccessToken;
   }
 
@@ -172,7 +181,10 @@ public class AlmSettingDto {
   }
 
   @CheckForNull
-  public String getClientSecret() {
+  public String getDecryptedClientSecret(Encryption encryption) {
+    if (!isNullOrEmpty(clientSecret) && encryption.isEncrypted(clientSecret)) {
+      return encryption.decrypt(clientSecret);
+    }
     return clientSecret;
   }
 
index acebd2bc6c5f4ee5665e4de9e2a49fa0e89615da..2ff6c75f8a28eb137f1d6eb67a590bd2a664f145 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.db.alm.setting;
 import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.impl.utils.TestSystem2;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.db.DbSession;
@@ -30,6 +31,7 @@ import org.sonar.db.almsettings.AlmSettingsTesting;
 import org.sonar.db.audit.NoOpAuditPersister;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.sonar.db.almsettings.AlmSettingsTesting.newGithubAlmSettingDto;
@@ -42,6 +44,8 @@ public class AlmSettingDaoTest {
   @Rule
   public DbTester db = DbTester.create(system2);
 
+  private final Encryption encryption = mock(Encryption.class);
+
   private DbSession dbSession = db.getSession();
   private UuidFactory uuidFactory = mock(UuidFactory.class);
 
@@ -50,17 +54,22 @@ public class AlmSettingDaoTest {
   @Test
   public void selectByUuid() {
     when(uuidFactory.create()).thenReturn(A_UUID);
+    when(encryption.isEncrypted(any())).thenReturn(false);
 
     AlmSettingDto almSettingDto = newGithubAlmSettingDto();
     underTest.insert(dbSession, almSettingDto);
 
     assertThat(underTest.selectByUuid(dbSession, A_UUID).get())
       .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl,
-        AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getPersonalAccessToken,
-        AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt)
+        AlmSettingDto::getAppId, AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt,
+        s -> almSettingDto.getDecryptedPrivateKey(encryption),
+        s -> almSettingDto.getDecryptedPersonalAccessToken(encryption),
+        s -> almSettingDto.getDecryptedClientSecret(encryption))
       .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(),
-        almSettingDto.getAppId(), almSettingDto.getPrivateKey(),
-        almSettingDto.getPersonalAccessToken(), NOW, NOW);
+        almSettingDto.getAppId(), NOW, NOW,
+        almSettingDto.getDecryptedPrivateKey(encryption),
+        almSettingDto.getDecryptedPersonalAccessToken(encryption),
+        almSettingDto.getDecryptedClientSecret(encryption));
 
     assertThat(underTest.selectByUuid(dbSession, "foo")).isNotPresent();
   }
@@ -68,17 +77,46 @@ public class AlmSettingDaoTest {
   @Test
   public void selectByKey() {
     when(uuidFactory.create()).thenReturn(A_UUID);
+    String decrypted = "decrypted";
+    when(encryption.isEncrypted(any())).thenReturn(true);
+    when(encryption.decrypt(any())).thenReturn(decrypted);
 
     AlmSettingDto almSettingDto = AlmSettingsTesting.newGithubAlmSettingDto();
     underTest.insert(dbSession, almSettingDto);
 
     assertThat(underTest.selectByKey(dbSession, almSettingDto.getKey()).get())
       .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl,
-        AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getPersonalAccessToken,
-        AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt)
+        AlmSettingDto::getAppId, AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt,
+        s -> almSettingDto.getDecryptedPrivateKey(encryption),
+        s -> almSettingDto.getDecryptedPersonalAccessToken(encryption),
+        s -> almSettingDto.getDecryptedClientSecret(encryption))
+      .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(),
+        almSettingDto.getAppId(), NOW, NOW,
+        almSettingDto.getDecryptedPrivateKey(encryption),
+        null,
+        almSettingDto.getDecryptedClientSecret(encryption));
+
+    assertThat(underTest.selectByKey(dbSession, "foo")).isNotPresent();
+  }
+
+  @Test
+  public void selectByKey_withEmptySecrets() {
+    when(uuidFactory.create()).thenReturn(A_UUID);
+    String decrypted = "decrypted";
+    when(encryption.isEncrypted(any())).thenReturn(true);
+    when(encryption.decrypt(any())).thenReturn(decrypted);
+
+    AlmSettingDto almSettingDto = AlmSettingsTesting.newAlmSettingDtoWithEmptySecrets();
+    underTest.insert(dbSession, almSettingDto);
+
+    assertThat(underTest.selectByKey(dbSession, almSettingDto.getKey()).get())
+      .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl,
+        AlmSettingDto::getAppId, AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt,
+        s -> almSettingDto.getDecryptedPrivateKey(encryption),
+        s -> almSettingDto.getDecryptedPersonalAccessToken(encryption),
+        s -> almSettingDto.getDecryptedClientSecret(encryption))
       .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(),
-        almSettingDto.getAppId(), almSettingDto.getPrivateKey(),
-        almSettingDto.getPersonalAccessToken(), NOW, NOW);
+        almSettingDto.getAppId(), NOW, NOW, null, null, null);
 
     assertThat(underTest.selectByKey(dbSession, "foo")).isNotPresent();
   }
@@ -127,11 +165,13 @@ public class AlmSettingDaoTest {
     AlmSettingDto result = underTest.selectByUuid(dbSession, A_UUID).get();
     assertThat(result)
       .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl,
-        AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getPersonalAccessToken,
+        AlmSettingDto::getAppId,
+        s -> almSettingDto.getDecryptedPrivateKey(encryption),
+        s -> almSettingDto.getDecryptedPersonalAccessToken(encryption),
         AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt)
       .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(),
-        almSettingDto.getAppId(), almSettingDto.getPrivateKey(),
-        almSettingDto.getPersonalAccessToken(), NOW, NOW + 1);
+        almSettingDto.getAppId(), almSettingDto.getDecryptedPrivateKey(encryption),
+        almSettingDto.getDecryptedPersonalAccessToken(encryption), NOW, NOW + 1);
   }
 
   @Test
diff --git a/server/sonar-db-dao/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/server/sonar-db-dao/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644 (file)
index 0000000..1f0955d
--- /dev/null
@@ -0,0 +1 @@
+mock-maker-inline
index 788caa61d2ce8c428d548030c202ffd50619f226..cd7fed0f18b17c1c6b22a9f94a6f784d597f478f 100644 (file)
@@ -40,6 +40,15 @@ public class AlmSettingsTesting {
       .setAlm(ALM.GITHUB);
   }
 
+  public static AlmSettingDto newAlmSettingDtoWithEmptySecrets() {
+    return new AlmSettingDto()
+      .setKey(randomAlphanumeric(200))
+      .setUrl(randomAlphanumeric(2000))
+      .setAppId(randomNumeric(8))
+      .setClientId(randomNumeric(8))
+      .setAlm(ALM.GITHUB);
+  }
+
   public static AlmSettingDto newAzureAlmSettingDto() {
     return new AlmSettingDto()
       .setKey(randomAlphanumeric(200))
index 334dde8d20643ac96c00735dbc5a551e7c478db8..b0e6e63c5581c35001be592f1fcb8492b61b30cc 100644 (file)
 package org.sonar.server.almintegration.validator;
 
 import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.server.ServerSide;
 import org.sonar.db.alm.setting.AlmSettingDto;
 
 @ServerSide
 public class BitbucketServerSettingsValidator {
   private final BitbucketServerRestClient bitbucketServerRestClient;
+  private final Encryption encryption;
 
-  public BitbucketServerSettingsValidator(BitbucketServerRestClient bitbucketServerRestClient) {
+  public BitbucketServerSettingsValidator(BitbucketServerRestClient bitbucketServerRestClient, Settings settings) {
     this.bitbucketServerRestClient = bitbucketServerRestClient;
+    this.encryption = settings.getEncryption();
   }
 
   public void validate(AlmSettingDto almSettingDto) {
     String bitbucketUrl = almSettingDto.getUrl();
-    String bitbucketToken = almSettingDto.getPersonalAccessToken();
+    String bitbucketToken = almSettingDto.getDecryptedPersonalAccessToken(encryption);
     if (bitbucketUrl == null || bitbucketToken == null) {
       throw new IllegalArgumentException("Your global Bitbucket Server configuration is incomplete.");
     }
index 6dd4c540d27dc4bef4f6d9e5efcfa7041510d961..56298ced863f808a7b53db1b5d7b91fd18b41367 100644 (file)
@@ -23,6 +23,8 @@ import java.util.Optional;
 import org.sonar.alm.client.github.GithubApplicationClient;
 import org.sonar.alm.client.github.GithubApplicationClientImpl;
 import org.sonar.alm.client.github.config.GithubAppConfiguration;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.server.ServerSide;
 import org.sonar.db.alm.setting.AlmSettingDto;
 
@@ -31,9 +33,11 @@ import static org.apache.commons.lang.StringUtils.isBlank;
 @ServerSide
 public class GithubGlobalSettingsValidator {
 
+  private final Encryption encryption;
   private final GithubApplicationClient githubApplicationClient;
 
-  public GithubGlobalSettingsValidator(GithubApplicationClientImpl githubApplicationClient) {
+  public GithubGlobalSettingsValidator(GithubApplicationClientImpl githubApplicationClient, Settings settings) {
+    this.encryption = settings.getEncryption();
     this.githubApplicationClient = githubApplicationClient;
   }
 
@@ -47,10 +51,11 @@ public class GithubGlobalSettingsValidator {
     if (isBlank(settings.getClientId())) {
       throw new IllegalArgumentException("Missing Client Id");
     }
-    if (isBlank(settings.getClientSecret())) {
+    if (isBlank(settings.getDecryptedClientSecret(encryption))) {
       throw new IllegalArgumentException("Missing Client Secret");
     }
-    GithubAppConfiguration configuration = new GithubAppConfiguration(appId, settings.getPrivateKey(), settings.getUrl());
+    GithubAppConfiguration configuration = new GithubAppConfiguration(appId, settings.getDecryptedPrivateKey(encryption),
+      settings.getUrl());
 
     githubApplicationClient.checkApiEndpoint(configuration);
     githubApplicationClient.checkAppPermissions(configuration);
index 40c4195e81b14386de1f45796d6ab4c048d0c26a..d6758b48201ea2492d65477c694ad054e9e759a9 100644 (file)
 package org.sonar.server.almintegration.validator;
 
 import org.sonar.alm.client.gitlab.GitlabHttpClient;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.server.ServerSide;
 import org.sonar.db.alm.setting.AlmSettingDto;
 
 @ServerSide
 public class GitlabGlobalSettingsValidator {
 
+  private final Encryption encryption;
   private final GitlabHttpClient gitlabHttpClient;
 
-  public GitlabGlobalSettingsValidator(GitlabHttpClient gitlabHttpClient) {
+  public GitlabGlobalSettingsValidator(GitlabHttpClient gitlabHttpClient, Settings settings) {
+    this.encryption = settings.getEncryption();
     this.gitlabHttpClient = gitlabHttpClient;
   }
 
   public void validate(AlmSettingDto almSettingDto) {
     String gitlabUrl = almSettingDto.getUrl();
-    String accessToken = almSettingDto.getPersonalAccessToken();
+    String accessToken = almSettingDto.getDecryptedPersonalAccessToken(encryption);
 
     if (gitlabUrl == null || accessToken == null) {
       throw new IllegalArgumentException("Your Gitlab global configuration is incomplete.");
index ec378fed13880a4011ddc12d41ffbdd0e60c31fe..64664859dfc03847aeb67c4e3149275de8b57186 100644 (file)
@@ -26,6 +26,8 @@ import org.sonar.alm.client.github.GithubApplicationClient.Organization;
 import org.sonar.alm.client.github.GithubApplicationClientImpl;
 import org.sonar.alm.client.github.security.AccessToken;
 import org.sonar.alm.client.github.security.UserAccessToken;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -53,11 +55,14 @@ public class ListGithubOrganizationsAction implements AlmIntegrationsWsAction {
   public static final String PARAM_TOKEN = "token";
 
   private final DbClient dbClient;
+  private final Encryption encryption;
   private final UserSession userSession;
   private final GithubApplicationClient githubApplicationClient;
 
-  public ListGithubOrganizationsAction(DbClient dbClient, UserSession userSession, GithubApplicationClientImpl githubApplicationClient) {
+  public ListGithubOrganizationsAction(DbClient dbClient, Settings settings, UserSession userSession,
+    GithubApplicationClientImpl githubApplicationClient) {
     this.dbClient = dbClient;
+    this.encryption = settings.getEncryption();
     this.userSession = userSession;
     this.githubApplicationClient = githubApplicationClient;
   }
@@ -109,7 +114,8 @@ public class ListGithubOrganizationsAction implements AlmIntegrationsWsAction {
       if (request.hasParam(PARAM_TOKEN)) {
         String code = request.mandatoryParam(PARAM_TOKEN);
         String clientId = requireNonNull(almSettingDto.getClientId(), String.format("No clientId set for GitHub ALM '%s'", almSettingKey));
-        String clientSecret = requireNonNull(almSettingDto.getClientSecret(), String.format("No clientSecret set for GitHub ALM '%s'", almSettingKey));
+        String clientSecret = requireNonNull(almSettingDto.getDecryptedClientSecret(encryption), String.format("No clientSecret set for GitHub ALM '%s'",
+          almSettingKey));
 
         try {
           accessToken = githubApplicationClient.createUserAccessToken(url, clientId, clientSecret, code);
index 111f6306dafc9feb6bccda3b3e137b66bcb1cc2e..700bc9eefa23ffe8f22ba839136a8ce0052ad1f7 100644 (file)
@@ -94,9 +94,13 @@ public class UpdateAzureAction implements AlmSettingsWsAction {
       if (isNotBlank(newKey) && !newKey.equals(key)) {
         almSettingsSupport.checkAlmSettingDoesNotAlreadyExist(dbSession, newKey);
       }
+
+      if (isNotBlank(pat)) {
+        almSettingDto.setPersonalAccessToken(pat);
+      }
+
       dbClient.almSettingDao().update(dbSession, almSettingDto
         .setKey(isNotBlank(newKey) ? newKey : key)
-        .setPersonalAccessToken(isNotBlank(pat) ? pat : almSettingDto.getPersonalAccessToken())
         .setUrl(url),
         pat != null);
       dbSession.commit();
index 811621fb64c939693dd0e871189cf8b0f2a5b086..2fb0ad70a3f7b3bf7a7cdb83fae0a957df43429d 100644 (file)
@@ -93,10 +93,14 @@ public class UpdateBitbucketAction implements AlmSettingsWsAction {
       if (isNotBlank(newKey) && !newKey.equals(key)) {
         almSettingsSupport.checkAlmSettingDoesNotAlreadyExist(dbSession, newKey);
       }
+
+      if (isNotBlank(pat)) {
+        almSettingDto.setPersonalAccessToken(pat);
+      }
+
       dbClient.almSettingDao().update(dbSession, almSettingDto
         .setKey(isNotBlank(newKey) ? newKey : key)
-        .setUrl(url)
-        .setPersonalAccessToken(isNotBlank(pat) ? pat : almSettingDto.getPersonalAccessToken()),
+        .setUrl(url),
         pat != null);
       dbSession.commit();
     }
index 1f00edcec0fe3a2d2b4a58a559cba7b2c9471521..1141bc58b2a5ba0fc0e4d79d1d781d6e102c0702 100644 (file)
@@ -96,11 +96,15 @@ public class UpdateBitbucketCloudAction implements AlmSettingsWsAction {
       if (isNotBlank(newKey) && !newKey.equals(key)) {
         almSettingsSupport.checkAlmSettingDoesNotAlreadyExist(dbSession, newKey);
       }
+
+      if (isNotBlank(clientSecret)) {
+        almSettingDto.setClientSecret(clientSecret);
+      }
+
       dbClient.almSettingDao().update(dbSession, almSettingDto
         .setKey(isNotBlank(newKey) ? newKey : key)
         .setClientId(clientId)
-        .setAppId(workspace)
-        .setClientSecret(isNotBlank(clientSecret) ? clientSecret : almSettingDto.getClientSecret()),
+        .setAppId(workspace),
         clientSecret != null);
       dbSession.commit();
     }
index 275b4f26f9f0db4dcae4b64415ce0205c439a928..9525bc70a1eef6801c96906a91d74782459124a3 100644 (file)
@@ -116,13 +116,20 @@ public class UpdateGithubAction implements AlmSettingsWsAction {
       if (isNotBlank(newKey) && !newKey.equals(key)) {
         almSettingsSupport.checkAlmSettingDoesNotAlreadyExist(dbSession, newKey);
       }
+
+      if (isNotBlank(privateKey)) {
+        almSettingDto.setPrivateKey(privateKey);
+      }
+
+      if (isNotBlank(clientSecret)) {
+        almSettingDto.setClientSecret(clientSecret);
+      }
+
       dbClient.almSettingDao().update(dbSession, almSettingDto
-        .setKey(isNotBlank(newKey) ? newKey : key)
-        .setUrl(url)
-        .setAppId(appId)
-        .setPrivateKey(isNotBlank(privateKey) ? privateKey : almSettingDto.getPrivateKey())
-        .setClientId(clientId)
-        .setClientSecret(isNotBlank(clientSecret) ? clientSecret : almSettingDto.getClientSecret()),
+          .setKey(isNotBlank(newKey) ? newKey : key)
+          .setUrl(url)
+          .setAppId(appId)
+          .setClientId(clientId),
         clientSecret != null || privateKey != null);
       dbSession.commit();
     }
index 2ef16921f0087f7acedc6597d7f4328ca9aa694f..4766e6794c7de9983d1f67b1e0ccbbddc3b5e60e 100644 (file)
@@ -95,10 +95,14 @@ public class UpdateGitlabAction implements AlmSettingsWsAction {
       if (isNotBlank(newKey) && !newKey.equals(key)) {
         almSettingsSupport.checkAlmSettingDoesNotAlreadyExist(dbSession, newKey);
       }
+
+      if (isNotBlank(pat)) {
+        almSettingDto.setPersonalAccessToken(pat);
+      }
+
       dbClient.almSettingDao().update(dbSession, almSettingDto
         .setKey(isNotBlank(newKey) ? newKey : key)
-        .setUrl(url)
-        .setPersonalAccessToken(isNotBlank(pat) ? pat : almSettingDto.getPersonalAccessToken()),
+        .setUrl(url),
         pat != null);
       dbSession.commit();
     }
index 24ce864f687f927ac09aafbf04f201ffee0eff1f..4e98da5649acbb40ae5d334b253f8c360407bad7 100644 (file)
@@ -21,6 +21,8 @@ package org.sonar.server.almsettings.ws;
 
 import org.sonar.alm.client.azure.AzureDevOpsHttpClient;
 import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudRestClient;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -37,6 +39,7 @@ public class ValidateAction implements AlmSettingsWsAction {
   private static final String PARAM_KEY = "key";
 
   private final DbClient dbClient;
+  private final Encryption encryption;
   private final UserSession userSession;
   private final AlmSettingsSupport almSettingsSupport;
   private final AzureDevOpsHttpClient azureDevOpsHttpClient;
@@ -46,6 +49,7 @@ public class ValidateAction implements AlmSettingsWsAction {
   private final BitbucketCloudRestClient bitbucketCloudRestClient;
 
   public ValidateAction(DbClient dbClient,
+    Settings settings,
     UserSession userSession,
     AlmSettingsSupport almSettingsSupport,
     AzureDevOpsHttpClient azureDevOpsHttpClient,
@@ -54,6 +58,7 @@ public class ValidateAction implements AlmSettingsWsAction {
     BitbucketServerSettingsValidator bitbucketServerSettingsValidator,
     BitbucketCloudRestClient bitbucketCloudRestClient) {
     this.dbClient = dbClient;
+    this.encryption = settings.getEncryption();
     this.userSession = userSession;
     this.almSettingsSupport = almSettingsSupport;
     this.azureDevOpsHttpClient = azureDevOpsHttpClient;
@@ -111,13 +116,13 @@ public class ValidateAction implements AlmSettingsWsAction {
 
   private void validateAzure(AlmSettingDto almSettingDto) {
     try {
-      azureDevOpsHttpClient.checkPAT(almSettingDto.getUrl(), almSettingDto.getPersonalAccessToken());
+      azureDevOpsHttpClient.checkPAT(almSettingDto.getUrl(), almSettingDto.getDecryptedPersonalAccessToken(encryption));
     } catch (IllegalArgumentException e) {
       throw new IllegalArgumentException("Invalid Azure URL or Personal Access Token", e);
     }
   }
 
   private void validateBitbucketCloud(AlmSettingDto almSettingDto) {
-    bitbucketCloudRestClient.validate(almSettingDto.getClientId(), almSettingDto.getClientSecret(), almSettingDto.getAppId());
+    bitbucketCloudRestClient.validate(almSettingDto.getClientId(), almSettingDto.getDecryptedClientSecret(encryption), almSettingDto.getAppId());
   }
 }
index 9122af01a0887c1fe9fbee2a063f0b892de2d55e..e8644877c1cf9e47e43a605abbc10d8c0111ae24 100644 (file)
  */
 package org.sonar.server.almintegration.validator;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.db.alm.setting.AlmSettingDto;
 
 import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
 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.mockito.Mockito.when;
 import static org.sonar.db.almsettings.AlmSettingsTesting.newBitbucketAlmSettingDto;
 
 public class BitbucketServerSettingsValidatorTest {
+  private static final Encryption encryption = mock(Encryption.class);
+  private static final Settings settings = mock(Settings.class);
 
   private final BitbucketServerRestClient bitbucketServerRestClient = mock(BitbucketServerRestClient.class);
-  private final BitbucketServerSettingsValidator underTest = new BitbucketServerSettingsValidator(bitbucketServerRestClient);
+  private final BitbucketServerSettingsValidator underTest = new BitbucketServerSettingsValidator(bitbucketServerRestClient, settings);
+
+  @BeforeClass
+  public static void setUp() {
+    when(settings.getEncryption()).thenReturn(encryption);
+  }
 
   @Test
   public void validate_success() {
     AlmSettingDto almSettingDto = newBitbucketAlmSettingDto()
       .setUrl("http://abc.com")
       .setPersonalAccessToken("abc");
+    when(encryption.isEncrypted(any())).thenReturn(false);
 
     underTest.validate(almSettingDto);
 
@@ -49,6 +62,23 @@ public class BitbucketServerSettingsValidatorTest {
     verify(bitbucketServerRestClient, times(1)).validateReadPermission("http://abc.com", "abc");
   }
 
+  @Test
+  public void validate_success_with_encrypted_token() {
+    String encryptedToken = "abc";
+    String decryptedToken = "decrypted-token";
+    AlmSettingDto almSettingDto = newBitbucketAlmSettingDto()
+      .setUrl("http://abc.com")
+      .setPersonalAccessToken(encryptedToken);
+    when(encryption.isEncrypted(encryptedToken)).thenReturn(true);
+    when(encryption.decrypt(encryptedToken)).thenReturn(decryptedToken);
+
+    underTest.validate(almSettingDto);
+
+    verify(bitbucketServerRestClient, times(1)).validateUrl("http://abc.com");
+    verify(bitbucketServerRestClient, times(1)).validateToken("http://abc.com", decryptedToken);
+    verify(bitbucketServerRestClient, times(1)).validateReadPermission("http://abc.com", decryptedToken);
+  }
+
   @Test
   public void validate_failure_on_incomplete_configuration() {
     AlmSettingDto almSettingDto = newBitbucketAlmSettingDto()
index efc2679fe28dfa3ad8dbc4717997640101d2189b..5c3d274a65b94c4d79c96bac8fac398f678fac1d 100644 (file)
  */
 package org.sonar.server.almintegration.validator;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.alm.client.github.GithubApplicationClientImpl;
 import org.sonar.alm.client.github.config.GithubAppConfiguration;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.db.alm.setting.AlmSettingDto;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.sonar.db.almsettings.AlmSettingsTesting.newGithubAlmSettingDto;
 
 public class GithubGlobalSettingsValidatorTest {
+  private static final Encryption encryption = mock(Encryption.class);
+  private static final Settings settings = mock(Settings.class);
+
   private final GithubApplicationClientImpl appClient = mock(GithubApplicationClientImpl.class);
-  private final GithubGlobalSettingsValidator underTest = new GithubGlobalSettingsValidator(appClient);
+  private final GithubGlobalSettingsValidator underTest = new GithubGlobalSettingsValidator(appClient, settings);
+
+  @BeforeClass
+  public static void setUp() {
+    when(settings.getEncryption()).thenReturn(encryption);
+  }
 
   @Test
   public void github_global_settings_validation() {
     AlmSettingDto almSettingDto = newGithubAlmSettingDto()
       .setClientId("clientId")
       .setClientSecret("clientSecret");
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
+    GithubAppConfiguration configuration = underTest.validate(almSettingDto);
+
+    ArgumentCaptor<GithubAppConfiguration> configurationArgumentCaptor = ArgumentCaptor.forClass(GithubAppConfiguration.class);
+    verify(appClient).checkApiEndpoint(configurationArgumentCaptor.capture());
+    verify(appClient).checkAppPermissions(configurationArgumentCaptor.capture());
+    assertThat(configuration.getId()).isEqualTo(configurationArgumentCaptor.getAllValues().get(0).getId());
+    assertThat(configuration.getId()).isEqualTo(configurationArgumentCaptor.getAllValues().get(1).getId());
+  }
+
+  @Test
+  public void github_global_settings_validation_with_encrypted_key() {
+    String encryptedKey = "encrypted-key";
+    String decryptedKey = "decrypted-key";
+    AlmSettingDto almSettingDto = newGithubAlmSettingDto()
+      .setClientId("clientId")
+      .setPrivateKey(encryptedKey)
+      .setClientSecret("clientSecret");
+    when(encryption.isEncrypted(encryptedKey)).thenReturn(true);
+    when(encryption.decrypt(encryptedKey)).thenReturn(decryptedKey);
 
     GithubAppConfiguration configuration = underTest.validate(almSettingDto);
 
@@ -47,7 +81,9 @@ public class GithubGlobalSettingsValidatorTest {
     verify(appClient).checkApiEndpoint(configurationArgumentCaptor.capture());
     verify(appClient).checkAppPermissions(configurationArgumentCaptor.capture());
     assertThat(configuration.getId()).isEqualTo(configurationArgumentCaptor.getAllValues().get(0).getId());
+    assertThat(decryptedKey).isEqualTo(configurationArgumentCaptor.getAllValues().get(0).getPrivateKey());
     assertThat(configuration.getId()).isEqualTo(configurationArgumentCaptor.getAllValues().get(1).getId());
+    assertThat(decryptedKey).isEqualTo(configurationArgumentCaptor.getAllValues().get(1).getPrivateKey());
   }
 
   @Test
index 1e16fef29fa427e2ee7a70fec30746ad22a17710..186b671ed2f1aeb118f53ce0da23020fbff77cb8 100644 (file)
  */
 package org.sonar.server.almintegration.validator;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.sonar.alm.client.gitlab.GitlabHttpClient;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.db.alm.setting.AlmSettingDto;
 
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class GitlabGlobalSettingsValidatorTest {
+  private static final Encryption encryption = mock(Encryption.class);
+  private static final Settings settings = mock(Settings.class);
 
   private final GitlabHttpClient gitlabHttpClient = mock(GitlabHttpClient.class);
 
-  private final GitlabGlobalSettingsValidator underTest = new GitlabGlobalSettingsValidator(gitlabHttpClient);
+  private final GitlabGlobalSettingsValidator underTest = new GitlabGlobalSettingsValidator(gitlabHttpClient, settings);
+
+  @BeforeClass
+  public static void setUp() {
+    when(settings.getEncryption()).thenReturn(encryption);
+  }
 
   @Test
   public void validate_success() {
+    String token = "personal-access-token";
     AlmSettingDto almSettingDto = new AlmSettingDto()
       .setUrl("https://gitlab.com/api")
       .setPersonalAccessToken("personal-access-token");
+    when(encryption.isEncrypted(token)).thenReturn(false);
+
+    underTest.validate(almSettingDto);
+    verify(gitlabHttpClient, times(1)).checkUrl(almSettingDto.getUrl());
+    verify(gitlabHttpClient, times(1)).checkToken(almSettingDto.getUrl(), almSettingDto.getDecryptedPersonalAccessToken(encryption));
+    verify(gitlabHttpClient, times(1)).checkReadPermission(almSettingDto.getUrl(), almSettingDto.getDecryptedPersonalAccessToken(encryption));
+    verify(gitlabHttpClient, times(1)).checkWritePermission(almSettingDto.getUrl(), almSettingDto.getDecryptedPersonalAccessToken(encryption));
+  }
+
+  @Test
+  public void validate_success_with_encrypted_token() {
+    String encryptedToken = "personal-access-token";
+    String decryptedToken = "decrypted-token";
+    AlmSettingDto almSettingDto = new AlmSettingDto()
+      .setUrl("https://gitlab.com/api")
+      .setPersonalAccessToken(encryptedToken);
+    when(encryption.isEncrypted(encryptedToken)).thenReturn(true);
+    when(encryption.decrypt(encryptedToken)).thenReturn(decryptedToken);
 
     underTest.validate(almSettingDto);
+
+    verify(gitlabHttpClient, times(1)).checkUrl(almSettingDto.getUrl());
+    verify(gitlabHttpClient, times(1)).checkToken(almSettingDto.getUrl(), decryptedToken);
+    verify(gitlabHttpClient, times(1)).checkReadPermission(almSettingDto.getUrl(), decryptedToken);
+    verify(gitlabHttpClient, times(1)).checkWritePermission(almSettingDto.getUrl(), decryptedToken);
   }
 
   @Test
index 8d7610b206be8fc14723b0520625918f1b93ec28..bd3b59262983d6d064de1cdf25c5f68c1597f224 100644 (file)
@@ -28,6 +28,7 @@ import org.junit.Test;
 import org.sonar.alm.client.azure.AzureDevOpsHttpClient;
 import org.sonar.alm.client.azure.GsonAzureProject;
 import org.sonar.alm.client.azure.GsonAzureRepo;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.core.i18n.I18n;
@@ -78,6 +79,7 @@ public class ImportAzureProjectActionTest {
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestProjectIndexers(), new SequenceUuidFactory());
 
+  private final Encryption encryption = mock(Encryption.class);
   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
   private final ProjectDefaultVisibility projectDefaultVisibility = mock(ProjectDefaultVisibility.class);
   private final ImportAzureProjectAction importAzureProjectAction = new ImportAzureProjectAction(db.getDbClient(), userSession,
@@ -96,11 +98,12 @@ public class ImportAzureProjectActionTest {
     AlmSettingDto almSetting = db.almSettings().insertAzureAlmSetting();
     db.almPats().insert(dto -> {
       dto.setAlmSettingUuid(almSetting.getUuid());
-      dto.setPersonalAccessToken(almSetting.getPersonalAccessToken());
+      dto.setPersonalAccessToken(almSetting.getDecryptedPersonalAccessToken(encryption));
       dto.setUserUuid(user.getUuid());
     });
     GsonAzureRepo repo = getGsonAzureRepo();
-    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getPersonalAccessToken(), "project-name", "repo-name"))
+    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getDecryptedPersonalAccessToken(encryption),
+      "project-name", "repo-name"))
       .thenReturn(repo);
 
     Projects.CreateWsResponse response = ws.newRequest()
@@ -138,11 +141,12 @@ public class ImportAzureProjectActionTest {
     AlmSettingDto almSetting = db.almSettings().insertAzureAlmSetting();
     db.almPats().insert(dto -> {
       dto.setAlmSettingUuid(almSetting.getUuid());
-      dto.setPersonalAccessToken(almSetting.getPersonalAccessToken());
+      dto.setPersonalAccessToken(almSetting.getDecryptedPersonalAccessToken(encryption));
       dto.setUserUuid(user.getUuid());
     });
     GsonAzureRepo repo = getEmptyGsonAzureRepo();
-    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getPersonalAccessToken(), "project-name", "repo-name"))
+    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getDecryptedPersonalAccessToken(encryption),
+      "project-name", "repo-name"))
       .thenReturn(repo);
 
     Projects.CreateWsResponse response = ws.newRequest()
@@ -228,14 +232,15 @@ public class ImportAzureProjectActionTest {
     AlmSettingDto almSetting = db.almSettings().insertAzureAlmSetting();
     db.almPats().insert(dto -> {
       dto.setAlmSettingUuid(almSetting.getUuid());
-      dto.setPersonalAccessToken(almSetting.getPersonalAccessToken());
+      dto.setPersonalAccessToken(almSetting.getDecryptedPersonalAccessToken(encryption));
       dto.setUserUuid(user.getUuid());
     });
     GsonAzureRepo repo = getGsonAzureRepo();
     String projectKey = repo.getProject().getName() + "_" + repo.getName();
     db.components().insertPublicProject(p -> p.setDbKey(projectKey));
 
-    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getPersonalAccessToken(), "project-name", "repo-name")).thenReturn(repo);
+    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getDecryptedPersonalAccessToken(encryption),
+      "project-name", "repo-name")).thenReturn(repo);
     TestRequest request = ws.newRequest()
       .setParam("almSetting", almSetting.getKey())
       .setParam("projectName", "project-name")
index 7918962abd5f6bb1abaa611658fff2bce064edae..792d279205bc6fe80a6cdb5541333a9c13418efd 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.alm.client.azure.AzureDevOpsHttpClient;
 import org.sonar.alm.client.azure.GsonAzureProject;
 import org.sonar.alm.client.azure.GsonAzureRepo;
 import org.sonar.alm.client.azure.GsonAzureRepoList;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.pat.AlmPatDto;
@@ -60,8 +61,9 @@ public class SearchAzureReposActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private AzureDevOpsHttpClient azureDevOpsHttpClient = mock(AzureDevOpsHttpClient.class);
-  private WsActionTester ws = new WsActionTester(new SearchAzureReposAction(db.getDbClient(), userSession, azureDevOpsHttpClient));
+  private final AzureDevOpsHttpClient azureDevOpsHttpClient = mock(AzureDevOpsHttpClient.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final WsActionTester ws = new WsActionTester(new SearchAzureReposAction(db.getDbClient(), userSession, azureDevOpsHttpClient));
 
   @Before
   public void before() {
@@ -347,7 +349,7 @@ public class SearchAzureReposActionTest {
     db.almPats().insert(dto -> {
       dto.setAlmSettingUuid(almSetting.getUuid());
       dto.setUserUuid(user.getUuid());
-      dto.setPersonalAccessToken(almSetting.getPersonalAccessToken());
+      dto.setPersonalAccessToken(almSetting.getDecryptedPersonalAccessToken(encryption));
     });
     return almSetting;
   }
index 7bca0e3af5ec913569638417996d847ec0f50b80..32945d45ce8ae1f710ad3653426eb3aa2c8cd914 100644 (file)
@@ -21,12 +21,15 @@ package org.sonar.server.almintegration.ws.github;
 
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.sonar.alm.client.github.GithubApplicationClient;
 import org.sonar.alm.client.github.GithubApplicationClientImpl;
 import org.sonar.alm.client.github.security.UserAccessToken;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.pat.AlmPatDto;
@@ -58,6 +61,8 @@ import static org.sonar.server.almintegration.ws.github.ListGithubOrganizationsA
 import static org.sonar.server.tester.UserSessionRule.standalone;
 
 public class ListGithubOrganizationsActionTest {
+  private static final Encryption encryption = mock(Encryption.class);
+  private static final Settings settings = mock(Settings.class);
 
   @Rule
   public UserSessionRule userSession = standalone();
@@ -68,7 +73,12 @@ public class ListGithubOrganizationsActionTest {
   @Rule
   public DbTester db = DbTester.create(system2);
 
-  private final WsActionTester ws = new WsActionTester(new ListGithubOrganizationsAction(db.getDbClient(), userSession, appClient));
+  private final WsActionTester ws = new WsActionTester(new ListGithubOrganizationsAction(db.getDbClient(), settings, userSession, appClient));
+
+  @BeforeClass
+  public static void setUp() {
+    when(settings.getEncryption()).thenReturn(encryption);
+  }
 
   @Test
   public void fail_when_missing_create_project_permission() {
@@ -91,7 +101,8 @@ public class ListGithubOrganizationsActionTest {
   @Test
   public void fail_when_unable_to_create_personal_access_token() {
     AlmSettingDto githubAlmSetting = setupAlm();
-    when(appClient.createUserAccessToken(githubAlmSetting.getUrl(), githubAlmSetting.getClientId(), githubAlmSetting.getClientSecret(), "abc"))
+    when(appClient.createUserAccessToken(githubAlmSetting.getUrl(), githubAlmSetting.getClientId(),
+      githubAlmSetting.getDecryptedClientSecret(encryption), "abc"))
       .thenThrow(IllegalStateException.class);
     TestRequest request = ws.newRequest()
       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
@@ -105,7 +116,8 @@ public class ListGithubOrganizationsActionTest {
   @Test
   public void fail_create_personal_access_token_because_of_invalid_settings() {
     AlmSettingDto githubAlmSetting = setupAlm();
-    when(appClient.createUserAccessToken(githubAlmSetting.getUrl(), githubAlmSetting.getClientId(), githubAlmSetting.getClientSecret(), "abc"))
+    when(appClient.createUserAccessToken(githubAlmSetting.getUrl(), githubAlmSetting.getClientId(),
+      githubAlmSetting.getDecryptedClientSecret(encryption), "abc"))
       .thenThrow(IllegalArgumentException.class);
     TestRequest request = ws.newRequest()
       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
@@ -130,8 +142,42 @@ public class ListGithubOrganizationsActionTest {
   public void return_organizations_and_store_personal_access_token() {
     UserAccessToken accessToken = new UserAccessToken("token_for_abc");
     AlmSettingDto githubAlmSettings = setupAlm();
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
+    when(appClient.createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(),
+      githubAlmSettings.getDecryptedClientSecret(encryption), "abc"))
+      .thenReturn(accessToken);
+    setupGhOrganizations(githubAlmSettings, accessToken.getValue());
+
+    ListGithubOrganizationsWsResponse response = ws.newRequest()
+      .setParam(PARAM_ALM_SETTING, githubAlmSettings.getKey())
+      .setParam(PARAM_TOKEN, "abc")
+      .executeProtobuf(ListGithubOrganizationsWsResponse.class);
+
+    assertThat(response.getPaging())
+      .extracting(Common.Paging::getPageIndex, Common.Paging::getPageSize, Common.Paging::getTotal)
+      .containsOnly(1, 100, 2);
+    assertThat(response.getOrganizationsList())
+      .extracting(GithubOrganization::getKey, GithubOrganization::getName)
+      .containsOnly(tuple("github", "github"), tuple("octacat", "octacat"));
+
+    verify(appClient).createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(),
+      githubAlmSettings.getDecryptedClientSecret(encryption), "abc");
+    verify(appClient).listOrganizations(githubAlmSettings.getUrl(), accessToken, 1, 100);
+    Mockito.verifyNoMoreInteractions(appClient);
+    assertThat(db.getDbClient().almPatDao().selectByUserAndAlmSetting(db.getSession(), userSession.getUuid(), githubAlmSettings).get().getPersonalAccessToken())
+      .isEqualTo(accessToken.getValue());
+  }
+
+  @Test
+  public void return_organizations_and_store_personal_access_token_with_encrypted_client_secret() {
+    String decryptedSecret = "decrypted-secret";
+    UserAccessToken accessToken = new UserAccessToken("token_for_abc");
+    AlmSettingDto githubAlmSettings = setupAlm();
+    when(encryption.isEncrypted(any())).thenReturn(true);
+    when(encryption.decrypt(any())).thenReturn(decryptedSecret);
 
-    when(appClient.createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(), githubAlmSettings.getClientSecret(), "abc"))
+    when(appClient.createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(), decryptedSecret, "abc"))
       .thenReturn(accessToken);
     setupGhOrganizations(githubAlmSettings, accessToken.getValue());
 
@@ -147,7 +193,7 @@ public class ListGithubOrganizationsActionTest {
       .extracting(GithubOrganization::getKey, GithubOrganization::getName)
       .containsOnly(tuple("github", "github"), tuple("octacat", "octacat"));
 
-    verify(appClient).createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(), githubAlmSettings.getClientSecret(), "abc");
+    verify(appClient).createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(), decryptedSecret, "abc");
     verify(appClient).listOrganizations(githubAlmSettings.getUrl(), accessToken, 1, 100);
     Mockito.verifyNoMoreInteractions(appClient);
     assertThat(db.getDbClient().almPatDao().selectByUserAndAlmSetting(db.getSession(), userSession.getUuid(), githubAlmSettings).get().getPersonalAccessToken())
@@ -163,7 +209,8 @@ public class ListGithubOrganizationsActionTest {
 
     // new pat
     UserAccessToken accessToken = new UserAccessToken("token_for_abc");
-    when(appClient.createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(), githubAlmSettings.getClientSecret(), "abc"))
+    when(appClient.createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(),
+      githubAlmSettings.getDecryptedClientSecret(encryption), "abc"))
       .thenReturn(accessToken);
     setupGhOrganizations(githubAlmSettings, accessToken.getValue());
 
@@ -179,7 +226,8 @@ public class ListGithubOrganizationsActionTest {
       .extracting(GithubOrganization::getKey, GithubOrganization::getName)
       .containsOnly(tuple("github", "github"), tuple("octacat", "octacat"));
 
-    verify(appClient).createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(), githubAlmSettings.getClientSecret(), "abc");
+    verify(appClient).createUserAccessToken(githubAlmSettings.getUrl(), githubAlmSettings.getClientId(),
+      githubAlmSettings.getDecryptedClientSecret(encryption), "abc");
     verify(appClient).listOrganizations(eq(githubAlmSettings.getUrl()), argThat(token -> token.getValue().equals(accessToken.getValue())), eq(1), eq(100));
     Mockito.verifyNoMoreInteractions(appClient);
     assertThat(db.getDbClient().almPatDao().selectByUserAndAlmSetting(db.getSession(), userSession.getUuid(), githubAlmSettings).get().getPersonalAccessToken())
index ad9fb29acc9421572c9ce1e588794cd10eaa04d0..da14c3f8473a3b1f11ae9438bd6c730c3f9bfcab 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -48,7 +49,8 @@ public class CreateAzureActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
 
   private WsActionTester ws = new WsActionTester(new CreateAzureAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
@@ -71,7 +73,9 @@ public class CreateAzureActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getPersonalAccessToken, AlmSettingDto::getUrl)
+      .extracting(AlmSettingDto::getKey,
+        s -> s.getDecryptedPersonalAccessToken(encryption),
+        AlmSettingDto::getUrl)
       .containsOnly(tuple("Azure Server - Dev Team", "98765432100", "https://ado.sonarqube.com/"));
   }
 
index ae8fe639867cd04eeaab5fc3e0081bd70f9b88dd..d899ddadd273b67f86cb983d21767a8a79276f59 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -48,7 +49,8 @@ public class CreateBitbucketActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
 
   private WsActionTester ws = new WsActionTester(new CreateBitBucketAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
@@ -71,7 +73,7 @@ public class CreateBitbucketActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple("Bitbucket Server - Dev Team", "https://bitbucket.enterprise.com", "98765432100"));
   }
 
index 769a4db66b04734debf27e35a69f8de9effcf11a..cb7f30be4be2df4ea13e444557d3e9de82a3c7d1 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -48,7 +49,8 @@ public class CreateBitbucketCloudActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
 
   private WsActionTester ws = new WsActionTester(new CreateBitbucketCloudAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
@@ -72,7 +74,7 @@ public class CreateBitbucketCloudActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret, AlmSettingDto::getAppId)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption), AlmSettingDto::getAppId)
       .containsOnly(tuple("Bitbucket Server - Dev Team", "id", "secret", "workspace1"));
   }
 
index d5f93eeae7035bba6134543c9697366f04c62a1a..6ab9d86a4334820483ae060b1d54397a778a8891 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -48,7 +49,8 @@ public class CreateGithubActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
 
   private WsActionTester ws = new WsActionTester(new CreateGithubAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
@@ -74,7 +76,8 @@ public class CreateGithubActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId,
+        s -> s.getDecryptedPrivateKey(encryption), AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption))
       .containsOnly(tuple("GitHub Server - Dev Team", "https://github.enterprise.com", "12345", "678910", "client_1234", "client_so_secret"));
   }
 
@@ -93,7 +96,8 @@ public class CreateGithubActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId,
+        s -> s.getDecryptedPrivateKey(encryption), AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption))
       .containsOnly(tuple("GitHub Server - Dev Team", "https://github.enterprise.com", "12345", "678910", "client_1234", "client_so_secret"));
   }
 
index 7323ec7f2f1de12150a11f454832267e2f8f8491..e1cf4fd2e0675995585bdc3ae4e8751499e0fa2a 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -52,7 +53,8 @@ public class CreateGitlabActionTest {
 
   private static String GITLAB_URL = "gitlab.com/api/v4";
 
-  private MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
 
   private WsActionTester ws = new WsActionTester(new CreateGitlabAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null), multipleAlmFeatureProvider)));
@@ -88,7 +90,7 @@ public class CreateGitlabActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple("Gitlab - Dev Team", GITLAB_URL, "98765432100"));
   }
 
index 9d4908802edc19640b777a75bfc7186215e167af..d26e59986e541220b38215dd3d4714a61c605a94 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.almsettings.ws;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -49,6 +50,8 @@ public class UpdateAzureActionTest {
 
   private static String AZURE_URL = "https://ado.sonarqube.com/";
 
+  private final Encryption encryption = mock(Encryption.class);
+
   private WsActionTester ws = new WsActionTester(new UpdateAzureAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
       mock(MultipleAlmFeatureProvider.class))));
@@ -66,7 +69,7 @@ public class UpdateAzureActionTest {
       .setParam("url", AZURE_URL)
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple(almSettingDto.getKey(), AZURE_URL, "10987654321"));
   }
 
@@ -84,7 +87,7 @@ public class UpdateAzureActionTest {
       .setParam("url", AZURE_URL)
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple("Azure Server - Infra Team", AZURE_URL, "0123456789"));
   }
 
@@ -100,8 +103,8 @@ public class UpdateAzureActionTest {
       .setParam("url", AZURE_URL)
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
-      .containsOnly(tuple(almSettingDto.getKey(), AZURE_URL, almSettingDto.getPersonalAccessToken()));
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
+      .containsOnly(tuple(almSettingDto.getKey(), AZURE_URL, almSettingDto.getDecryptedPersonalAccessToken(encryption)));
   }
 
   @Test
index f05b53c083f15e6264f5e70385fb26d637a1545d..19927eb0fa6ab88bfb33763b678784ae9cdc9501 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.almsettings.ws;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -47,6 +48,8 @@ public class UpdateBitbucketActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
+  private final Encryption encryption = mock(Encryption.class);
+
   private WsActionTester ws = new WsActionTester(new UpdateBitbucketAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
       mock(MultipleAlmFeatureProvider.class))));
@@ -64,7 +67,7 @@ public class UpdateBitbucketActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple(almSettingDto.getKey(), "https://bitbucket.enterprise-unicorn.com", "10987654321"));
   }
 
@@ -82,7 +85,7 @@ public class UpdateBitbucketActionTest {
       .setParam("personalAccessToken", "0123456789")
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple("Bitbucket Server - Infra Team", "https://bitbucket.enterprise-unicorn.com", "0123456789"));
   }
 
@@ -98,8 +101,8 @@ public class UpdateBitbucketActionTest {
       .setParam("url", "https://bitbucket.enterprise-unicorn.com")
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
-      .containsOnly(tuple(almSettingDto.getKey(), "https://bitbucket.enterprise-unicorn.com", almSettingDto.getPersonalAccessToken()));
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
+      .containsOnly(tuple(almSettingDto.getKey(), "https://bitbucket.enterprise-unicorn.com", almSettingDto.getDecryptedPersonalAccessToken(encryption)));
   }
 
   @Test
index 47d2868bdbd75054f88c1b722e263a8c2abda60f..0a4639ce137e4aeae7c2ba3f69c345fac0d5bff5 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.almsettings.ws;
 
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
@@ -38,7 +39,9 @@ import static java.lang.String.format;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.assertj.core.groups.Tuple.tuple;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class UpdateBitbucketCloudActionTest {
   @Rule
@@ -46,12 +49,15 @@ public class UpdateBitbucketCloudActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
+  private final Encryption encryption = mock(Encryption.class);
+
   private final WsActionTester ws = new WsActionTester(new UpdateBitbucketCloudAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), mock(ResourceTypes.class)),
       mock(MultipleAlmFeatureProvider.class))));
 
   @Test
   public void update() {
+    when(encryption.isEncrypted(any())).thenReturn(false);
     UserDto user = db.users().insertUser();
     userSession.logIn(user).setSystemAdministrator();
     AlmSettingDto almSettingDto = db.almSettings().insertBitbucketAlmSetting();
@@ -64,12 +70,15 @@ public class UpdateBitbucketCloudActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret, AlmSettingDto::getAppId)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId,
+        s -> s.getDecryptedClientSecret(encryption), AlmSettingDto::getAppId)
       .containsOnly(tuple(almSettingDto.getKey(), "id", "secret", "workspace"));
   }
 
   @Test
   public void update_with_new_key() {
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
     UserDto user = db.users().insertUser();
     userSession.logIn(user).setSystemAdministrator();
 
@@ -83,12 +92,15 @@ public class UpdateBitbucketCloudActionTest {
       .setParam("clientSecret", "secret")
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret, AlmSettingDto::getAppId)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId,
+        s -> s.getDecryptedClientSecret(encryption), AlmSettingDto::getAppId)
       .containsOnly(tuple("Bitbucket Server - Infra Team", "id", "secret", "workspace"));
   }
 
   @Test
   public void update_binding_without_changing_the_key() {
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
     UserDto user = db.users().insertUser();
     userSession.logIn(user).setSystemAdministrator();
     AlmSettingDto almSetting = db.almSettings().insertBitbucketAlmSetting();
@@ -102,12 +114,15 @@ public class UpdateBitbucketCloudActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret, AlmSettingDto::getAppId)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId,
+        s -> s.getDecryptedClientSecret(encryption), AlmSettingDto::getAppId)
       .containsOnly(tuple(almSetting.getKey(), "id", "secret", "workspace"));
   }
 
   @Test
   public void update_without_secret() {
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
     UserDto user = db.users().insertUser();
     userSession.logIn(user).setSystemAdministrator();
 
@@ -119,8 +134,9 @@ public class UpdateBitbucketCloudActionTest {
       .setParam("clientId", "id")
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret, AlmSettingDto::getAppId)
-      .containsOnly(tuple(almSettingDto.getKey(), "id", almSettingDto.getClientSecret(), "workspace"));
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getClientId,
+        s -> s.getDecryptedClientSecret(encryption), AlmSettingDto::getAppId)
+      .containsOnly(tuple(almSettingDto.getKey(), "id", almSettingDto.getDecryptedPrivateKey(encryption), "workspace"));
   }
 
   @Test
index 93265c354fbe5b1d901f3548f8a1f3166d568b4c..d100ba0674eaa4b4f0edf60cb1b6b78396235b68 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.almsettings.ws;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -47,6 +48,8 @@ public class UpdateGithubActionTest {
   @Rule
   public DbTester db = DbTester.create();
 
+  private final Encryption encryption = mock(Encryption.class);
+
   private WsActionTester ws = new WsActionTester(new UpdateGithubAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null),
       mock(MultipleAlmFeatureProvider.class))));
@@ -67,7 +70,8 @@ public class UpdateGithubActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId,
+        s -> s.getDecryptedPrivateKey(encryption), AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption))
       .containsOnly(tuple(almSettingDto.getKey(), "https://github.enterprise-unicorn.com", "54321", "10987654321", "client_1234", "client_so_secret"));
   }
 
@@ -87,7 +91,8 @@ public class UpdateGithubActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId,
+        s -> s.getDecryptedPrivateKey(encryption), AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption))
       .containsOnly(tuple(almSettingDto.getKey(), "https://github.enterprise-unicorn.com", "54321", "10987654321", "client_1234", "client_so_secret"));
   }
 
@@ -108,7 +113,8 @@ public class UpdateGithubActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId,
+        s -> s.getDecryptedPrivateKey(encryption), AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption))
       .containsOnly(tuple("GitHub Server - Infra Team", "https://github.enterprise-unicorn.com", "54321", "10987654321", "client_1234", "client_so_secret"));
   }
 
@@ -126,8 +132,10 @@ public class UpdateGithubActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getClientId, AlmSettingDto::getClientSecret)
-      .containsOnly(tuple(almSettingDto.getKey(), "https://github.enterprise-unicorn.com", "54321", almSettingDto.getPrivateKey(), "client_1234", almSettingDto.getClientSecret()));
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId,
+        s -> s.getDecryptedPrivateKey(encryption), AlmSettingDto::getClientId, s -> s.getDecryptedClientSecret(encryption))
+      .containsOnly(tuple(almSettingDto.getKey(), "https://github.enterprise-unicorn.com", "54321",
+        almSettingDto.getDecryptedPrivateKey(encryption), "client_1234", almSettingDto.getDecryptedClientSecret(encryption)));
   }
 
   @Test
index 132d8d2dde6cfe2e62b126ba4d86c6bdb5670187..073e64f89acf7769492c963578c7eb895ca89bb5 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.Encryption;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
@@ -53,7 +54,8 @@ public class UpdateGitlabActionTest {
 
   private static String GITLAB_URL = "gitlab.com/api/v4";
 
-  private MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
+  private final Encryption encryption = mock(Encryption.class);
+  private final MultipleAlmFeatureProvider multipleAlmFeatureProvider = mock(MultipleAlmFeatureProvider.class);
 
   private WsActionTester ws = new WsActionTester(new UpdateGitlabAction(db.getDbClient(), userSession,
     new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null), multipleAlmFeatureProvider)));
@@ -90,7 +92,7 @@ public class UpdateGitlabActionTest {
       .setParam("personalAccessToken", "10987654321")
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
       .containsOnly(tuple(almSettingDto.getKey(), GITLAB_URL, "10987654321"));
   }
 
@@ -109,7 +111,7 @@ public class UpdateGitlabActionTest {
       .execute();
 
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getPersonalAccessToken, AlmSettingDto::getUrl)
+      .extracting(AlmSettingDto::getKey, s -> s.getDecryptedPersonalAccessToken(encryption), AlmSettingDto::getUrl)
       .containsOnly(tuple("Gitlab - Infra Team", "0123456789", GITLAB_URL));
   }
 
@@ -125,8 +127,8 @@ public class UpdateGitlabActionTest {
       .setParam("url", GITLAB_URL)
       .execute();
     assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession()))
-      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getPersonalAccessToken)
-      .containsOnly(tuple(almSettingDto.getKey(), GITLAB_URL, almSettingDto.getPersonalAccessToken()));
+      .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, s -> s.getDecryptedPersonalAccessToken(encryption))
+      .containsOnly(tuple(almSettingDto.getKey(), GITLAB_URL, almSettingDto.getDecryptedPersonalAccessToken(encryption)));
   }
 
   @Test
index 545922e664b0004ff914f2896a8a133c32ae3e50..97da7ad21fb97ed4bc186db1abfec02312c841e1 100644 (file)
  */
 package org.sonar.server.almsettings.ws;
 
+import org.junit.BeforeClass;
 import org.junit.Rule;
 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.api.config.internal.Encryption;
+import org.sonar.api.config.internal.Settings;
 import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbTester;
@@ -48,8 +51,11 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class ValidateActionTest {
+  private static final Encryption encryption = mock(Encryption.class);
+  private static final Settings settings = mock(Settings.class);
 
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone();
@@ -65,8 +71,13 @@ public class ValidateActionTest {
   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,
-      bitbucketServerSettingsValidator, bitbucketCloudRestClient));
+    new ValidateAction(db.getDbClient(), settings, userSession, almSettingsSupport, azureDevOpsHttpClient, githubGlobalSettingsValidator,
+      gitlabSettingsValidator, bitbucketServerSettingsValidator, bitbucketCloudRestClient));
+
+  @BeforeClass
+  public static void setUp() {
+    when(settings.getEncryption()).thenReturn(encryption);
+  }
 
   @Test
   public void fail_when_key_does_not_match_existing_alm_setting() {
@@ -93,6 +104,7 @@ public class ValidateActionTest {
   @Test
   public void gitlab_validation_checks() {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertGitlabAlmSetting());
+    when(encryption.isEncrypted(any())).thenReturn(false);
 
     ws.newRequest()
       .setParam("key", almSetting.getKey())
@@ -105,6 +117,29 @@ public class ValidateActionTest {
   public void github_validation_checks() {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertGitHubAlmSetting(settings -> settings.setClientId("clientId")
       .setClientSecret("clientSecret")));
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
+    ws.newRequest()
+      .setParam("key", almSetting.getKey())
+      .execute();
+
+    ArgumentCaptor<AlmSettingDto> almSettingDtoArgumentCaptor = ArgumentCaptor.forClass(AlmSettingDto.class);
+    verify(githubGlobalSettingsValidator).validate(almSettingDtoArgumentCaptor.capture());
+    assertThat(almSettingDtoArgumentCaptor.getAllValues()).hasSize(1);
+    assertThat(almSettingDtoArgumentCaptor.getValue().getClientId()).isEqualTo(almSetting.getClientId());
+    assertThat(almSettingDtoArgumentCaptor.getValue().getDecryptedClientSecret(encryption)).isEqualTo(almSetting.getDecryptedClientSecret(encryption));
+    assertThat(almSettingDtoArgumentCaptor.getValue().getAlm()).isEqualTo(almSetting.getAlm());
+    assertThat(almSettingDtoArgumentCaptor.getValue().getAppId()).isEqualTo(almSetting.getAppId());
+  }
+
+  @Test
+  public void github_validation_checks_with_encrypted_secret() {
+    String secret = "encrypted-secret";
+    String decryptedSecret = "decrypted-secret";
+    AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertGitHubAlmSetting(settings -> settings.setClientId("clientId")
+      .setClientSecret(secret)));
+    when(encryption.isEncrypted(secret)).thenReturn(true);
+    when(encryption.decrypt(secret)).thenReturn(decryptedSecret);
 
     ws.newRequest()
       .setParam("key", almSetting.getKey())
@@ -114,7 +149,7 @@ public class ValidateActionTest {
     verify(githubGlobalSettingsValidator).validate(almSettingDtoArgumentCaptor.capture());
     assertThat(almSettingDtoArgumentCaptor.getAllValues()).hasSize(1);
     assertThat(almSettingDtoArgumentCaptor.getValue().getClientId()).isEqualTo(almSetting.getClientId());
-    assertThat(almSettingDtoArgumentCaptor.getValue().getClientSecret()).isEqualTo(almSetting.getClientSecret());
+    assertThat(almSettingDtoArgumentCaptor.getValue().getDecryptedClientSecret(encryption)).isEqualTo(decryptedSecret);
     assertThat(almSettingDtoArgumentCaptor.getValue().getAlm()).isEqualTo(almSetting.getAlm());
     assertThat(almSettingDtoArgumentCaptor.getValue().getAppId()).isEqualTo(almSetting.getAppId());
   }
@@ -122,6 +157,7 @@ public class ValidateActionTest {
   @Test
   public void bitbucketServer_validation_checks() {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertBitbucketAlmSetting());
+    when(encryption.isEncrypted(any())).thenReturn(false);
 
     ws.newRequest()
       .setParam("key", almSetting.getKey())
@@ -137,12 +173,27 @@ public class ValidateActionTest {
   @Test
   public void azure_devops_validation_checks() {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertAzureAlmSetting());
+    when(encryption.isEncrypted(any())).thenReturn(false);
 
     ws.newRequest()
       .setParam("key", almSetting.getKey())
       .execute();
 
-    verify(azureDevOpsHttpClient).checkPAT(almSetting.getUrl(), almSetting.getPersonalAccessToken());
+    verify(azureDevOpsHttpClient).checkPAT(almSetting.getUrl(), almSetting.getDecryptedPersonalAccessToken(encryption));
+  }
+
+  @Test
+  public void azure_devops_validation_checks_with_encrypted_token() {
+    AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertAzureAlmSetting());
+    String decryptedToken = "decrypted-token";
+    when(encryption.isEncrypted(any())).thenReturn(true);
+    when(encryption.decrypt(any())).thenReturn(decryptedToken);
+
+    ws.newRequest()
+      .setParam("key", almSetting.getKey())
+      .execute();
+
+    verify(azureDevOpsHttpClient).checkPAT(almSetting.getUrl(), decryptedToken);
   }
 
   @Test
@@ -150,7 +201,7 @@ public class ValidateActionTest {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertAzureAlmSetting());
 
     doThrow(IllegalArgumentException.class)
-      .when(azureDevOpsHttpClient).checkPAT(almSetting.getUrl(), almSetting.getPersonalAccessToken());
+      .when(azureDevOpsHttpClient).checkPAT(any(), any());
 
     assertThatThrownBy(() -> ws.newRequest()
       .setParam("key", almSetting.getKey())
@@ -160,20 +211,36 @@ public class ValidateActionTest {
   @Test
   public void bitbucketcloud_validation_checks() {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertBitbucketCloudAlmSetting());
+    when(encryption.isEncrypted(any())).thenReturn(false);
+
+    ws.newRequest()
+      .setParam("key", almSetting.getKey())
+      .execute();
+
+    verify(bitbucketCloudRestClient).validate(almSetting.getClientId(), almSetting.getDecryptedClientSecret(encryption), almSetting.getAppId());
+  }
+
+  @Test
+  public void bitbucketcloud_validation_checks_with_encrypted_secret() {
+    String decryptedSecret = "decrypted-secret";
+    AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertBitbucketCloudAlmSetting());
+    when(encryption.isEncrypted(any())).thenReturn(true);
+    when(encryption.decrypt(any())).thenReturn(decryptedSecret);
 
     ws.newRequest()
       .setParam("key", almSetting.getKey())
       .execute();
 
-    verify(bitbucketCloudRestClient).validate(almSetting.getClientId(), almSetting.getClientSecret(), almSetting.getAppId());
+    verify(bitbucketCloudRestClient).validate(almSetting.getClientId(), decryptedSecret, almSetting.getAppId());
   }
 
   @Test
   public void bitbucketcloud_validation_check_fails() {
     AlmSettingDto almSetting = insertAlmSetting(db.almSettings().insertBitbucketCloudAlmSetting());
+    when(encryption.isEncrypted(any())).thenReturn(false);
 
     doThrow(IllegalArgumentException.class)
-      .when(bitbucketCloudRestClient).validate(almSetting.getClientId(), almSetting.getClientSecret(), almSetting.getAppId());
+      .when(bitbucketCloudRestClient).validate(any(), any(), any());
 
     TestRequest request = ws.newRequest()
       .setParam("key", almSetting.getKey());