Moving APIs around after some discussion, creating a self API to make it obvious.

This commit is contained in:
mike12345567 2022-02-10 18:34:55 +00:00
parent ac49ce6612
commit 788cb19fa8
13 changed files with 88 additions and 67 deletions

1
.gitignore vendored
View File

@ -95,3 +95,4 @@ hosting/.generated-nginx.dev.conf
*.sublime-workspace *.sublime-workspace
bin/ bin/
hosting/.generated*

View File

@ -3,3 +3,4 @@ docker-compose.yaml
nginx.conf nginx.conf
build/ build/
docker-error.log docker-error.log
envoy.yaml

View File

@ -20,6 +20,7 @@ import { buildScreenEndpoints } from "./screens"
import { buildTableEndpoints } from "./tables" import { buildTableEndpoints } from "./tables"
import { buildTemplateEndpoints } from "./templates" import { buildTemplateEndpoints } from "./templates"
import { buildUserEndpoints } from "./user" import { buildUserEndpoints } from "./user"
import { buildSelfEndpoints } from "./self"
import { buildViewEndpoints } from "./views" import { buildViewEndpoints } from "./views"
const defaultAPIClientConfig = { const defaultAPIClientConfig = {
@ -231,5 +232,6 @@ export const createAPIClient = config => {
...buildTemplateEndpoints(API), ...buildTemplateEndpoints(API),
...buildUserEndpoints(API), ...buildUserEndpoints(API),
...buildViewEndpoints(API), ...buildViewEndpoints(API),
...buildSelfEndpoints(API),
} }
} }

View File

@ -0,0 +1,22 @@
export const buildSelfEndpoints = API => ({
/**
* Using the logged in user, this will generate a new API key,
* assuming the user is a builder.
* @return {Promise<object>} returns the API response, including an API key.
*/
generateAPIKey: async () => {
return await API.post({
url: "/api/global/self/api_key",
})
},
/**
* retrieves the API key for the logged in user.
* @return {Promise<object>} An object containing the user developer information.
*/
fetchDeveloperInfo: async () => {
return await API.get({
url: "/api/global/self/api_key",
})
},
})

View File

@ -126,25 +126,4 @@ export const buildUserEndpoints = API => ({
}, },
}) })
}, },
/**
* Using the logged in user, this will generate a new API key,
* assuming the user is a builder.
* @return {Promise<object>} returns the API response, including an API key.
*/
generateAPIKey: async () => {
return await API.post({
url: "/api/global/users/api/key",
})
},
/**
* retrieves the API key for the logged in user.
* @return {Promise<object>} An object containing the user developer information.
*/
fetchDeveloperInfo: async () => {
return await API.get({
url: "/api/global/users/api/key",
})
},
}) })

View File

@ -5,6 +5,9 @@ const {
DocumentTypes, DocumentTypes,
} = require("@budibase/backend-core/db") } = require("@budibase/backend-core/db")
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context") const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
const { user: userCache } = require("@budibase/backend-core/cache")
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
const { allUsers } = require("../../utilities")
exports.fetch = async ctx => { exports.fetch = async ctx => {
const tenantId = ctx.user.tenantId const tenantId = ctx.user.tenantId
@ -42,3 +45,23 @@ exports.find = async ctx => {
} }
}) })
} }
exports.removeAppRole = async ctx => {
const { appId } = ctx.params
const db = getGlobalDB()
const users = await allUsers(ctx)
const bulk = []
const cacheInvalidations = []
for (let user of users) {
if (user.roles[appId]) {
cacheInvalidations.push(userCache.invalidateUser(user._id))
delete user.roles[appId]
bulk.push(user)
}
}
await db.bulkDocs(bulk)
await Promise.all(cacheInvalidations)
ctx.body = {
message: "App role removed from all users",
}
}

View File

@ -0,0 +1,11 @@
exports.generateAPIKey = async ctx => {
ctx.body = {
apiKey: "a175402a-89fc-11ec-a8a3-0242ac120002",
}
}
exports.fetchAPIKey = async ctx => {
ctx.body = {
apiKey: "a175402a-89fc-11ec-a8a3-0242ac120002",
}
}

View File

