Browse Source
Merge pull request #2881 from Budibase/api-keys
Add API keys between account portal and budibase
gh-pages
Rory Powell
5 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with
44 additions and
7 deletions
-
hosting/kubernetes/budibase/templates/worker-service-deployment.yaml
-
hosting/kubernetes/budibase/values.yaml
-
packages/auth/src/cloud/accounts.js
-
packages/auth/src/environment.js
-
packages/auth/src/middleware/matchers.js
-
packages/server/src/api/controllers/row/ExternalRequest.ts
-
packages/worker/scripts/dev/manage.js
-
packages/worker/src/api/routes/global/users.js
-
packages/worker/src/middleware/cloudRestricted.js
|
|
|
@ -89,6 +89,8 @@ spec: |
|
|
|
value: {{ .Values.globals.selfHosted | quote }} |
|
|
|
- name: ACCOUNT_PORTAL_URL |
|
|
|
value: {{ .Values.globals.accountPortalUrl | quote }} |
|
|
|
- name: ACCOUNT_PORTAL_API_KEY |
|
|
|
value: {{ .Values.globals.accountPortalApiKey | quote }} |
|
|
|
- name: COOKIE_DOMAIN |
|
|
|
value: {{ .Values.globals.cookieDomain | quote }} |
|
|
|
image: budibase/worker |
|
|
|
|
|
|
|
@ -90,6 +90,7 @@ globals: |
|
|
|
logLevel: info |
|
|
|
selfHosted: 1 |
|
|
|
accountPortalUrL: "" |
|
|
|
accountPortalApiKey: "" |
|
|
|
cookieDomain: "" |
|
|
|
createSecrets: true # creates an internal API key, JWT secrets and redis password for you |
|
|
|
|
|
|
|
|
|
|
|
@ -1,16 +1,18 @@ |
|
|
|
const API = require("./api") |
|
|
|
const env = require("../environment") |
|
|
|
const { Headers } = require("../constants") |
|
|
|
|
|
|
|
const api = new API(env.ACCOUNT_PORTAL_URL) |
|
|
|
|
|
|
|
// TODO: Authorization
|
|
|
|
|
|
|
|
exports.getAccount = async email => { |
|
|
|
const payload = { |
|
|
|
email, |
|
|
|
} |
|
|
|
const response = await api.post(`/api/accounts/search`, { |
|
|
|
body: payload, |
|
|
|
headers: { |
|
|
|
[Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY, |
|
|
|
}, |
|
|
|
}) |
|
|
|
const json = await response.json() |
|
|
|
|
|
|
|
|
|
|
|
@ -21,6 +21,7 @@ module.exports = { |
|
|
|
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, |
|
|
|
MULTI_TENANCY: process.env.MULTI_TENANCY, |
|
|
|
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, |
|
|
|
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED), |
|
|
|
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN, |
|
|
|
|
|
|
|
@ -7,6 +7,7 @@ exports.buildMatcherRegex = patterns => { |
|
|
|
return patterns.map(pattern => { |
|
|
|
const isObj = typeof pattern === "object" && pattern.route |
|
|
|
const method = isObj ? pattern.method : "GET" |
|
|
|
const strict = pattern.strict ? pattern.strict : false |
|
|
|
let route = isObj ? pattern.route : pattern |
|
|
|
|
|
|
|
const matches = route.match(PARAM_REGEX) |
|
|
|
@ -16,13 +17,19 @@ exports.buildMatcherRegex = patterns => { |
|
|
|
route = route.replace(match, pattern) |
|
|
|
} |
|
|
|
} |
|
|
|
return { regex: new RegExp(route), method } |
|
|
|
return { regex: new RegExp(route), method, strict, route } |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
exports.matches = (ctx, options) => { |
|
|
|
return options.find(({ regex, method }) => { |
|
|
|
const urlMatch = regex.test(ctx.request.url) |
|
|
|
return options.find(({ regex, method, strict, route }) => { |
|
|
|
let urlMatch |
|
|
|
if (strict) { |
|
|
|
urlMatch = ctx.request.url === route |
|
|
|
} else { |
|
|
|
urlMatch = regex.test(ctx.request.url) |
|
|
|
} |
|
|
|
|
|
|
|
const methodMatch = |
|
|
|
method === "ALL" |
|
|
|
? true |
|
|
|
|
|
|
|
@ -205,9 +205,13 @@ module External { |
|
|
|
} else { |
|
|
|
// we're not inserting a doc, will be a bunch of update calls
|
|
|
|
const isUpdate = !field.through |
|
|
|
const thisKey: string = isUpdate ? "id" : (field.throughTo || linkTablePrimary) |
|
|
|
const thisKey: string = isUpdate |
|
|
|
? "id" |
|
|
|
: field.throughTo || linkTablePrimary |
|
|
|
// @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) => { |
|
|
|
// we don't really support composite keys for relationships, this is why [0] is used
|
|
|
|
manyRelationships.push({ |
|
|
|
|
|
|
|
@ -23,6 +23,7 @@ async function init() { |
|
|
|
MULTI_TENANCY: "", |
|
|
|
DISABLE_ACCOUNT_PORTAL: "", |
|
|
|
ACCOUNT_PORTAL_URL: "http://localhost:10001", |
|
|
|
ACCOUNT_PORTAL_API_KEY: "budibase", |
|
|
|
PLATFORM_URL: "http://localhost:10000", |
|
|
|
} |
|
|
|
let envFile = "" |
|
|
|
|
|
|
|
@ -3,6 +3,7 @@ const controller = require("../../controllers/global/users") |
|
|
|
const joiValidator = require("../../../middleware/joi-validator") |
|
|
|
const adminOnly = require("../../../middleware/adminOnly") |
|
|
|
const Joi = require("joi") |
|
|
|
const cloudRestricted = require("../../../middleware/cloudRestricted") |
|
|
|
|
|
|
|
const router = Router() |
|
|
|
|
|
|
|
@ -90,6 +91,7 @@ router |
|
|
|
) |
|
|
|
.post( |
|
|
|
"/api/global/users/init", |
|
|
|
cloudRestricted, |
|
|
|
buildAdminInitValidation(), |
|
|
|
controller.adminUser |
|
|
|
) |
|
|
|
|
|
|
|
@ -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() |
|
|
|
} |