From 73818ae0861450ace4895b776dd7d871b7904ec2 Mon Sep 17 00:00:00 2001 From: Rudhra Deep Biswas <98055396+rudeUltra@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:18:29 +0530 Subject: [PATCH] init (#10784) --- .../index.jsx | 20 +++++--- server/src/entities/folder.entity.ts | 2 +- server/src/helpers/queries.ts | 50 +++++++++++++------ .../granular-permissions.constant.ts | 10 ---- .../constants/group-permissions.constant.ts | 2 + .../utility/granular-permissios.utility.ts | 5 +- server/src/services/folders.service.ts | 23 ++++++--- .../services/granular_permissions.service.ts | 4 +- 8 files changed, 70 insertions(+), 46 deletions(-) diff --git a/frontend/src/ManageGroupPermissionResourcesV2/index.jsx b/frontend/src/ManageGroupPermissionResourcesV2/index.jsx index be47a24752..80e3ff4fec 100644 --- a/frontend/src/ManageGroupPermissionResourcesV2/index.jsx +++ b/frontend/src/ManageGroupPermissionResourcesV2/index.jsx @@ -150,7 +150,8 @@ class ManageGroupPermissionResourcesComponent extends React.Component { toast.success('Group permissions updated'); this.fetchGroupPermission(groupPermissionId); }) - .catch(({ error }) => { + .catch((e) => { + const error = e?.error; if (error?.type) { this.setState({ showAutoRoleChangeModal: true, @@ -160,13 +161,16 @@ class ManageGroupPermissionResourcesComponent extends React.Component { }); return; } - this.setState({ - errorMessage: error?.error, - showEditRoleErrorModal: true, - errorListItems: error?.data, - errorTitle: error?.title ? error?.title : 'Cannot add this permission to the group', - errorIconName: 'lock', - }); + // status code 451 - license error handled on separate modal + if (e?.statusCode !== 451) { + this.setState({ + errorMessage: error?.error, + showEditRoleErrorModal: true, + errorListItems: error?.data, + errorTitle: error?.title ? error?.title : 'Cannot add this permission to the group', + errorIconName: 'lock', + }); + } }); }; diff --git a/server/src/entities/folder.entity.ts b/server/src/entities/folder.entity.ts index 3104656a4f..13ab47c1b4 100644 --- a/server/src/entities/folder.entity.ts +++ b/server/src/entities/folder.entity.ts @@ -53,7 +53,7 @@ export class Folder { @AfterLoad() generateCount(): void { if (this.folderApps) { - this.count = this.folderApps.length; + this.count = this.folderApps?.length || 0; } } } diff --git a/server/src/helpers/queries.ts b/server/src/helpers/queries.ts index c46d76651c..2167821498 100644 --- a/server/src/helpers/queries.ts +++ b/server/src/helpers/queries.ts @@ -22,30 +22,33 @@ export function getFolderQuery( ]) ), ]; - const hiddenApps = userAppPermissions.hiddenAppsId.filter((id) => !userAppPermissions.editableAppsId.includes(id)); + const hiddenApps = [ + ...userAppPermissions.hiddenAppsId.filter((id) => !userAppPermissions.editableAppsId.includes(id)), + ]; const query = manager.createQueryBuilder(Folder, 'folders'); + query.leftJoinAndSelect('folders.folderApps', 'folder_apps'); + query.leftJoin('folder_apps.app', 'app'); if (!isAllEditable) { - if ((isAllViewable && hideAll) || (!isAllViewable && !hideAll) || (!isAllViewable && hideAll)) - query.leftJoinAndSelect('folders.folderApps', 'folder_apps', 'folder_apps.appId IN (:...viewableApps)', { + // Not all apps are editable - filter with view privilege + if (!isAllViewable) { + // Not all apps are viewable + query.andWhere('folder_apps.appId IN (:...viewableApps)', { viewableApps, }); - else if (!userAppPermissions.hideAll && isAllViewable) { - if (hiddenApps.length > 0) - query.leftJoinAndSelect('folders.folderApps', 'folder_apps', 'folder_apps.appId NOT IN (:...hiddenApps)', { - hiddenApps, - }); - else { - query.leftJoinAndSelect('folders.folderApps', 'folder_apps'); - } + } else if (!hideAll && hiddenApps?.length) { + // Not all apps are hidden + query.andWhere('folder_apps.appId NOT IN (:...hiddenApps)', { + hiddenApps, + }); + } else if (hideAll) { + // No need to return any + query.andWhere('1=0'); } - } else { - query.leftJoinAndSelect('folders.folderApps', 'folder_apps'); } - query.leftJoin('folder_apps.app', 'app'); if (searchKey) { - query.where('LOWER(app.name) like :searchKey', { + query.andWhere('LOWER(app.name) like :searchKey', { searchKey: `%${searchKey && searchKey.toLowerCase()}%`, }); } @@ -57,6 +60,23 @@ export function getFolderQuery( return query; } +export function getAllFoldersQuery( + organizationId: string, + manager: EntityManager, + type = 'front-end' +): SelectQueryBuilder { + const query = manager.createQueryBuilder(Folder, 'folders'); + query + .andWhere('folders.organization_id = :organizationId', { + organizationId, + }) + .andWhere('folders.type = :type', { + type, + }) + .orderBy('folders.name', 'ASC'); + + return query; +} export function viewableAppsQueryUsingPermissions( user: User, diff --git a/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts b/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts index b018090ed1..764eedec20 100644 --- a/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts +++ b/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts @@ -34,13 +34,3 @@ export const DEFAULT_RESOURCE_PERMISSIONS = { }, }, } as Record>; - -export const ERROR_HANDLER = { - GROUP_DOES_NOT_EXIST: 'Group does not exist', - ADMIN_DEFAULT_GROUP_GRANULAR_PERMISSIONS: 'Cannot create granular permissions of admin group', - EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED: - 'End-users can only be granted permission to view apps. If you wish to add this permission, kindly change the following users role from end-user to builder', - EDITOR_LEVEL_PERMISSION_NOT_ALLOWED_END_USER: 'Cannot assign builder level permission to end users', - UPDATE_EDITABLE_PERMISSION_END_USER_GROUP: - 'End-users can only be granted permission to view apps. If you wish to add this permission, kindly change the following users role from end-user to builder- ', -}; diff --git a/server/src/modules/user_resource_permissions/constants/group-permissions.constant.ts b/server/src/modules/user_resource_permissions/constants/group-permissions.constant.ts index 8be0d5eb4b..f1ef042616 100644 --- a/server/src/modules/user_resource_permissions/constants/group-permissions.constant.ts +++ b/server/src/modules/user_resource_permissions/constants/group-permissions.constant.ts @@ -125,4 +125,6 @@ export const ERROR_HANDLER = { DELETING_DEFAULT_GROUP_USER: 'Deleting default user from default group is not allowed', EDITING_LAST_ADMIN_ROLE_NOT_ALLOWED: 'Cannot change role of last present admin, please add another admin and change the role', + ADMIN_DEFAULT_GROUP_GRANULAR_PERMISSIONS: 'Cannot create granular permissions of admin group', + EDITOR_LEVEL_PERMISSION_NOT_ALLOWED_END_USER: 'Cannot assign builder level permission to end users', }; diff --git a/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts b/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts index c7eb0b0a37..afb6684c9e 100644 --- a/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts +++ b/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts @@ -1,7 +1,6 @@ import { GroupPermissions } from 'src/entities/group_permissions.entity'; -import { USER_ROLE } from '../constants/group-permissions.constant'; +import { USER_ROLE, ERROR_HANDLER } from '../constants/group-permissions.constant'; import { BadRequestException } from '@nestjs/common'; -import { ERROR_HANDLER } from '../constants/granular-permissions.constant'; import { EntityManager, SelectQueryBuilder } from 'typeorm'; import { GranularPermissionQuerySearchParam, ResourceGroupActions } from '../interface/granular-permissions.interface'; import { GranularPermissions } from 'src/entities/granular_permissions.entity'; @@ -12,7 +11,7 @@ export function validateGranularPermissionCreateOperation(group: GroupPermission } export function validateGranularPermissionUpdateOperation(group: GroupPermissions, organizationId: string) { - if (group.organizationId !== organizationId) throw new BadRequestException(ERROR_HANDLER.GROUP_DOES_NOT_EXIST); + if (group.organizationId !== organizationId) throw new BadRequestException(ERROR_HANDLER.GROUP_NOT_EXIST); if (group.name === USER_ROLE.ADMIN) throw new BadRequestException(ERROR_HANDLER.ADMIN_DEFAULT_GROUP_GRANULAR_PERMISSIONS); } diff --git a/server/src/services/folders.service.ts b/server/src/services/folders.service.ts index fd14f484ac..3c66a14425 100644 --- a/server/src/services/folders.service.ts +++ b/server/src/services/folders.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { FolderApp } from 'src/entities/folder_app.entity'; -import { getFolderQuery } from 'src/helpers/queries'; +import { getFolderQuery, getAllFoldersQuery } from 'src/helpers/queries'; import { User } from '../../src/entities/user.entity'; import { Folder } from '../entities/folder.entity'; @@ -42,12 +42,22 @@ export class FoldersService { }, [{ dbConstraint: DataBaseConstraints.FOLDER_NAME_UNIQUE, message: 'This folder name is already taken.' }]); } - async allFolders(user: User, userAppPermissions: UserAppsPermissions, searchKey?: string): Promise { + async allFoldersWithAppCount( + user: User, + userAppPermissions: UserAppsPermissions, + searchKey?: string + ): Promise { return await dbTransactionWrap(async (manager: EntityManager) => { return await getFolderQuery(user.organizationId, manager, userAppPermissions, searchKey).distinct().getMany(); }); } + async allFolders(user: User, type = 'front-end'): Promise { + return await dbTransactionWrap(async (manager: EntityManager) => { + return await getAllFoldersQuery(user.organizationId, manager, type).getMany(); + }); + } + async all(user: User, searchKey: string): Promise { const userAppPermissions = ( await this.abilityService.resourceActionsPermission(user, { @@ -56,18 +66,17 @@ export class FoldersService { }) ).App; - const allFolderList = await this.allFolders(user, userAppPermissions); - if (!searchKey || allFolderList.length === 0) { + const allFolderList = await this.allFolders(user); + if (allFolderList.length === 0) { return allFolderList; } - const folders = await this.allFolders(user, userAppPermissions, searchKey); + const folders = await this.allFoldersWithAppCount(user, userAppPermissions, searchKey); allFolderList.forEach((folder, index) => { const currentFolder = folders.find((f) => f.id === folder.id); if (currentFolder) { - allFolderList[index] = currentFolder; - allFolderList[index].folderApps; + allFolderList[index].folderApps = [...(currentFolder?.folderApps || [])]; allFolderList[index].generateCount(); console.log('folder found'); } else { diff --git a/server/src/services/granular_permissions.service.ts b/server/src/services/granular_permissions.service.ts index f88a9aa5b0..73a454e470 100644 --- a/server/src/services/granular_permissions.service.ts +++ b/server/src/services/granular_permissions.service.ts @@ -21,7 +21,7 @@ import { DATA_BASE_CONSTRAINTS, USER_ROLE, } from '@modules/user_resource_permissions/constants/group-permissions.constant'; -import { ERROR_HANDLER } from '@modules/user_resource_permissions/constants/granular-permissions.constant'; +import { ERROR_HANDLER } from '@modules/user_resource_permissions/constants/group-permissions.constant'; import { getAllGranularPermissionQuery, getGranularPermissionQuery, @@ -144,7 +144,7 @@ export class GranularPermissionsService { if (groupEditors.length && canEdit) throw new BadRequestException({ message: { - error: ERROR_HANDLER.EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED, + error: ERROR_HANDLER.EDITOR_LEVEL_PERMISSION_NOT_ALLOWED_END_USER, data: groupEditors.map((user) => user.email), title: 'Cannot create permissions', },