From 0dc03abe5f585a7e2ae6db945b059ff123d431b3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 1 Sep 2023 17:03:33 +0200 Subject: [PATCH] Display dependant info --- .../DataTable/modals/ManageAccessModal.svelte | 23 ++++++++++++++ .../builder/src/stores/backend/permissions.js | 3 ++ packages/frontend-core/src/api/permissions.js | 10 +++++++ .../server/src/api/controllers/permission.ts | 10 +++++++ packages/server/src/api/routes/permission.ts | 5 ++++ .../server/src/sdk/app/permissions/index.ts | 30 ++++++++++++++++++- packages/types/src/api/web/app/permission.ts | 4 +++ 7 files changed, 84 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte b/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte index 9106542130..031af85e62 100644 --- a/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte @@ -9,6 +9,7 @@ ModalContent, Tags, Tag, + Icon, } from "@budibase/bbui" import { capitalise } from "helpers" import { get } from "svelte/store" @@ -63,6 +64,12 @@ ) $: requiresPlanToModify = permissions.requiresPlanToModify + + let dependantResources + async function loadDependantResources() { + dependantResources = await permissionsStore.getDependantsCount(resourceId) + } + loadDependantResources() @@ -93,6 +100,17 @@ /> {/each} + + {#if dependantResources} +
+ + + + {dependantResources} resource/s are inheriting this access. + + +
+ {/if}
diff --git a/packages/builder/src/stores/backend/permissions.js b/packages/builder/src/stores/backend/permissions.js index 52bd1e1303..ad0429671b 100644 --- a/packages/builder/src/stores/backend/permissions.js +++ b/packages/builder/src/stores/backend/permissions.js @@ -26,6 +26,9 @@ export function createPermissionStore() { forResourceDetailed: async resourceId => { return await API.getPermissionForResource(resourceId) }, + getDependantsCount: async resourceId => { + return (await API.getDependants(resourceId)).total + }, } } diff --git a/packages/frontend-core/src/api/permissions.js b/packages/frontend-core/src/api/permissions.js index 9ba0be23cd..0204f358e8 100644 --- a/packages/frontend-core/src/api/permissions.js +++ b/packages/frontend-core/src/api/permissions.js @@ -34,4 +34,14 @@ export const buildPermissionsEndpoints = API => ({ url: `/api/permission/${roleId}/${resourceId}/${level}`, }) }, + + /** + * Gets the resources that depend on this resource permissions + * @param resourceId the resource ID to check + */ + getDependants: async resourceId => { + return await API.get({ + url: `/api/permission/${resourceId}/dependants`, + }) + }, }) diff --git a/packages/server/src/api/controllers/permission.ts b/packages/server/src/api/controllers/permission.ts index f287d4577d..8d7db9e5e4 100644 --- a/packages/server/src/api/controllers/permission.ts +++ b/packages/server/src/api/controllers/permission.ts @@ -6,6 +6,7 @@ import { PermissionLevel, GetResourcePermsResponse, ResourcePermissionInfo, + GetDependantResourcesResponse, } from "@budibase/types" import { getRoleParams } from "../../db/utils" import { @@ -179,6 +180,15 @@ export async function getResourcePerms( } } +export async function getDependantResources( + ctx: UserCtx +) { + const resourceId = ctx.params.resourceId + ctx.body = { + total: await sdk.permissions.getDependantResources(resourceId), + } +} + export async function addPermission(ctx: UserCtx) { ctx.body = await updatePermissionOnRole(ctx.params, PermissionUpdateType.ADD) } diff --git a/packages/server/src/api/routes/permission.ts b/packages/server/src/api/routes/permission.ts index 7f82d34052..119853e066 100644 --- a/packages/server/src/api/routes/permission.ts +++ b/packages/server/src/api/routes/permission.ts @@ -23,6 +23,11 @@ router authorized(permissions.BUILDER), controller.getResourcePerms ) + .get( + "/api/permission/:resourceId/dependants", + authorized(permissions.BUILDER), + controller.getDependantResources + ) // adding a specific role/level for the resource overrides the underlying access control .post( "/api/permission/:roleId/:resourceId/:level", diff --git a/packages/server/src/sdk/app/permissions/index.ts b/packages/server/src/sdk/app/permissions/index.ts index 446e2b15af..317e66a153 100644 --- a/packages/server/src/sdk/app/permissions/index.ts +++ b/packages/server/src/sdk/app/permissions/index.ts @@ -1,4 +1,4 @@ -import { context, env, roles } from "@budibase/backend-core" +import { context, db, env, roles } from "@budibase/backend-core" import { features } from "@budibase/pro" import { DocumentType, @@ -16,6 +16,8 @@ import { CURRENTLY_SUPPORTED_LEVELS, getBasePermissions, } from "../../../utilities/security" +import sdk from "../../../sdk" +import { isV2 } from "../views" type ResourceActionAllowedResult = | { allowed: true } @@ -134,3 +136,29 @@ export async function getResourcePerms( const result = Object.assign(basePermissions, permissions) return result } + +export async function getDependantResources(resourceId: string) { + if (db.isTableId(resourceId)) { + const dependants = new Set() + + const table = await sdk.tables.getTable(resourceId) + const views = Object.values(table.views || {}) + + for (const view of views) { + if (!isV2(view)) { + continue + } + + const permissions = await getResourcePerms(view.id) + for (const [level, roleInfo] of Object.entries(permissions)) { + if (roleInfo.type === PermissionSource.INHERITED) { + dependants.add(view.id) + } + } + } + + return dependants.size + } + + return 0 +} diff --git a/packages/types/src/api/web/app/permission.ts b/packages/types/src/api/web/app/permission.ts index 293ea62122..1623abd8ac 100644 --- a/packages/types/src/api/web/app/permission.ts +++ b/packages/types/src/api/web/app/permission.ts @@ -10,3 +10,7 @@ export interface GetResourcePermsResponse { permissions: Record requiresPlanToModify?: PlanType } + +export interface GetDependantResourcesResponse { + total: number +}