Re-writing APIs based on most recent discussion about RBAC and per app builders.
This commit is contained in:
parent
c375f860ba
commit
d9c8e26f65
|
@ -85,10 +85,3 @@ export interface AcceptUserInviteResponse {
|
||||||
export interface SyncUserRequest {
|
export interface SyncUserRequest {
|
||||||
previousUser?: User
|
previousUser?: User
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddAppBuilderRequest {
|
|
||||||
userId: string
|
|
||||||
appId: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RemoveAppBuilderRequest {}
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ export interface User extends Document {
|
||||||
roles: UserRoles
|
roles: UserRoles
|
||||||
builder?: {
|
builder?: {
|
||||||
global?: boolean
|
global?: boolean
|
||||||
|
appBuilder?: boolean
|
||||||
apps?: string[]
|
apps?: string[]
|
||||||
}
|
}
|
||||||
admin?: {
|
admin?: {
|
||||||
|
|
|
@ -8,8 +8,6 @@ import env from "../../../environment"
|
||||||
import {
|
import {
|
||||||
AcceptUserInviteRequest,
|
AcceptUserInviteRequest,
|
||||||
AcceptUserInviteResponse,
|
AcceptUserInviteResponse,
|
||||||
AddAppBuilderRequest,
|
|
||||||
RemoveAppBuilderRequest,
|
|
||||||
BulkUserRequest,
|
BulkUserRequest,
|
||||||
BulkUserResponse,
|
BulkUserResponse,
|
||||||
CloudAccount,
|
CloudAccount,
|
||||||
|
@ -32,6 +30,7 @@ import {
|
||||||
tenancy,
|
tenancy,
|
||||||
platform,
|
platform,
|
||||||
ErrorCode,
|
ErrorCode,
|
||||||
|
db as dbCore,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import { checkAnyUserExists } from "../../../utilities/users"
|
import { checkAnyUserExists } from "../../../utilities/users"
|
||||||
import { isEmailConfigured } from "../../../utilities/email"
|
import { isEmailConfigured } from "../../../utilities/email"
|
||||||
|
@ -434,8 +433,57 @@ export const inviteAccept = async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addAppBuilder = async (ctx: Ctx<AddAppBuilderRequest, void>) => {}
|
export const grantAppBuilder = async (ctx: Ctx) => {
|
||||||
|
const { userId } = ctx.params
|
||||||
|
const user = await userSdk.getUser(userId)
|
||||||
|
if (!user.builder) {
|
||||||
|
user.builder = {}
|
||||||
|
}
|
||||||
|
user.builder.appBuilder = true
|
||||||
|
await userSdk.save(user, { hashPassword: false })
|
||||||
|
ctx.body = { message: `User "${user.email}" granted app builder permissions` }
|
||||||
|
}
|
||||||
|
|
||||||
export const removeAppBuilder = async (
|
export const addAppBuilder = async (ctx: Ctx) => {
|
||||||
ctx: Ctx<RemoveAppBuilderRequest, void>
|
const { userId, appId } = ctx.params
|
||||||
) => {}
|
const user = await userSdk.getUser(userId)
|
||||||
|
if (!user.builder?.global || user.admin?.global) {
|
||||||
|
ctx.body = { message: "User already admin - no permissions updated." }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!user.builder?.appBuilder) {
|
||||||
|
ctx.throw(
|
||||||
|
400,
|
||||||
|
"Unable to update access, user must be granted app builder permissions."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const prodAppId = dbCore.getProdAppID(appId)
|
||||||
|
if (!user.builder.apps) {
|
||||||
|
user.builder.apps = []
|
||||||
|
}
|
||||||
|
user.builder.apps.push(prodAppId)
|
||||||
|
await userSdk.save(user, { hashPassword: false })
|
||||||
|
ctx.body = { message: `User "${user.email}" app builder access updated.` }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removeAppBuilder = async (ctx: Ctx) => {
|
||||||
|
const { userId, appId } = ctx.params
|
||||||
|
const user = await userSdk.getUser(userId)
|
||||||
|
if (!user.builder?.global || user.admin?.global) {
|
||||||
|
ctx.body = { message: "User already admin - no permissions removed." }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!user.builder?.appBuilder) {
|
||||||
|
ctx.throw(
|
||||||
|
400,
|
||||||
|
"Unable to update access, user must be granted app builder permissions."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const prodAppId = dbCore.getProdAppID(appId)
|
||||||
|
const indexOf = user.builder?.apps?.indexOf(prodAppId)
|
||||||
|
if (indexOf && indexOf !== -1) {
|
||||||
|
user.builder.apps = user.builder.apps!.splice(indexOf, 1)
|
||||||
|
}
|
||||||
|
await userSdk.save(user, { hashPassword: false })
|
||||||
|
ctx.body = { message: `User "${user.email}" app builder access removed.` }
|
||||||
|
}
|
||||||
|
|
|
@ -122,6 +122,15 @@ router
|
||||||
buildAdminInitValidation(),
|
buildAdminInitValidation(),
|
||||||
controller.adminUser
|
controller.adminUser
|
||||||
)
|
)
|
||||||
|
.post("/api/global/users/:userId/app/builder", controller.grantAppBuilder)
|
||||||
|
.patch(
|
||||||
|
"/api/global/users/:userId/app/:appId/builder",
|
||||||
|
controller.addAppBuilder
|
||||||
|
)
|
||||||
|
.delete(
|
||||||
|
"/api/global/users/:userId/app/:appId/builder",
|
||||||
|
controller.removeAppBuilder
|
||||||
|
)
|
||||||
.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)
|
||||||
.get("/api/global/users/:id", auth.builderOrAdmin, controller.find)
|
.get("/api/global/users/:id", auth.builderOrAdmin, controller.find)
|
||||||
|
@ -132,7 +141,5 @@ router
|
||||||
users.buildUserSaveValidation(),
|
users.buildUserSaveValidation(),
|
||||||
selfController.updateSelf
|
selfController.updateSelf
|
||||||
)
|
)
|
||||||
.post("/api/global/users/builder", controller.addAppBuilder)
|
|
||||||
.delete("/api/global/users/builder", controller.removeAppBuilder)
|
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
Loading…
Reference in New Issue