From 38e6d617091bcc02d3bd41d8977b9a3cae75ba74 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Thu, 30 Mar 2023 13:40:59 +0100 Subject: [PATCH] Explictly check for google datasource configured (#10165) * Explictly check for google datasource configured * Unit tests for getGoogleDatasourceConfig * Update /api/global/configs/public test + lint --- packages/backend-core/src/configs/configs.ts | 2 +- .../src/configs/tests/configs.spec.ts | 74 ++++++++++++++++++- .../tests/utilities/structures/sso.ts | 14 +++- .../modals/GoogleDatasourceConfigModal.svelte | 2 +- .../builder/src/stores/portal/organisation.js | 2 + packages/types/src/api/web/global/configs.ts | 1 + .../src/api/controllers/global/configs.ts | 3 + .../api/routes/global/tests/configs.spec.ts | 1 + 8 files changed, 94 insertions(+), 5 deletions(-) diff --git a/packages/backend-core/src/configs/configs.ts b/packages/backend-core/src/configs/configs.ts index 305a074152..b461497747 100644 --- a/packages/backend-core/src/configs/configs.ts +++ b/packages/backend-core/src/configs/configs.ts @@ -162,7 +162,7 @@ export async function getGoogleConfig(): Promise< export async function getGoogleDatasourceConfig(): Promise< GoogleInnerConfig | undefined > { - if (!env.isDev() && !env.SELF_HOSTED) { + if (!env.SELF_HOSTED) { // always use the env vars in cloud return getDefaultGoogleConfig() } diff --git a/packages/backend-core/src/configs/tests/configs.spec.ts b/packages/backend-core/src/configs/tests/configs.spec.ts index 079f2ab681..45e56a2581 100644 --- a/packages/backend-core/src/configs/tests/configs.spec.ts +++ b/packages/backend-core/src/configs/tests/configs.spec.ts @@ -1,4 +1,9 @@ -import { DBTestConfiguration, generator, testEnv } from "../../../tests" +import { + DBTestConfiguration, + generator, + testEnv, + structures, +} from "../../../tests" import { ConfigType } from "@budibase/types" import env from "../../environment" import * as configs from "../configs" @@ -113,4 +118,71 @@ describe("configs", () => { }) }) }) + + describe("getGoogleDatasourceConfig", () => { + function setEnvVars() { + env.GOOGLE_CLIENT_SECRET = "test" + env.GOOGLE_CLIENT_ID = "test" + } + + function unsetEnvVars() { + env.GOOGLE_CLIENT_SECRET = undefined + env.GOOGLE_CLIENT_ID = undefined + } + + describe("cloud", () => { + beforeEach(() => { + testEnv.cloudHosted() + }) + + it("returns from env vars", async () => { + await config.doInTenant(async () => { + setEnvVars() + const config = await configs.getGoogleDatasourceConfig() + unsetEnvVars() + + expect(config).toEqual({ + activated: true, + clientID: "test", + clientSecret: "test", + }) + }) + }) + + it("returns undefined when no env vars are configured", async () => { + await config.doInTenant(async () => { + const config = await configs.getGoogleDatasourceConfig() + expect(config).toBeUndefined() + }) + }) + }) + + describe("self host", () => { + beforeEach(() => { + testEnv.selfHosted() + }) + + it("returns from config", async () => { + await config.doInTenant(async () => { + const googleDoc = structures.sso.googleConfigDoc() + await configs.save(googleDoc) + const config = await configs.getGoogleDatasourceConfig() + expect(config).toEqual(googleDoc.config) + }) + }) + + it("falls back to env vars when config is disabled", async () => { + await config.doInTenant(async () => { + setEnvVars() + const config = await configs.getGoogleDatasourceConfig() + unsetEnvVars() + expect(config).toEqual({ + activated: true, + clientID: "test", + clientSecret: "test", + }) + }) + }) + }) + }) }) diff --git a/packages/backend-core/tests/utilities/structures/sso.ts b/packages/backend-core/tests/utilities/structures/sso.ts index 7413fa3c09..9da9c82223 100644 --- a/packages/backend-core/tests/utilities/structures/sso.ts +++ b/packages/backend-core/tests/utilities/structures/sso.ts @@ -1,4 +1,6 @@ import { + ConfigType, + GoogleConfig, GoogleInnerConfig, JwtClaims, OAuth2, @@ -10,10 +12,10 @@ import { User, } from "@budibase/types" import { generator } from "./generator" -import { uuid, email } from "./common" +import { email, uuid } from "./common" import * as shared from "./shared" -import _ from "lodash" import { user } from "./shared" +import _ from "lodash" export function OAuth(): OAuth2 { return { @@ -107,3 +109,11 @@ export function googleConfig(): GoogleInnerConfig { clientSecret: generator.string(), } } + +export function googleConfigDoc(): GoogleConfig { + return { + _id: "config_google", + type: ConfigType.GOOGLE, + config: googleConfig(), + } +} diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/GoogleDatasourceConfigModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/GoogleDatasourceConfigModal.svelte index c12ddab78d..de9ecce778 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/modals/GoogleDatasourceConfigModal.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/GoogleDatasourceConfigModal.svelte @@ -12,7 +12,7 @@ // kill the reference so the input isn't saved let datasource = cloneDeep(integration) - $: isGoogleConfigured = !!$organisation.google + $: isGoogleConfigured = !!$organisation.googleDatasourceConfigured onMount(async () => { await organisation.init() diff --git a/packages/builder/src/stores/portal/organisation.js b/packages/builder/src/stores/portal/organisation.js index 486b45642d..ed7dd36636 100644 --- a/packages/builder/src/stores/portal/organisation.js +++ b/packages/builder/src/stores/portal/organisation.js @@ -19,6 +19,7 @@ const DEFAULT_CONFIG = { company: "Budibase", oidc: undefined, google: undefined, + googleDatasourceConfigured: undefined, oidcCallbackUrl: "", googleCallbackUrl: "", isSSOEnforced: false, @@ -39,6 +40,7 @@ export function createOrganisationStore() { const storeConfig = _.cloneDeep(get(store)) delete storeConfig.oidc delete storeConfig.google + delete storeConfig.googleDatasourceConfigured delete storeConfig.oidcCallbackUrl delete storeConfig.googleCallbackUrl await API.saveConfig({ diff --git a/packages/types/src/api/web/global/configs.ts b/packages/types/src/api/web/global/configs.ts index 1476d13cee..b36d974904 100644 --- a/packages/types/src/api/web/global/configs.ts +++ b/packages/types/src/api/web/global/configs.ts @@ -5,6 +5,7 @@ import { SettingsConfig, SettingsInnerConfig } from "../../../documents" */ export interface PublicSettingsInnerConfig extends SettingsInnerConfig { google: boolean + googleDatasourceConfigured: boolean oidc: boolean oidcCallbackUrl: string googleCallbackUrl: string diff --git a/packages/worker/src/api/controllers/global/configs.ts b/packages/worker/src/api/controllers/global/configs.ts index ab63a06ab4..66804c3b9c 100644 --- a/packages/worker/src/api/controllers/global/configs.ts +++ b/packages/worker/src/api/controllers/global/configs.ts @@ -332,6 +332,8 @@ export async function publicSettings( // google const googleConfig = await configs.getGoogleConfig() + const googleDatasourceConfigured = + !!(await configs.getGoogleDatasourceConfig()) const preActivated = googleConfig && googleConfig.activated == null const google = preActivated || !!googleConfig?.activated const _googleCallbackUrl = await googleCallbackUrl(googleConfig) @@ -352,6 +354,7 @@ export async function publicSettings( ...config, ...branding, google, + googleDatasourceConfigured, oidc, isSSOEnforced, oidcCallbackUrl: _oidcCallbackUrl, diff --git a/packages/worker/src/api/routes/global/tests/configs.spec.ts b/packages/worker/src/api/routes/global/tests/configs.spec.ts index 8c31adff2b..193dbf4a59 100644 --- a/packages/worker/src/api/routes/global/tests/configs.spec.ts +++ b/packages/worker/src/api/routes/global/tests/configs.spec.ts @@ -290,6 +290,7 @@ describe("configs", () => { logoUrl: "", analyticsEnabled: false, google: false, + googleDatasourceConfigured: false, googleCallbackUrl: `http://localhost:10000/api/global/auth/${config.tenantId}/google/callback`, isSSOEnforced: false, oidc: false,