fix: Make sure updatable connections come back with decrypted tokens (#26558)

This commit is contained in:
Nidhi 2023-08-23 16:32:14 +05:30 committed by GitHub
parent 4c936a85d9
commit 734b563237
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 6 deletions

View File

@ -147,15 +147,14 @@ public class DatasourceContextServiceCEImpl implements DatasourceContextServiceC
public Mono<Object> updateDatasourceAndSetAuthentication(Object connection, DatasourceStorage datasourceStorage) {
Mono<DatasourceStorage> datasourceStorageMono = Mono.just(datasourceStorage);
if (connection instanceof UpdatableConnection) {
if (connection instanceof UpdatableConnection updatableConnection) {
datasourceStorage.setUpdatedAt(Instant.now());
datasourceStorage
.getDatasourceConfiguration()
.setAuthentication(((UpdatableConnection) connection)
.getAuthenticationDTO(datasourceStorage
.getDatasourceConfiguration()
.getAuthentication()));
datasourceStorageMono = datasourceStorageService.save(datasourceStorage);
.setAuthentication(updatableConnection.getAuthenticationDTO(
datasourceStorage.getDatasourceConfiguration().getAuthentication()));
datasourceStorageMono = datasourceStorageService.updateDatasourceStorage(
datasourceStorage, datasourceStorage.getEnvironmentId(), Boolean.FALSE);
}
return datasourceStorageMono.thenReturn(connection);
}

View File

@ -1,12 +1,15 @@
package com.appsmith.server.services;
import com.appsmith.external.helpers.restApiUtils.connections.OAuth2ClientCredentials;
import com.appsmith.external.models.ApiKeyAuth;
import com.appsmith.external.models.AuthenticationDTO;
import com.appsmith.external.models.BasicAuth;
import com.appsmith.external.models.DBAuth;
import com.appsmith.external.models.Datasource;
import com.appsmith.external.models.DatasourceConfiguration;
import com.appsmith.external.models.DatasourceStorage;
import com.appsmith.external.models.DatasourceStorageDTO;
import com.appsmith.external.models.OAuth2;
import com.appsmith.external.models.UpdatableConnection;
import com.appsmith.external.plugins.PluginExecutor;
import com.appsmith.external.services.EncryptionService;
@ -419,6 +422,7 @@ public class DatasourceContextServiceTest {
DatasourceStorage createdDatasourceStorage =
datasourceStorageService.createDatasourceStorageFromDatasourceStorageDTO(datasourceStorageDTO);
createdDatasourceStorage.setPluginId(createdDatasource.getPluginId());
DatasourceContextIdentifier datasourceContextIdentifier =
new DatasourceContextIdentifier(createdDatasource.getId(), defaultEnvironmentId);
@ -545,4 +549,78 @@ public class DatasourceContextServiceTest {
assertThat(datasourceContextIdentifier.getDatasourceId()).isEqualTo(sampleDatasourceId);
assertThat(datasourceContextIdentifier.getEnvironmentId()).isEqualTo(defaultEnvironmentId);
}
@Test
@WithUserDetails(value = "api_user")
public void
testUpdateDatasourceAndSetAuthentication_withNoRealChange_keepsDatasourceConfigurationValuesDecrypted() {
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any()))
.thenReturn(Mono.just(new MockPluginExecutor()));
Mono<Plugin> pluginMono = pluginService.findByPackageName("restapi-plugin");
Datasource datasource = new Datasource();
datasource.setName(
"testUpdateDatasourceAndSetAuthentication_withNoRealChange_keepsDatasourceConfigurationValuesDecrypted");
DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration();
datasourceConfiguration.setUrl("http://test.com");
OAuth2 authenticationDTO = new OAuth2();
String username = "username";
String password = "This is the decrypted value to test for";
authenticationDTO.setClientId(username);
authenticationDTO.setClientSecret(password);
authenticationDTO.setAccessTokenUrl("http://test.com");
authenticationDTO.setGrantType(OAuth2.Type.CLIENT_CREDENTIALS);
datasourceConfiguration.setAuthentication(authenticationDTO);
datasource.setWorkspaceId(workspaceId);
DatasourceStorageDTO datasourceStorageDTO = new DatasourceStorageDTO();
datasourceStorageDTO.setDatasourceConfiguration(datasourceConfiguration);
datasourceStorageDTO.setEnvironmentId(defaultEnvironmentId);
datasourceStorageDTO.setIsConfigured(Boolean.TRUE);
HashMap<String, DatasourceStorageDTO> storages = new HashMap<>();
storages.put(defaultEnvironmentId, datasourceStorageDTO);
datasource.setDatasourceStorages(storages);
final Datasource createdDatasource = pluginMono
.map(plugin -> {
datasource.setPluginId(plugin.getId());
return datasource;
})
.flatMap(datasourceService::create)
.block();
assert createdDatasource != null;
DatasourceStorage datasourceStorage = datasourceService
.findById(createdDatasource.getId())
.flatMap(datasource1 ->
datasourceStorageService.findByDatasourceAndEnvironmentId(datasource1, defaultEnvironmentId))
.block();
OAuth2ClientCredentials oAuth2ClientCredentials = Mockito.mock(OAuth2ClientCredentials.class);
Mockito.when(oAuth2ClientCredentials.getAuthenticationDTO(Mockito.any()))
.thenCallRealMethod();
// Check that the value was decrypted before
DatasourceConfiguration savedDsConfig = datasourceStorage.getDatasourceConfiguration();
AuthenticationDTO auth1 = savedDsConfig.getAuthentication();
assertThat(auth1).isInstanceOf(OAuth2.class);
assertThat(((OAuth2) auth1).getClientSecret()).isEqualTo(password);
Mono<Object> resultMono = datasourceContextService.updateDatasourceAndSetAuthentication(
oAuth2ClientCredentials, datasourceStorage);
// Check that the value remains decrypted after
StepVerifier.create(resultMono)
.assertNext(result -> {
DatasourceConfiguration newDsConfig = datasourceStorage.getDatasourceConfiguration();
AuthenticationDTO auth2 = newDsConfig.getAuthentication();
assertThat(auth2).isInstanceOf(OAuth2.class);
assertThat(((OAuth2) auth2).getClientSecret()).isEqualTo(password);
})
.verifyComplete();
}
}