Merge pull request #2881 from Budibase/api-keys

Add API keys between account portal and budibase
This commit is contained in:
Rory Powell 2021-10-04 14:17:17 +01:00 committed by GitHub
commit 421f72c4dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 7 deletions

View File

@ -89,6 +89,8 @@ spec:
value: {{ .Values.globals.selfHosted | quote }} value: {{ .Values.globals.selfHosted | quote }}
- name: ACCOUNT_PORTAL_URL - name: ACCOUNT_PORTAL_URL
value: {{ .Values.globals.accountPortalUrl | quote }} value: {{ .Values.globals.accountPortalUrl | quote }}
- name: ACCOUNT_PORTAL_API_KEY
value: {{ .Values.globals.accountPortalApiKey | quote }}
- name: COOKIE_DOMAIN - name: COOKIE_DOMAIN
value: {{ .Values.globals.cookieDomain | quote }} value: {{ .Values.globals.cookieDomain | quote }}
image: budibase/worker image: budibase/worker

View File

@ -90,6 +90,7 @@ globals:
logLevel: info logLevel: info
selfHosted: 1 selfHosted: 1
accountPortalUrL: "" accountPortalUrL: ""
accountPortalApiKey: ""
cookieDomain: "" cookieDomain: ""
createSecrets: true # creates an internal API key, JWT secrets and redis password for you createSecrets: true # creates an internal API key, JWT secrets and redis password for you

View File

@ -1,16 +1,18 @@
const API = require("./api") const API = require("./api")
const env = require("../environment") const env = require("../environment")
const { Headers } = require("../constants")
const api = new API(env.ACCOUNT_PORTAL_URL) const api = new API(env.ACCOUNT_PORTAL_URL)
// TODO: Authorization
exports.getAccount = async email => { exports.getAccount = async email => {
const payload = { const payload = {
email, email,
} }
const response = await api.post(`/api/accounts/search`, { const response = await api.post(`/api/accounts/search`, {
body: payload, body: payload,
headers: {
[Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
},
}) })
const json = await response.json() const json = await response.json()

View File

@ -21,6 +21,7 @@ module.exports = {
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
MULTI_TENANCY: process.env.MULTI_TENANCY, MULTI_TENANCY: process.env.MULTI_TENANCY,
ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL, ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,
ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY,
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL, DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED), SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN, COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,

View File

@ -7,6 +7,7 @@ exports.buildMatcherRegex = patterns => {
return patterns.map(pattern => { return patterns.map(pattern => {
const isObj = typeof pattern === "object" && pattern.route const isObj = typeof pattern === "object" && pattern.route
const method = isObj ? pattern.method : "GET" const method = isObj ? pattern.method : "GET"
const strict = pattern.strict ? pattern.strict : false
let route = isObj ? pattern.route : pattern let route = isObj ? pattern.route : pattern
const matches = route.match(PARAM_REGEX) const matches = route.match(PARAM_REGEX)
@ -16,13 +17,19 @@ exports.buildMatcherRegex = patterns => {
route = route.replace(match, pattern) route = route.replace(match, pattern)
} }
} }
return { regex: new RegExp(route), method } return { regex: new RegExp(route), method, strict, route }
}) })
} }
exports.matches = (ctx, options) => { exports.matches = (ctx, options) => {
return options.find(({ regex, method }) => { return options.find(({ regex, method, strict, route }) => {
const urlMatch = regex.test(ctx.request.url) let urlMatch
if (strict) {
urlMatch = ctx.request.url === route
} else {
urlMatch = regex.test(ctx.request.url)
}
const methodMatch = const methodMatch =
method === "ALL" method === "ALL"
? true ? true

View File

@ -205,9 +205,13 @@ module External {
} else { } else {
// we're not inserting a doc, will be a bunch of update calls // we're not inserting a doc, will be a bunch of update calls
const isUpdate = !field.through const isUpdate = !field.through
const thisKey: string = isUpdate ? "id" : (field.throughTo || linkTablePrimary) const thisKey: string = isUpdate
? "id"
: field.throughTo || linkTablePrimary
// @ts-ignore // @ts-ignore
const otherKey: string = isUpdate ? field.fieldName : (field.throughFrom || tablePrimary) const otherKey: string = isUpdate
? field.fieldName
: field.throughFrom || tablePrimary
row[key].map((relationship: any) => { row[key].map((relationship: any) => {
// we don't really support composite keys for relationships, this is why [0] is used // we don't really support composite keys for relationships, this is why [0] is used
manyRelationships.push({ manyRelationships.push({

View File

@ -23,6 +23,7 @@ async function init() {
MULTI_TENANCY: "", MULTI_TENANCY: "",
DISABLE_ACCOUNT_PORTAL: "", DISABLE_ACCOUNT_PORTAL: "",
ACCOUNT_PORTAL_URL: "http://localhost:10001", ACCOUNT_PORTAL_URL: "http://localhost:10001",
ACCOUNT_PORTAL_API_KEY: "budibase",
PLATFORM_URL: "http://localhost:10000", PLATFORM_URL: "http://localhost:10000",
} }
let envFile = "" let envFile = ""

View File

@ -3,6 +3,7 @@ const controller = require("../../controllers/global/users")
const joiValidator = require("../../../middleware/joi-validator") const joiValidator = require("../../../middleware/joi-validator")
const adminOnly = require("../../../middleware/adminOnly") const adminOnly = require("../../../middleware/adminOnly")
const Joi = require("joi") const Joi = require("joi")
const cloudRestricted = require("../../../middleware/cloudRestricted")
const router = Router() const router = Router()
@ -90,6 +91,7 @@ router
) )
.post( .post(
"/api/global/users/init", "/api/global/users/init",
cloudRestricted,
buildAdminInitValidation(), buildAdminInitValidation(),
controller.adminUser controller.adminUser
) )

View File

@ -0,0 +1,17 @@
const env = require("../environment")
const { Headers } = require("@budibase/auth").constants
/**
* This is a restricted endpoint in the cloud.
* Ensure that the correct API key has been supplied.
*/
module.exports = async (ctx, next) => {
if (!env.SELF_HOSTED) {
const apiKey = ctx.request.headers[Headers.API_KEY]
if (apiKey !== env.INTERNAL_API_KEY) {
ctx.throw(403, "Unauthorized")
}
}
return next()
}