Adding in self hosted API key.

This commit is contained in:
mike12345567 2020-12-09 17:04:05 +00:00
parent 3c2ca11d31
commit bc5f520a03
6 changed files with 79 additions and 8 deletions

View File

@ -9,6 +9,7 @@ const env = require("./environment")
const eventEmitter = require("./events") const eventEmitter = require("./events")
const automations = require("./automations/index") const automations = require("./automations/index")
const Sentry = require("@sentry/node") const Sentry = require("@sentry/node")
const selfhost = require("./selfhost")
const app = new Koa() const app = new Koa()
@ -49,9 +50,12 @@ destroyable(server)
server.on("close", () => console.log("Server Closed")) server.on("close", () => console.log("Server Closed"))
module.exports = server.listen(env.PORT || 4001, () => { module.exports = server.listen(env.PORT || 4001, async () => {
console.log(`Budibase running on ${JSON.stringify(server.address())}`) console.log(`Budibase running on ${JSON.stringify(server.address())}`)
automations.init() automations.init()
if (env.SELF_HOSTED) {
await selfhost.init()
}
}) })
process.on("uncaughtException", err => { process.on("uncaughtException", err => {

View File

@ -7,7 +7,7 @@ const {
doesHavePermission, doesHavePermission,
} = require("../utilities/security/permissions") } = require("../utilities/security/permissions")
const env = require("../environment") const env = require("../environment")
const { apiKeyTable } = require("../db/dynamoClient") const { getAPIKey } = require("../utilities/security/apikey")
const { AuthTypes } = require("../constants") const { AuthTypes } = require("../constants")
const ADMIN_ROLES = [BUILTIN_ROLE_IDS.ADMIN, BUILTIN_ROLE_IDS.BUILDER] const ADMIN_ROLES = [BUILTIN_ROLE_IDS.ADMIN, BUILTIN_ROLE_IDS.BUILDER]
@ -21,9 +21,7 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
} }
if (env.CLOUD && ctx.headers["x-api-key"] && ctx.headers["x-instanceid"]) { if (env.CLOUD && ctx.headers["x-api-key"] && ctx.headers["x-instanceid"]) {
// api key header passed by external webhook // api key header passed by external webhook
const apiKeyInfo = await apiKeyTable.get({ const apiKeyInfo = await getAPIKey(ctx.headers["x-api-key"])
primary: ctx.headers["x-api-key"],
})
if (apiKeyInfo) { if (apiKeyInfo) {
ctx.auth = { ctx.auth = {

View File

@ -43,6 +43,10 @@ module.exports = async (ctx, next) => {
return return
} }
} }
// if running in builder or a self hosted cloud usage quotas should not be executed
if (!env.CLOUD || env.SELF_HOSTED) {
return next()
}
// update usage for uploads to be the total size // update usage for uploads to be the total size
if (property === usageQuota.Properties.UPLOAD) { if (property === usageQuota.Properties.UPLOAD) {
const files = const files =
@ -51,9 +55,6 @@ module.exports = async (ctx, next) => {
: [ctx.request.files.file] : [ctx.request.files.file]
usage = files.map(file => file.size).reduce((total, size) => total + size) usage = files.map(file => file.size).reduce((total, size) => total + size)
} }
if (!env.CLOUD) {
return next()
}
try { try {
await usageQuota.update(ctx.auth.apiKey, property, usage) await usageQuota.update(ctx.auth.apiKey, property, usage)
return next() return next()

View File

@ -0,0 +1,7 @@
### Self hosting
This directory contains utilities that are needed for self hosted platforms to operate.
These will mostly be utilities, necessary to the operation of the server e.g. storing self
hosting specific options and attributes to CouchDB.
All the internal operations should be exposed through the `index.js` so importing
the self host directory should give you everything you need.

View File

@ -0,0 +1,39 @@
const CouchDB = require("../db")
const env = require("../environment")
const newid = require("../db/newid")
const SELF_HOST_DB = "self-host-db"
const SELF_HOST_DOC = "self-host-info"
async function createSelfHostDB(db) {
await db.put({
_id: "_design/database",
views: {},
})
const selfHostInfo = {
_id: SELF_HOST_DOC,
apiKeyId: newid(),
}
await db.put(selfHostInfo)
return selfHostInfo
}
exports.init = async () => {
if (!env.SELF_HOSTED) {
return
}
const db = new CouchDB(SELF_HOST_DB)
try {
await db.get(SELF_HOST_DOC)
} catch (err) {
// failed to retrieve
if (err.status === 404) {
await createSelfHostDB(db)
}
}
}
exports.getSelfHostInfo = async () => {
const db = new CouchDB(SELF_HOST_DB)
return db.get(SELF_HOST_DOC)
}

View File

@ -0,0 +1,22 @@
const { apiKeyTable } = require("../../db/dynamoClient")
const env = require("../../environment")
const { getSelfHostInfo } = require("../../selfhost")
/**
* This file purely exists so that we can centralise all logic pertaining to API keys, as their usage differs
* in our Cloud environment versus self hosted.
*/
exports.getAPIKey = async apiKeyId => {
if (env.CLOUD && !env.SELF_HOSTED) {
return apiKeyTable.get({
primary: apiKeyId,
})
}
if (env.SELF_HOSTED) {
const selfHostInfo = await getSelfHostInfo()
// if the api key supplied is correct then return structure similar
return apiKeyId === selfHostInfo.apiKeyId ? { pk: apiKeyId } : null
}
return null
}