@ -24,16 +24,7 @@ const {
const { removeUserFromInfoDB } = require("@budibase/backend-core/deprovision") const { removeUserFromInfoDB } = require("@budibase/backend-core/deprovision")
const env = require("../../../environment") const env = require("../../../environment")
const { syncUserInApps } = require("../../../utilities/appService") const { syncUserInApps } = require("../../../utilities/appService")
const { allUsers } = require("../../utilities")
async function allUsers() {
const db = getGlobalDB()
const response = await db.allDocs(
getGlobalUserParams(null, {
include_docs: true,
})
)
return response.rows.map(row => row.doc)
}
exports.save = async ctx => { exports.save = async ctx => {
try { try {
@ -138,26 +129,6 @@ exports.destroy = async ctx => {
} }
} }
exports.removeAppRole = async ctx => {
const { appId } = ctx.params
const db = getGlobalDB()
const users = await allUsers(ctx)
const bulk = []
const cacheInvalidations = []
for (let user of users) {
if (user.roles[appId]) {
cacheInvalidations.push(userCache.invalidateUser(user._id))
delete user.roles[appId]
bulk.push(user)
}
}
await db.bulkDocs(bulk)
await Promise.all(cacheInvalidations)
ctx.body = {
message: "App role removed from all users",
}
}
exports.getSelf = async ctx => { exports.getSelf = async ctx => {
if (!ctx.user) { if (!ctx.user) {
ctx.throw(403, "User not logged in") ctx.throw(403, "User not logged in")
@ -280,15 +251,3 @@ exports.inviteAccept = async ctx => {
ctx.throw(400, "Unable to create new user, invitation invalid.") ctx.throw(400, "Unable to create new user, invitation invalid.")
} }
} }
exports.generateAPIKey = async ctx => {
ctx.body = {
apiKey: "a175402a-89fc-11ec-a8a3-0242ac120002",
}
}
exports.fetchAPIKey = async ctx => {
ctx.body = {
apiKey: "a175402a-89fc-11ec-a8a3-0242ac120002",
}
}

View File

@ -7,5 +7,6 @@ const router = Router()
router router
.get("/api/global/roles", adminOnly, controller.fetch) .get("/api/global/roles", adminOnly, controller.fetch)
.get("/api/global/roles/:appId", adminOnly, controller.find) .get("/api/global/roles/:appId", adminOnly, controller.find)
.delete("/api/global/roles/:appId", adminOnly, controller.removeAppRole)
module.exports = router module.exports = router

View File

@ -0,0 +1,11 @@
const Router = require("@koa/router")
const controller = require("../../controllers/global/self")
const builderOnly = require("../../../middleware/builderOnly")
const router = Router()
router
.post("/api/global/self/api_key", builderOnly, controller.generateAPIKey)
.get("/api/global/self/api_key", builderOnly, controller.fetchAPIKey)
module.exports = router

View File

@ -4,7 +4,6 @@ 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 cloudRestricted = require("../../../middleware/cloudRestricted")
const builderOnly = require("../../../middleware/builderOnly")
const router = Router() const router = Router()
@ -70,7 +69,6 @@ router
controller.save controller.save
) )
.get("/api/global/users", adminOnly, controller.fetch) .get("/api/global/users", adminOnly, controller.fetch)
.delete("/api/global/roles/:appId", adminOnly, controller.removeAppRole)
.delete("/api/global/users/:id", adminOnly, controller.destroy) .delete("/api/global/users/:id", adminOnly, controller.destroy)
.get("/api/global/roles/:appId") .get("/api/global/roles/:appId")
.post( .post(
@ -96,8 +94,7 @@ router
buildAdminInitValidation(), buildAdminInitValidation(),
controller.adminUser controller.adminUser
) )
.post("/api/global/users/api/key", builderOnly, controller.generateAPIKey)
.get("/api/global/users/api/key", builderOnly, controller.fetchAPIKey)
.get("/api/global/users/self", controller.getSelf) .get("/api/global/users/self", controller.getSelf)
.get("/api/global/users/tenant/:id", controller.tenantUserLookup) .get("/api/global/users/tenant/:id", controller.tenantUserLookup)
// global endpoint but needs to come at end (blocks other endpoints otherwise) // global endpoint but needs to come at end (blocks other endpoints otherwise)

View File

@ -8,6 +8,7 @@ const roleRoutes = require("./global/roles")
const sessionRoutes = require("./global/sessions") const sessionRoutes = require("./global/sessions")
const environmentRoutes = require("./system/environment") const environmentRoutes = require("./system/environment")
const tenantsRoutes = require("./system/tenants") const tenantsRoutes = require("./system/tenants")
const selfRoutes = require("./global/self")
exports.routes = [ exports.routes = [
configRoutes, configRoutes,
@ -20,4 +21,5 @@ exports.routes = [
sessionRoutes, sessionRoutes,
roleRoutes, roleRoutes,
environmentRoutes, environmentRoutes,
selfRoutes,
] ]

View File

@ -0,0 +1,12 @@
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
const { getGlobalUserParams } = require("@budibase/backend-core/db")
exports.allUsers = async () => {
const db = getGlobalDB()
const response = await db.allDocs(
getGlobalUserParams(null, {
include_docs: true,
})
)
return response.rows.map(row => row.doc)
}