diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DecryptedSensitiveFields.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DecryptedSensitiveFields.java index 6b6a64bb3f..4d41a1fd32 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DecryptedSensitiveFields.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DecryptedSensitiveFields.java @@ -30,6 +30,8 @@ public class DecryptedSensitiveFields { BasicAuth basicAuth; OAuth2 openAuth2; + + BearerTokenAuth bearerTokenAuth; public DecryptedSensitiveFields(AuthenticationResponse authResponse) { this.token = authResponse.getToken(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java index 58d91e609d..5f2be404b0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java @@ -7,6 +7,7 @@ import com.appsmith.external.models.AuthenticationDTO; import com.appsmith.external.models.AuthenticationResponse; import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.BasicAuth; +import com.appsmith.external.models.BearerTokenAuth; import com.appsmith.external.models.DBAuth; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; @@ -1983,6 +1984,10 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica authResponse.setExpiresAt(Instant.now()); auth2.setAuthenticationResponse(authResponse); datasource.getDatasourceConfiguration().setAuthentication(auth2); + } else if (StringUtils.equals(authType, BearerTokenAuth.class.getName())) { + BearerTokenAuth auth = new BearerTokenAuth(); + auth.setBearerToken(decryptedFields.getBearerTokenAuth().getBearerToken()); + datasource.getDatasourceConfiguration().setAuthentication(auth); } return datasource; } @@ -2020,6 +2025,8 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica } else if (authentication instanceof BasicAuth auth) { dsDecryptedFields.setPassword(auth.getPassword()); dsDecryptedFields.setBasicAuth(auth); + } else if (authentication instanceof BearerTokenAuth auth) { + dsDecryptedFields.setBearerTokenAuth(auth); } dsDecryptedFields.setAuthType(authentication.getClass().getName()); return dsDecryptedFields; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImplV2.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImplV2.java index 0ac9d9213d..68193a6691 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImplV2.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImplV2.java @@ -7,6 +7,7 @@ import com.appsmith.external.models.AuthenticationDTO; import com.appsmith.external.models.AuthenticationResponse; import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.BasicAuth; +import com.appsmith.external.models.BearerTokenAuth; import com.appsmith.external.models.DBAuth; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; @@ -32,7 +33,6 @@ import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.ApplicationJson; -import com.appsmith.server.dtos.CustomJSLibApplicationDTO; import com.appsmith.server.dtos.ExportFileDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; @@ -2019,6 +2019,10 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli authResponse.setExpiresAt(Instant.now()); auth2.setAuthenticationResponse(authResponse); datasource.getDatasourceConfiguration().setAuthentication(auth2); + } else if (org.apache.commons.lang.StringUtils.equals(authType, BearerTokenAuth.class.getName())) { + BearerTokenAuth auth = new BearerTokenAuth(); + auth.setBearerToken(decryptedFields.getBearerTokenAuth().getBearerToken()); + datasource.getDatasourceConfiguration().setAuthentication(auth); } return datasource; } @@ -2059,6 +2063,8 @@ public class ImportExportApplicationServiceCEImplV2 implements ImportExportAppli BasicAuth auth = (BasicAuth) authentication; dsDecryptedFields.setPassword(auth.getPassword()); dsDecryptedFields.setBasicAuth(auth); + } else if (authentication instanceof BearerTokenAuth auth) { + dsDecryptedFields.setBearerTokenAuth(auth); } dsDecryptedFields.setAuthType(authentication.getClass().getName()); return dsDecryptedFields; diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java index bf55b9887e..53f215fffe 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java @@ -3,13 +3,17 @@ package com.appsmith.server.solutions; import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.ActionDTO; +import com.appsmith.external.models.BearerTokenAuth; +import com.appsmith.external.models.Connection; import com.appsmith.external.models.DBAuth; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.DecryptedSensitiveFields; import com.appsmith.external.models.InvisibleActionFields; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; import com.appsmith.external.models.Property; +import com.appsmith.external.models.SSLDetails; import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.SerialiseApplicationObjective; import com.appsmith.server.domains.ActionCollection; @@ -3509,4 +3513,79 @@ public class ImportExportApplicationServiceTests { .verifyComplete(); } + + @Test + @WithUserDetails(value = "api_user") + public void exportApplication_WithBearerTokenAndExportWithConfig_exportedWithDecryptedFields() { + String randomUUID = UUID.randomUUID().toString(); + + Workspace testWorkspace = new Workspace(); + testWorkspace.setName("workspace-" + randomUUID); + // User apiUser = userService.findByEmail("api_user").block(); + Mono workspaceMono = workspaceService.create(testWorkspace).cache(); + + Mono applicationMono = workspaceMono.flatMap(workspace -> { + Application testApplication = new Application(); + testApplication.setName("application-" + randomUUID); + testApplication.setExportWithConfiguration(true); + testApplication.setWorkspaceId(workspace.getId()); + return applicationPageService.createApplication(testApplication); + }).flatMap(application -> { + ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); + accessDTO.setPublicAccess(true); + return applicationService.changeViewAccess(application.getId(), accessDTO).thenReturn(application); + }); + + Mono datasourceMono = workspaceMono.zipWith(pluginRepository.findByPackageName("restapi-plugin")) + .flatMap(objects -> { + Workspace workspace = objects.getT1(); + Plugin plugin = objects.getT2(); + + Datasource datasource = new Datasource(); + datasource.setPluginId(plugin.getId()); + datasource.setName("RestAPIWithBearerToken"); + datasource.setWorkspaceId(workspace.getId()); + datasource.setIsConfigured(true); + + BearerTokenAuth bearerTokenAuth = new BearerTokenAuth(); + bearerTokenAuth.setBearerToken("token_" + randomUUID); + + SSLDetails sslDetails = new SSLDetails(); + sslDetails.setAuthType(SSLDetails.AuthType.DEFAULT); + Connection connection = new Connection(); + connection.setSsl(sslDetails); + + DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration(); + datasourceConfiguration.setAuthentication(bearerTokenAuth); + datasourceConfiguration.setConnection(connection); + datasourceConfiguration.setConnection(new Connection()); + datasourceConfiguration.setUrl("https://mock-api.appsmith.com"); + + datasource.setDatasourceConfiguration(datasourceConfiguration); + return datasourceService.create(datasource); + }); + + Mono exportAppMono = Mono.zip(applicationMono, datasourceMono).flatMap(objects -> { + ApplicationPage applicationPage = objects.getT1().getPages().get(0); + ActionDTO action = new ActionDTO(); + action.setName("validAction"); + action.setPageId(applicationPage.getId()); + action.setPluginId(objects.getT2().getPluginId()); + action.setDatasource(objects.getT2()); + + ActionConfiguration actionConfiguration = new ActionConfiguration(); + actionConfiguration.setHttpMethod(HttpMethod.GET); + actionConfiguration.setPath("/test/path"); + action.setActionConfiguration(actionConfiguration); + + return layoutActionService.createSingleAction(action, Boolean.FALSE) + .then(importExportApplicationService.exportApplicationById(objects.getT1().getId(), "")); + }); + + StepVerifier.create(exportAppMono).assertNext(applicationJson -> { + assertThat(applicationJson.getDecryptedFields()).isNotEmpty(); + DecryptedSensitiveFields fields = applicationJson.getDecryptedFields().get("RestAPIWithBearerToken"); + assertThat(fields.getBearerTokenAuth().getBearerToken()).isEqualTo("token_" + randomUUID); + }).verifyComplete(); + } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceV2Tests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceV2Tests.java index 3c65b77735..585c6cf8e0 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceV2Tests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceV2Tests.java @@ -3,13 +3,17 @@ package com.appsmith.server.solutions; import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.ActionDTO; +import com.appsmith.external.models.BearerTokenAuth; +import com.appsmith.external.models.Connection; import com.appsmith.external.models.DBAuth; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.DecryptedSensitiveFields; import com.appsmith.external.models.InvisibleActionFields; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; import com.appsmith.external.models.Property; +import com.appsmith.external.models.SSLDetails; import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.SerialiseApplicationObjective; import com.appsmith.server.domains.ActionCollection; @@ -30,7 +34,6 @@ import com.appsmith.server.dtos.ApplicationAccessDTO; import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.dtos.ApplicationPagesDTO; -import com.appsmith.server.dtos.CustomJSLibApplicationDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.PageNameIdDTO; import com.appsmith.server.exceptions.AppsmithError; @@ -95,7 +98,6 @@ import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -3601,4 +3603,79 @@ public class ImportExportApplicationServiceV2Tests { .verifyComplete(); } + + @Test + @WithUserDetails(value = "api_user") + public void exportApplication_WithBearerTokenAndExportWithConfig_exportedWithDecryptedFields() { + String randomUUID = UUID.randomUUID().toString(); + + Workspace testWorkspace = new Workspace(); + testWorkspace.setName("workspace-" + randomUUID); + // User apiUser = userService.findByEmail("api_user").block(); + Mono workspaceMono = workspaceService.create(testWorkspace).cache(); + + Mono applicationMono = workspaceMono.flatMap(workspace -> { + Application testApplication = new Application(); + testApplication.setName("application-" + randomUUID); + testApplication.setExportWithConfiguration(true); + testApplication.setWorkspaceId(workspace.getId()); + return applicationPageService.createApplication(testApplication); + }).flatMap(application -> { + ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); + accessDTO.setPublicAccess(true); + return applicationService.changeViewAccess(application.getId(), accessDTO).thenReturn(application); + }); + + Mono datasourceMono = workspaceMono.zipWith(pluginRepository.findByPackageName("restapi-plugin")) + .flatMap(objects -> { + Workspace workspace = objects.getT1(); + Plugin plugin = objects.getT2(); + + Datasource datasource = new Datasource(); + datasource.setPluginId(plugin.getId()); + datasource.setName("RestAPIWithBearerToken"); + datasource.setWorkspaceId(workspace.getId()); + datasource.setIsConfigured(true); + + BearerTokenAuth bearerTokenAuth = new BearerTokenAuth(); + bearerTokenAuth.setBearerToken("token_" + randomUUID); + + SSLDetails sslDetails = new SSLDetails(); + sslDetails.setAuthType(SSLDetails.AuthType.DEFAULT); + Connection connection = new Connection(); + connection.setSsl(sslDetails); + + DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration(); + datasourceConfiguration.setAuthentication(bearerTokenAuth); + datasourceConfiguration.setConnection(connection); + datasourceConfiguration.setConnection(new Connection()); + datasourceConfiguration.setUrl("https://mock-api.appsmith.com"); + + datasource.setDatasourceConfiguration(datasourceConfiguration); + return datasourceService.create(datasource); + }); + + Mono exportAppMono = Mono.zip(applicationMono, datasourceMono).flatMap(objects -> { + ApplicationPage applicationPage = objects.getT1().getPages().get(0); + ActionDTO action = new ActionDTO(); + action.setName("validAction"); + action.setPageId(applicationPage.getId()); + action.setPluginId(objects.getT2().getPluginId()); + action.setDatasource(objects.getT2()); + + ActionConfiguration actionConfiguration = new ActionConfiguration(); + actionConfiguration.setHttpMethod(HttpMethod.GET); + actionConfiguration.setPath("/test/path"); + action.setActionConfiguration(actionConfiguration); + + return layoutActionService.createSingleAction(action, Boolean.FALSE) + .then(importExportApplicationService.exportApplicationById(objects.getT1().getId(), "")); + }); + + StepVerifier.create(exportAppMono).assertNext(applicationJson -> { + assertThat(applicationJson.getDecryptedFields()).isNotEmpty(); + DecryptedSensitiveFields fields = applicationJson.getDecryptedFields().get("RestAPIWithBearerToken"); + assertThat(fields.getBearerTokenAuth().getBearerToken()).isEqualTo("token_" + randomUUID); + }).verifyComplete(); + } }