diff --git a/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte b/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte index d8f094b3cb..9b82c2047e 100644 --- a/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte @@ -6,7 +6,7 @@ import ErrorsBox from "components/common/ErrorsBox.svelte" import { backendUiStore } from "builderStore" - let permissions = [] + let basePermissions = [] let selectedRole = {} let errors = [] let builtInRoles = ["Admin", "Power", "Basic", "Public"] @@ -16,9 +16,9 @@ ) $: isCreating = selectedRoleId == null || selectedRoleId === "" - const fetchPermissions = async () => { - const permissionsResponse = await api.get("/api/permissions") - permissions = await permissionsResponse.json() + const fetchBasePermissions = async () => { + const permissionsResponse = await api.get("/api/permission/builtin") + basePermissions = await permissionsResponse.json() } // Changes the selected role @@ -81,7 +81,7 @@ } } - onMount(fetchPermissions) + onMount(fetchBasePermissions) - {#each permissions as permission} - + {#each basePermissions as basePerm} + {/each} {/if} diff --git a/packages/server/src/api/controllers/hosting.js b/packages/server/src/api/controllers/hosting.js index 1d1884eb52..280d24d378 100644 --- a/packages/server/src/api/controllers/hosting.js +++ b/packages/server/src/api/controllers/hosting.js @@ -14,6 +14,7 @@ exports.fetchInfo = async ctx => { } exports.save = async ctx => { + console.trace("DID A SAVE!") const db = new CouchDB(BUILDER_CONFIG_DB) const { type } = ctx.request.body if (type === HostingTypes.CLOUD && ctx.request.body._rev) { diff --git a/packages/server/src/api/controllers/permission.js b/packages/server/src/api/controllers/permission.js index a2715a5363..9ff788b5cc 100644 --- a/packages/server/src/api/controllers/permission.js +++ b/packages/server/src/api/controllers/permission.js @@ -1,6 +1,25 @@ -const { BUILTIN_PERMISSIONS } = require("../../utilities/security/permissions") +const { + BUILTIN_PERMISSIONS, + PermissionLevels, +} = require("../../utilities/security/permissions") -exports.fetch = async function(ctx) { - // TODO: need to build out custom permissions +function updatePermissionOnRole(roleId, permissions, remove = false) { + +} + +exports.fetchBuiltin = function(ctx) { ctx.body = Object.values(BUILTIN_PERMISSIONS) } + +exports.fetchLevels = function(ctx) { + ctx.body = Object.values(PermissionLevels) +} + +exports.addPermission = async function(ctx) { + const permissions = ctx.body.permissions, appId = ctx.appId + updatePermissionOnRole +} + +exports.removePermission = async function(ctx) { + const permissions = ctx.body.permissions, appId = ctx.appId +} diff --git a/packages/server/src/api/routes/permission.js b/packages/server/src/api/routes/permission.js index 9dcec253b3..3dbce73599 100644 --- a/packages/server/src/api/routes/permission.js +++ b/packages/server/src/api/routes/permission.js @@ -1,10 +1,46 @@ const Router = require("@koa/router") const controller = require("../controllers/permission") const authorized = require("../../middleware/authorized") -const { BUILDER } = require("../../utilities/security/permissions") +const { + BUILDER, + PermissionLevels, +} = require("../../utilities/security/permissions") +const Joi = require("joi") +const joiValidator = require("../../middleware/joi-validator") const router = Router() -router.get("/api/permissions", authorized(BUILDER), controller.fetch) +function generateAddValidator() { + const permLevelArray = Object.values(PermissionLevels) + // prettier-ignore + return joiValidator.body(Joi.object({ + permissions: Joi.object() + .pattern(/.*/, [Joi.string().valid(...permLevelArray)]) + .required() + }).unknown(true)) +} + +function generateRemoveValidator() { + // prettier-ignore + return joiValidator.body(Joi.object({ + permissions: Joi.array().items(Joi.string()) + }).unknown(true)) +} + +router + .get("/api/permission/builtin", authorized(BUILDER), controller.fetchBuiltin) + .get("/api/permission/levels", authorized(BUILDER), controller.fetchLevels) + .patch( + "/api/permission/:roleId/add", + authorized(BUILDER), + generateAddValidator(), + controller.addPermission + ) + .patch( + "/api/permission/:roleId/remove", + authorized(BUILDER), + generateRemoveValidator(), + controller.removePermission + ) module.exports = router diff --git a/packages/server/src/utilities/builder/hosting.js b/packages/server/src/utilities/builder/hosting.js index 3c02410afd..24ca76dc3e 100644 --- a/packages/server/src/utilities/builder/hosting.js +++ b/packages/server/src/utilities/builder/hosting.js @@ -23,6 +23,7 @@ exports.HostingTypes = { } exports.getHostingInfo = async () => { + console.trace("DID A GET!") const db = new CouchDB(BUILDER_CONFIG_DB) let doc try { diff --git a/packages/server/src/utilities/security/permissions.js b/packages/server/src/utilities/security/permissions.js index c00f3ce6c7..12010dcc40 100644 --- a/packages/server/src/utilities/security/permissions.js +++ b/packages/server/src/utilities/security/permissions.js @@ -7,6 +7,7 @@ const PermissionLevels = { ADMIN: "admin", } +// these are the global types, that govern the underlying default behaviour const PermissionTypes = { TABLE: "table", USER: "user", diff --git a/packages/server/src/utilities/security/roles.js b/packages/server/src/utilities/security/roles.js index 6b6ec39b24..2379e090fd 100644 --- a/packages/server/src/utilities/security/roles.js +++ b/packages/server/src/utilities/security/roles.js @@ -66,14 +66,23 @@ exports.getRole = async (appId, roleId) => { if (!roleId) { return null } - let role + let role = {} + // built in roles mostly come from the in-code implementation, + // but can be extended by a doc stored about them (e.g. permissions) if (isBuiltin(roleId)) { role = cloneDeep( Object.values(exports.BUILTIN_ROLES).find(role => role._id === roleId) ) - } else { + } + try { const db = new CouchDB(appId) - role = await db.get(roleId) + const dbRole = await db.get(roleId) + role = Object.assign(role, dbRole) + } catch (err) { + // only throw an error if there is no role at all + if (Object.keys(role).length === 0) { + throw err + } } return role }