more flexible datasource auth config
This commit is contained in:
parent
857d1f7c0b
commit
20cb3d8f2c
|
@ -7,6 +7,7 @@ exports.Cookies = {
|
||||||
CurrentApp: "budibase:currentapp",
|
CurrentApp: "budibase:currentapp",
|
||||||
Auth: "budibase:auth",
|
Auth: "budibase:auth",
|
||||||
Init: "budibase:init",
|
Init: "budibase:init",
|
||||||
|
DatasourceAuth: "budibase:datasourceauth",
|
||||||
OIDC_CONFIG: "budibase:oidc:config",
|
OIDC_CONFIG: "budibase:oidc:config",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ const authenticated = require("./authenticated")
|
||||||
const auditLog = require("./auditLog")
|
const auditLog = require("./auditLog")
|
||||||
const tenancy = require("./tenancy")
|
const tenancy = require("./tenancy")
|
||||||
const appTenancy = require("./appTenancy")
|
const appTenancy = require("./appTenancy")
|
||||||
|
const datasourceGoogle = require("./passport/datasource/google")
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
google,
|
google,
|
||||||
|
@ -18,4 +19,7 @@ module.exports = {
|
||||||
tenancy,
|
tenancy,
|
||||||
appTenancy,
|
appTenancy,
|
||||||
authError,
|
authError,
|
||||||
|
datasource: {
|
||||||
|
google: datasourceGoogle,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
const { getScopedConfig } = require("../../../db/utils")
|
||||||
|
const { getGlobalDB } = require("../../../tenancy")
|
||||||
|
const google = require("../google")
|
||||||
|
const { Configs, Cookies } = require("../../../constants")
|
||||||
|
const { clearCookie, getCookie } = require("../../../utils")
|
||||||
|
const { getDB } = require("../../../db")
|
||||||
|
|
||||||
|
async function preAuth(passport, ctx, next) {
|
||||||
|
const db = getGlobalDB()
|
||||||
|
// get the relevant config
|
||||||
|
const config = await getScopedConfig(db, {
|
||||||
|
type: Configs.GOOGLE,
|
||||||
|
workspace: ctx.query.workspace,
|
||||||
|
})
|
||||||
|
const publicConfig = await getScopedConfig(db, {
|
||||||
|
type: Configs.SETTINGS,
|
||||||
|
})
|
||||||
|
let callbackUrl = `${publicConfig.platformUrl}/api/global/auth/datasource/google/callback`
|
||||||
|
const strategy = await google.strategyFactory(config, callbackUrl)
|
||||||
|
|
||||||
|
if (!ctx.query.appId || !ctx.query.datasourceId) {
|
||||||
|
ctx.throw(400, "appId and datasourceId query params not present.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: prob update - shouldn't include the google sheets scopes here
|
||||||
|
return passport.authenticate(strategy, {
|
||||||
|
scope: ["profile", "email", "https://www.googleapis.com/auth/spreadsheets"],
|
||||||
|
})(ctx, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function postAuth(passport, ctx, next) {
|
||||||
|
const db = getGlobalDB()
|
||||||
|
|
||||||
|
const config = await getScopedConfig(db, {
|
||||||
|
type: Configs.GOOGLE,
|
||||||
|
workspace: ctx.query.workspace,
|
||||||
|
})
|
||||||
|
|
||||||
|
const publicConfig = await getScopedConfig(db, {
|
||||||
|
type: Configs.SETTINGS,
|
||||||
|
})
|
||||||
|
|
||||||
|
let callbackUrl = `${publicConfig.platformUrl}/api/global/auth/datasource/google/callback`
|
||||||
|
const strategy = await google.strategyFactory(
|
||||||
|
config,
|
||||||
|
callbackUrl,
|
||||||
|
(accessToken, refreshToken, profile, done) => {
|
||||||
|
clearCookie(ctx, Cookies.DatasourceAuth)
|
||||||
|
done(null, { accessToken, refreshToken })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const authStateCookie = getCookie(ctx, Cookies.DatasourceAuth)
|
||||||
|
|
||||||
|
return passport.authenticate(
|
||||||
|
strategy,
|
||||||
|
{ successRedirect: "/", failureRedirect: "/error" },
|
||||||
|
async (err, tokens) => {
|
||||||
|
// update the DB for the datasource with all the user info
|
||||||
|
const db = getDB(authStateCookie.appId)
|
||||||
|
const datasource = await db.get(authStateCookie.datasourceId)
|
||||||
|
datasource.config = {
|
||||||
|
auth: {
|
||||||
|
type: "google",
|
||||||
|
...tokens,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
await db.put(datasource)
|
||||||
|
ctx.redirect(
|
||||||
|
`/builder/app/${authStateCookie.appId}/data/datasource/${authStateCookie.datasourceId}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)(ctx, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.preAuth = preAuth
|
||||||
|
exports.postAuth = postAuth
|
|
@ -12,9 +12,8 @@
|
||||||
<ActionButton
|
<ActionButton
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
const datasource = await preAuthStep()
|
const datasource = await preAuthStep()
|
||||||
console.log(datasource)
|
|
||||||
window.open(
|
window.open(
|
||||||
`/api/global/auth/${tenantId}/google2?datasourceId=${datasource._id}&appId=${$store.appId}`,
|
`/api/global/auth/${tenantId}/datasource/google?datasourceId=${datasource._id}&appId=${$store.appId}`,
|
||||||
"_blank"
|
"_blank"
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -9,8 +9,11 @@ const { Thread, ThreadType } = require("../../../threads")
|
||||||
const { save: saveDatasource } = require("../datasource")
|
const { save: saveDatasource } = require("../datasource")
|
||||||
const { RestImporter } = require("./import")
|
const { RestImporter } = require("./import")
|
||||||
const { invalidateDynamicVariables } = require("../../../threads/utils")
|
const { invalidateDynamicVariables } = require("../../../threads/utils")
|
||||||
|
const environment = require("../../../environment")
|
||||||
|
|
||||||
const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 })
|
const Runner = new Thread(ThreadType.QUERY, {
|
||||||
|
timeoutMs: 10000 || environment.QUERY_THREAD_TIMEOUT,
|
||||||
|
})
|
||||||
|
|
||||||
// simple function to append "readable" to all read queries
|
// simple function to append "readable" to all read queries
|
||||||
function enrichQueries(input) {
|
function enrichQueries(input) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ const {
|
||||||
isMultiTenant,
|
isMultiTenant,
|
||||||
} = require("@budibase/backend-core/tenancy")
|
} = require("@budibase/backend-core/tenancy")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
const CouchDB = require("../../../db")
|
|
||||||
|
|
||||||
const ssoCallbackUrl = async (config, type) => {
|
const ssoCallbackUrl = async (config, type) => {
|
||||||
// incase there is a callback URL from before
|
// incase there is a callback URL from before
|
||||||
|
@ -146,78 +145,30 @@ exports.logout = async ctx => {
|
||||||
ctx.body = { message: "User logged out." }
|
ctx.body = { message: "User logged out." }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
exports.datasourcePreAuth = async (ctx, next) => {
|
||||||
* The initial call that google authentication makes to take you to the google login screen.
|
const provider = ctx.params.provider
|
||||||
* On a successful login, you will be redirected to the googleAuth callback route.
|
const middleware = require(`@budibase/backend-core/middleware`)
|
||||||
*/
|
const handler = middleware.datasource[provider]
|
||||||
exports.googlePreAuth2 = async (ctx, next) => {
|
|
||||||
const db = getGlobalDB()
|
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
|
||||||
type: Configs.GOOGLE,
|
|
||||||
workspace: ctx.query.workspace,
|
|
||||||
})
|
|
||||||
// let callbackUrl = await exports.googleCallbackUrl(config)
|
|
||||||
// TODO: Hardcoded - fix
|
|
||||||
let callbackUrl = "http://localhost:10000/api/global/auth/google2/callback"
|
|
||||||
const strategy = await google.strategyFactory(config, callbackUrl)
|
|
||||||
|
|
||||||
// TODO: fix
|
|
||||||
setCookie(
|
setCookie(
|
||||||
ctx,
|
ctx,
|
||||||
{
|
{
|
||||||
|
provider,
|
||||||
appId: ctx.query.appId,
|
appId: ctx.query.appId,
|
||||||
datasourceId: ctx.query.datasourceId,
|
datasourceId: ctx.query.datasourceId,
|
||||||
},
|
},
|
||||||
"AuthCallback"
|
Cookies.DatasourceAuth
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: prob update - shouldn't include the google sheets scopes here
|
return handler.preAuth(passport, ctx, next)
|
||||||
return passport.authenticate(strategy, {
|
|
||||||
scope: ["profile", "email", "https://www.googleapis.com/auth/spreadsheets"],
|
|
||||||
})(ctx, next)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.googleAuth2 = async (ctx, next) => {
|
exports.datasourceAuth = async (ctx, next) => {
|
||||||
const db = getGlobalDB()
|
const authStateCookie = getCookie(ctx, Cookies.DatasourceAuth)
|
||||||
|
const provider = authStateCookie.provider
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const middleware = require(`@budibase/backend-core/middleware`)
|
||||||
type: Configs.GOOGLE,
|
const handler = middleware.datasource[provider]
|
||||||
workspace: ctx.query.workspace,
|
return handler.postAuth(passport, ctx, next)
|
||||||
})
|
|
||||||
// const callbackUrl = await exports.googleCallbackUrl(config)
|
|
||||||
const authStateCookie = getCookie(ctx, "AuthCallback")
|
|
||||||
|
|
||||||
// TODO: correct callback URL
|
|
||||||
let callbackUrl = "http://localhost:10000/api/global/auth/google2/callback"
|
|
||||||
const strategy = await google.strategyFactory(
|
|
||||||
config,
|
|
||||||
callbackUrl,
|
|
||||||
(accessToken, refreshToken, profile, done) => {
|
|
||||||
clearCookie(ctx, "AuthCallback")
|
|
||||||
done(null, { accessToken, refreshToken })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return passport.authenticate(
|
|
||||||
strategy,
|
|
||||||
{ successRedirect: "/", failureRedirect: "/error" },
|
|
||||||
async (err, tokens) => {
|
|
||||||
// update the DB for the datasource with all the user info
|
|
||||||
const db = new CouchDB(authStateCookie.appId)
|
|
||||||
const datasource = await db.get(authStateCookie.datasourceId)
|
|
||||||
datasource.config = {
|
|
||||||
auth: {
|
|
||||||
type: "google",
|
|
||||||
...tokens,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
await db.put(datasource)
|
|
||||||
ctx.redirect(
|
|
||||||
`/builder/app/${authStateCookie.appId}/data/datasource/${authStateCookie.datasourceId}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)(ctx, next)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -64,14 +64,16 @@ router
|
||||||
authController.googlePreAuth
|
authController.googlePreAuth
|
||||||
)
|
)
|
||||||
.get(
|
.get(
|
||||||
"/api/global/auth/:tenantId/google2",
|
"/api/global/auth/:tenantId/datasource/:provider",
|
||||||
updateTenant,
|
updateTenant,
|
||||||
authController.googlePreAuth2
|
authController.datasourcePreAuth
|
||||||
)
|
)
|
||||||
// single tenancy endpoint
|
// single tenancy endpoint
|
||||||
.get("/api/global/auth/google/callback", authController.googleAuth)
|
.get("/api/global/auth/google/callback", authController.googleAuth)
|
||||||
// TODO: Remove
|
.get(
|
||||||
.get("/api/global/auth/google2/callback", authController.googleAuth2)
|
"/api/global/auth/datasource/:provider/callback",
|
||||||
|
authController.datasourceAuth
|
||||||
|
)
|
||||||
// multi-tenancy endpoint
|
// multi-tenancy endpoint
|
||||||
.get(
|
.get(
|
||||||
"/api/global/auth/:tenantId/google/callback",
|
"/api/global/auth/:tenantId/google/callback",
|
||||||
|
|
Loading…
Reference in New Issue