From dc940d33dbf75605a5fbb7e3b9e0bd9a7695ecbc Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 28 Mar 2022 12:03:44 +0100 Subject: [PATCH 1/3] fix launch.json --- .vscode/launch.json | 11 +++++- .../middleware/passport/datasource/google.js | 37 ++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 34951b6310..8cb49d5825 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -22,9 +22,16 @@ "name": "Budibase Worker", "type": "node", "request": "launch", - "program": "${workspaceFolder}/packages/worker/src/index.js", + "runtimeArgs": [ + "--nolazy", + "-r", + "ts-node/register/transpile-only" + ], + "args": [ + "${workspaceFolder}/packages/worker/src/index.ts" + ], "cwd": "${workspaceFolder}/packages/worker" - } + }, ], "compounds": [ { diff --git a/packages/backend-core/src/middleware/passport/datasource/google.js b/packages/backend-core/src/middleware/passport/datasource/google.js index c7553cee50..62d626a30c 100644 --- a/packages/backend-core/src/middleware/passport/datasource/google.js +++ b/packages/backend-core/src/middleware/passport/datasource/google.js @@ -1,15 +1,37 @@ const google = require("../google") -const { Cookies } = require("../../../constants") +const { Cookies, Configs } = require("../../../constants") const { clearCookie, getCookie } = require("../../../utils") const { getDB } = require("../../../db") +const { getScopedConfig } = require("../../../db/utils") const environment = require("../../../environment") +const { getGlobalDB } = require("../../../tenancy") + +async function fetchGoogleCreds() { + let config + + // try and get the config from the tenant + const db = getGlobalDB() + const googleConfig = await getScopedConfig(db, { + type: Configs.GOOGLE, + }) + if (googleConfig.clientID && googleConfig.clientSecret) { + config = googleConfig + } + + // fall back to env variables + if (!config) { + config = { + clientID: environment.GOOGLE_CLIENT_ID, + clientSecret: environment.GOOGLE_CLIENT_SECRET, + } + } + + return googleConfig +} async function preAuth(passport, ctx, next) { // get the relevant config - const googleConfig = { - clientID: environment.GOOGLE_CLIENT_ID, - clientSecret: environment.GOOGLE_CLIENT_SECRET, - } + const googleConfig = await fetchGoogleCreds() let callbackUrl = `${environment.PLATFORM_URL}/api/global/auth/datasource/google/callback` const strategy = await google.strategyFactory(googleConfig, callbackUrl) @@ -26,10 +48,7 @@ async function preAuth(passport, ctx, next) { async function postAuth(passport, ctx, next) { // get the relevant config - const config = { - clientID: environment.GOOGLE_CLIENT_ID, - clientSecret: environment.GOOGLE_CLIENT_SECRET, - } + const config = await fetchGoogleCreds() let callbackUrl = `${environment.PLATFORM_URL}/api/global/auth/datasource/google/callback` const strategy = await google.strategyFactory( From aed9bfc7283fee4f928b1226583d3b3038e786a7 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 28 Mar 2022 16:44:33 +0100 Subject: [PATCH 2/3] fixing google sheets bug, respect google configuration hierarchy --- .../templates/app-service-deployment.yaml | 4 ++++ .../middleware/passport/datasource/google.js | 18 +++++------------- .../src/middleware/passport/google.js | 5 ++++- .../TableIntegrationMenu/PlusConfigForm.svelte | 6 ++++++ .../server/src/api/controllers/integration.js | 18 +++++++++++++++++- packages/server/src/environment.js | 2 ++ .../server/src/integrations/googlesheets.ts | 17 ++++++++++++++++- packages/server/src/integrations/index.ts | 8 ++++---- 8 files changed, 58 insertions(+), 20 deletions(-) diff --git a/charts/budibase/templates/app-service-deployment.yaml b/charts/budibase/templates/app-service-deployment.yaml index d9def8c641..86e255d331 100644 --- a/charts/budibase/templates/app-service-deployment.yaml +++ b/charts/budibase/templates/app-service-deployment.yaml @@ -110,6 +110,10 @@ spec: value: {{ .Values.globals.cookieDomain | quote }} - name: HTTP_MIGRATIONS value: {{ .Values.globals.httpMigrations | quote }} + - name: GOOGLE_CLIENT_ID + value: {{ .Values.globals.google.clientId | quote }} + - name: GOOGLE_CLIENT_SECRET + value: {{ .Values.globals.google.secret | quote }} image: budibase/apps:{{ .Values.globals.appVersion }} imagePullPolicy: Always name: bbapps diff --git a/packages/backend-core/src/middleware/passport/datasource/google.js b/packages/backend-core/src/middleware/passport/datasource/google.js index 62d626a30c..5046815b1f 100644 --- a/packages/backend-core/src/middleware/passport/datasource/google.js +++ b/packages/backend-core/src/middleware/passport/datasource/google.js @@ -7,26 +7,18 @@ const environment = require("../../../environment") const { getGlobalDB } = require("../../../tenancy") async function fetchGoogleCreds() { - let config - // try and get the config from the tenant const db = getGlobalDB() const googleConfig = await getScopedConfig(db, { type: Configs.GOOGLE, }) - if (googleConfig.clientID && googleConfig.clientSecret) { - config = googleConfig + // or fall back to env variables + const config = googleConfig || { + clientID: environment.GOOGLE_CLIENT_ID, + clientSecret: environment.GOOGLE_CLIENT_SECRET, } - // fall back to env variables - if (!config) { - config = { - clientID: environment.GOOGLE_CLIENT_ID, - clientSecret: environment.GOOGLE_CLIENT_SECRET, - } - } - - return googleConfig + return config } async function preAuth(passport, ctx, next) { diff --git a/packages/backend-core/src/middleware/passport/google.js b/packages/backend-core/src/middleware/passport/google.js index cb93844c31..8fd0961ea1 100644 --- a/packages/backend-core/src/middleware/passport/google.js +++ b/packages/backend-core/src/middleware/passport/google.js @@ -51,7 +51,10 @@ exports.strategyFactory = async function ( ) } catch (err) { console.error(err) - throw new Error("Error constructing google authentication strategy", err) + throw new Error( + `Error constructing google authentication strategy: ${err}`, + err + ) } } // expose for testing diff --git a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/PlusConfigForm.svelte b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/PlusConfigForm.svelte index c94e750c29..66d7d43841 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/PlusConfigForm.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/PlusConfigForm.svelte @@ -15,6 +15,7 @@ import ArrayRenderer from "components/common/renderers/ArrayRenderer.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte" import { goto } from "@roxi/routify" + import GoogleButton from "../_components/GoogleButton.svelte" export let datasource export let save @@ -160,6 +161,11 @@ Fetch tables + {#if integration.auth} + {#if integration.auth.type === "google"} + + {/if} + {/if} diff --git a/packages/server/src/api/controllers/integration.js b/packages/server/src/api/controllers/integration.js index 75fd9ce80e..f3f3309c02 100644 --- a/packages/server/src/api/controllers/integration.js +++ b/packages/server/src/api/controllers/integration.js @@ -1,8 +1,24 @@ +const { cloneDeep } = require("lodash") const { definitions } = require("../../integrations") +const { getTenantId } = require("@budibase/backend-core/tenancy") +const { SourceNames } = require("../../definitions/datasource") +const googlesheets = require("../../integrations/googlesheets") +const env = require("../../environment") exports.fetch = async function (ctx) { ctx.status = 200 - ctx.body = definitions + const defs = cloneDeep(definitions) + + // for google sheets integration google verification + if (env.EXCLUDE_QUOTAS_TENANTS) { + const excludedTenants = env.EXCLUDE_QUOTAS_TENANTS.split(",") + const tenantId = getTenantId() + if (excludedTenants.includes(tenantId)) { + defs[SourceNames.GOOGLE_SHEETS] = googlesheets.schema + } + } + + ctx.body = defs } exports.find = async function (ctx) { diff --git a/packages/server/src/environment.js b/packages/server/src/environment.js index 212a54b87c..bdbbbde79f 100644 --- a/packages/server/src/environment.js +++ b/packages/server/src/environment.js @@ -46,6 +46,8 @@ module.exports = { MULTI_TENANCY: process.env.MULTI_TENANCY, HTTP_MIGRATIONS: process.env.HTTP_MIGRATIONS, API_REQ_LIMIT_PER_SEC: process.env.API_REQ_LIMIT_PER_SEC, + GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID, + GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET, // environment NODE_ENV: process.env.NODE_ENV, JEST_WORKER_ID: process.env.JEST_WORKER_ID, diff --git a/packages/server/src/integrations/googlesheets.ts b/packages/server/src/integrations/googlesheets.ts index bb2de26f5d..c58fdea551 100644 --- a/packages/server/src/integrations/googlesheets.ts +++ b/packages/server/src/integrations/googlesheets.ts @@ -10,6 +10,7 @@ import { Table, TableSchema } from "../definitions/common" import { buildExternalTableId } from "./utils" import { DataSourceOperation, FieldTypes } from "../constants" import { GoogleSpreadsheet } from "google-spreadsheet" +import env from "../environment" module GoogleSheetsModule { const { getGlobalDB } = require("@budibase/backend-core/tenancy") @@ -138,13 +139,27 @@ module GoogleSheetsModule { try { // Initialise oAuth client const db = getGlobalDB() - const googleConfig = await getScopedConfig(db, { + let googleConfig = await getScopedConfig(db, { type: Configs.GOOGLE, }) + + if (!googleConfig) { + googleConfig = { + clientID: env.GOOGLE_CLIENT_ID, + clientSecret: env.GOOGLE_CLIENT_SECRET, + } + } + const oauthClient = new OAuth2Client({ clientId: googleConfig.clientID, clientSecret: googleConfig.clientSecret, }) + oauthClient.on("tokens", tokens => { + oauthClient.setCredentials({ + refresh_token: googleConfig.refreshToken, + access_token: tokens.access_token, + }) + }) oauthClient.credentials.access_token = this.config.auth.accessToken oauthClient.credentials.refresh_token = this.config.auth.refreshToken this.client.useOAuth2Client(oauthClient) diff --git a/packages/server/src/integrations/index.ts b/packages/server/src/integrations/index.ts index 07f3211fcb..3f5471d332 100644 --- a/packages/server/src/integrations/index.ts +++ b/packages/server/src/integrations/index.ts @@ -42,6 +42,7 @@ const INTEGRATIONS = { [SourceNames.ARANGODB]: arangodb.integration, [SourceNames.REST]: rest.integration, [SourceNames.FIREBASE]: firebase.integration, + [SourceNames.GOOGLE_SHEETS]: googlesheets.integration, } // optionally add oracle integration if the oracle binary can be installed @@ -51,10 +52,9 @@ if (!(process.arch === "arm64" && process.platform === "darwin")) { INTEGRATIONS[SourceNames.ORACLE] = oracle.integration } -if (environment.SELF_HOSTED) { - DEFINITIONS[SourceNames.GOOGLE_SHEETS] = googlesheets.schema - INTEGRATIONS[SourceNames.GOOGLE_SHEETS] = googlesheets.integration -} +// if (environment.SELF_HOSTED) { +// DEFINITIONS[SourceNames.GOOGLE_SHEETS] = googlesheets.schema +// } module.exports = { definitions: DEFINITIONS, From 457a4812cfefaccac016d92d3f8c8ab9569694ae Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 28 Mar 2022 16:46:05 +0100 Subject: [PATCH 3/3] re-add gsheets to self host --- packages/server/src/integrations/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server/src/integrations/index.ts b/packages/server/src/integrations/index.ts index 3f5471d332..0a892d7317 100644 --- a/packages/server/src/integrations/index.ts +++ b/packages/server/src/integrations/index.ts @@ -52,9 +52,9 @@ if (!(process.arch === "arm64" && process.platform === "darwin")) { INTEGRATIONS[SourceNames.ORACLE] = oracle.integration } -// if (environment.SELF_HOSTED) { -// DEFINITIONS[SourceNames.GOOGLE_SHEETS] = googlesheets.schema -// } +if (environment.SELF_HOSTED) { + DEFINITIONS[SourceNames.GOOGLE_SHEETS] = googlesheets.schema +} module.exports = { definitions: DEFINITIONS,