chore: Remove CS URL in client (#37665)

The server should be the source of truth and owner for the current CS
URL, and the client having direct access to the CS URL is (almost) an
abstraction leak. We're using it on client for one purpose only, to
redirect to CS for Google sheets authorization. That's just as well
achieved with another redirect via the server.

This PR does that redirection and removes access to the CS URL to the
client code. Not used anywhere else, and shouldn't be needed.


## Automation

/test sanity datasource

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12029489682>
> Commit: 0a1937e7d5d492c7c6a98bde124a157663126ac1
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12029489682&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity, @tag.Datasource`
> Spec:
> <hr>Tue, 26 Nov 2024 12:21:11 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
	- Enhanced CI workflow with improved error handling and logging.
- Added a new authorization redirection endpoint in the SaaS controller.

- **Improvements**
	- Database URL validation step added to CI tests.
	- Artifact management for test results has been clarified and improved.
- Removal of `cloudServicesBaseUrl` from various configurations to
streamline cloud service integration.

- **Bug Fixes**
	- Refined logic for rerunning tests based on previous results.

These updates contribute to a more robust and efficient testing and
configuration environment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Shrikant Sharat Kandula 2024-11-27 10:32:35 +05:30 committed by GitHub
parent 61960edb09
commit c9ddd9c765
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 40 additions and 40 deletions

View File

@ -166,10 +166,8 @@ jobs:
-e APPSMITH_JWT_SECRET=appsmith-cloud-services-jwt-secret-dummy-key \
-e APPSMITH_ENCRYPTION_SALT=encryption-salt \
-e APPSMITH_ENCRYPTION_PASSWORD=encryption-password \
-e APPSMITH_CLOUD_SERVICES_URL=https://cs-dev.appsmith.com \
-e APPSMITH_CUSTOMER_PORTAL_URL=https://dev.appsmith.com \
-e APPSMITH_CLOUD_SERVICES_BASE_URL=https://cs-dev.appsmith.com \
-e APPSMITH_CLOUD_SERVER_BASE_URL=https://release.app.appsmith.com \
-e AUTH0_ISSUER_URL=https://login.release-customer.appsmith.com/ \
-e AUTH0_CLIENT_ID=dummy-client-id \
-e AUTH0_CLIENT_SECRET=dummy-secret-id \
@ -198,7 +196,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version-file: app/client/package.json
- name: Check DB URL
if: steps.run_result.outputs.run_result != 'success'
run: |
@ -457,20 +455,20 @@ jobs:
name: server-logs-${{ matrix.job }}
path: app/server/server-logs.log
overwrite: true
- name: Collect docker log as file
if: always()
run: |
docker logs appsmith >& app/server/docker-logs.log
- name: Upload server docker logs bundle on failure
- name: Upload server docker logs bundle on failure
uses: actions/upload-artifact@v4
if: always()
with:
name: docker-logs-${{ matrix.job }}
path: app/server/docker-logs.log
overwrite: true
# Set status = success
- name: Save the status of the run
run: |

View File

@ -17,7 +17,7 @@ on:
run_count:
description: 'Number of times to repeat the test run'
required: false
type: number
type: number
default: 1
workflow_call:
inputs:
@ -176,10 +176,8 @@ jobs:
-e APPSMITH_JWT_SECRET=appsmith-cloud-services-jwt-secret-dummy-key \
-e APPSMITH_ENCRYPTION_SALT=encryption-salt \
-e APPSMITH_ENCRYPTION_PASSWORD=encryption-password \
-e APPSMITH_CLOUD_SERVICES_URL=https://cs-dev.appsmith.com \
-e APPSMITH_CUSTOMER_PORTAL_URL=https://dev.appsmith.com \
-e APPSMITH_CLOUD_SERVICES_BASE_URL=https://cs-dev.appsmith.com \
-e APPSMITH_CLOUD_SERVER_BASE_URL=https://release.app.appsmith.com \
-e AUTH0_ISSUER_URL=https://login.release-customer.appsmith.com/ \
-e AUTH0_CLIENT_ID=dummy-client-id \
-e AUTH0_CLIENT_SECRET=dummy-secret-id \
@ -351,10 +349,10 @@ jobs:
npx cypress-repeat-pro run -n ${{ inputs.run_count }} --force \
--spec ${{ env.specs_to_run }} \
--config-file "cypress_ci_custom.config.ts"
cat cy-repeat-summary.txt
cat cy-repeat-summary.txt
# Define the path for the failure flag file
FAILURE_FLAG_FILE="ci_test_status.txt"
# Check for test results and store the status in the file
if ! grep -q "Total Failed: 0" cy-repeat-summary.txt; then
echo "ci_test_failed=true" > "$FAILURE_FLAG_FILE"
@ -362,7 +360,7 @@ jobs:
echo "ci_test_failed=false" > "$FAILURE_FLAG_FILE"
fi
cat "$FAILURE_FLAG_FILE"
- name: Trim number of cypress log files
if: failure()
run: |
@ -375,7 +373,7 @@ jobs:
name: cypress-repeat-logs
path: ${{ github.workspace }}/app/client/cy-repeat-summary.txt
overwrite: true
- name: Upload ci_test_status.txt artifact
if: always()
uses: actions/upload-artifact@v4

View File

@ -166,10 +166,8 @@ jobs:
-e APPSMITH_JWT_SECRET=appsmith-cloud-services-jwt-secret-dummy-key \
-e APPSMITH_ENCRYPTION_SALT=encryption-salt \
-e APPSMITH_ENCRYPTION_PASSWORD=encryption-password \
-e APPSMITH_CLOUD_SERVICES_URL=https://cs-dev.appsmith.com \
-e APPSMITH_CUSTOMER_PORTAL_URL=https://dev.appsmith.com \
-e APPSMITH_CLOUD_SERVICES_BASE_URL=https://cs-dev.appsmith.com \
-e APPSMITH_CLOUD_SERVER_BASE_URL=https://release.app.appsmith.com \
-e AUTH0_ISSUER_URL=https://login.release-customer.appsmith.com/ \
-e AUTH0_CLIENT_ID=dummy-client-id \
-e AUTH0_CLIENT_SECRET=dummy-secret-id \

View File

@ -37,7 +37,6 @@ server {
sub_filter __APPSMITH_VERSION_RELEASE_DATE__ '${APPSMITH_VERSION_RELEASE_DATE}';
sub_filter __APPSMITH_INTERCOM_APP_ID__ '${APPSMITH_INTERCOM_APP_ID}';
sub_filter __APPSMITH_MAIL_ENABLED__ '${APPSMITH_MAIL_ENABLED}';
sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}';
sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}';
sub_filter __APPSMITH_DISABLE_INTERCOM__ '${APPSMITH_DISABLE_INTERCOM}';
sub_filter __APPSMITH_ZIPY_SDK_KEY__ '${APPSMITH_ZIPY_SDK_KEY}';

View File

@ -263,9 +263,6 @@
},
intercomAppID: INTERCOM_APP_ID,
mailEnabled: parseConfig('{{env "APPSMITH_MAIL_ENABLED"}}'),
cloudServicesBaseUrl:
parseConfig('{{env "APPSMITH_CLOUD_SERVICES_BASE_URL"}}') ||
"https://cs.appsmith.com",
googleRecaptchaSiteKey: parseConfig('{{env "APPSMITH_RECAPTCHA_SITE_KEY"}}'),
hideWatermark: parseConfig('{{env "APPSMITH_HIDE_WATERMARK"}}'),
disableIframeWidgetSandbox: parseConfig(

View File

@ -1,6 +1,2 @@
import { getAppsmithConfigs } from "ee/configs";
const { cloudServicesBaseUrl: BASE_URL } = getAppsmithConfigs();
export const authorizeDatasourceWithAppsmithToken = (appsmithToken: string) =>
`${BASE_URL}/api/v1/integrations/oauth/authorize?appsmithToken=${appsmithToken}`;
`/api/v1/saas/authorize?appsmithToken=${appsmithToken}`;

View File

@ -43,7 +43,6 @@ export interface INJECTED_CONFIGS {
};
intercomAppID: string;
mailEnabled: boolean;
cloudServicesBaseUrl: string;
googleRecaptchaSiteKey: string;
supportEmail: string;
disableIframeWidgetSandbox: boolean;
@ -116,7 +115,6 @@ export const getConfigsFromEnvVars = (): INJECTED_CONFIGS => {
mailEnabled: process.env.REACT_APP_MAIL_ENABLED
? process.env.REACT_APP_MAIL_ENABLED.length > 0
: false,
cloudServicesBaseUrl: process.env.REACT_APP_CLOUD_SERVICES_BASE_URL || "",
googleRecaptchaSiteKey:
process.env.REACT_APP_GOOGLE_RECAPTCHA_SITE_KEY || "",
supportEmail: process.env.APPSMITH_SUPPORT_EMAIL || "support@appsmith.com",
@ -287,10 +285,6 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => {
ENV_CONFIG.intercomAppID || APPSMITH_FEATURE_CONFIGS?.intercomAppID || "",
mailEnabled:
ENV_CONFIG.mailEnabled || APPSMITH_FEATURE_CONFIGS?.mailEnabled || false,
cloudServicesBaseUrl:
ENV_CONFIG.cloudServicesBaseUrl ||
APPSMITH_FEATURE_CONFIGS?.cloudServicesBaseUrl ||
"",
appsmithSupportEmail: ENV_CONFIG.supportEmail,
disableIframeWidgetSandbox:
ENV_CONFIG.disableIframeWidgetSandbox ||

View File

@ -56,8 +56,6 @@ export interface AppsmithUIConfigs {
intercomAppID: string;
mailEnabled: boolean;
cloudServicesBaseUrl: string;
googleRecaptchaSiteKey: {
enabled: boolean;
apiKey: string;

View File

@ -1,5 +1,6 @@
package com.appsmith.server.controllers;
import com.appsmith.server.configurations.CloudServicesConfig;
import com.appsmith.server.constants.Url;
import com.appsmith.server.controllers.ce.SaasControllerCE;
import com.appsmith.server.solutions.AuthenticationService;
@ -12,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping(Url.SAAS_URL)
public class SaasController extends SaasControllerCE {
public SaasController(AuthenticationService authenticationService) {
super(authenticationService);
public SaasController(AuthenticationService authenticationService, CloudServicesConfig cloudServicesConfig) {
super(authenticationService, cloudServicesConfig);
}
}

View File

@ -2,15 +2,18 @@ package com.appsmith.server.controllers.ce;
import com.appsmith.external.models.OAuth2ResponseDTO;
import com.appsmith.external.views.Views;
import com.appsmith.server.configurations.CloudServicesConfig;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.constants.Url;
import com.appsmith.server.dtos.RequestAppsmithTokenDTO;
import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.solutions.AuthenticationService;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -20,16 +23,17 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@Slf4j
@RequestMapping(Url.SAAS_URL)
@RequiredArgsConstructor
public class SaasControllerCE {
private final AuthenticationService authenticationService;
@Autowired
public SaasControllerCE(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
private final CloudServicesConfig cloudServicesConfig;
@JsonView(Views.Public.class)
@PostMapping("/{datasourceId}/oauth")
@ -63,4 +67,21 @@ public class SaasControllerCE {
.getAccessTokenFromCloud(datasourceId, environmentId, appsmithToken)
.map(datasource -> new ResponseDTO<>(HttpStatus.OK.value(), datasource, null));
}
@GetMapping("authorize")
public Mono<Void> redirectForAuthorize(ServerWebExchange exchange, @RequestParam String appsmithToken) {
if (appsmithToken == null || appsmithToken.isEmpty()) {
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
return exchange.getResponse().setComplete();
}
final String url = cloudServicesConfig.getBaseUrl() + "/api/v1/integrations/oauth/authorize?appsmithToken="
+ URLEncoder.encode(appsmithToken, StandardCharsets.UTF_8);
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
response.getHeaders().set("Location", url);
return response.setComplete();
}
}