Refactor privilege management to support hierarchical privilege keys
- Updated privilege key structure to use a 3- or 4-part dotted hierarchy (e.g., `GROUP.PARENT.MODULE`). - Modified the `RequirePrivilege` decorator to accept multiple keys, allowing for OR logic in privilege checks. - Enhanced `PrivilegesGuard` to validate against multiple privilege keys, improving access control logic. - Created migration scripts to update existing privilege keys in the database to the new format. - Updated related services, controllers, and tests to accommodate the new privilege key structure and validation logic.
This commit is contained in:
@@ -18,7 +18,10 @@ import { BEARER_AUTH_NAME } from '../../../common/swagger/setup-swagger';
|
||||
import { CustomerDto, ListCustomersQueryDto } from './dto/customer.dto';
|
||||
import { CustomersService } from './customers.service';
|
||||
|
||||
export const CUSTOMER_PRIVILEGE_KEY = 'CONFIGURATION.CUSTOMER';
|
||||
export const CUSTOMER_PRIVILEGE_KEYS = [
|
||||
'ADMIN.SETTINGS.DATA.CUSTOMER',
|
||||
'MOBILE.SALES.CUSTOMER',
|
||||
] as const;
|
||||
|
||||
@ApiTags('customers')
|
||||
@ApiBearerAuth(BEARER_AUTH_NAME)
|
||||
@@ -28,7 +31,7 @@ export class CustomersReadController {
|
||||
|
||||
@Get()
|
||||
@Pagination()
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'view')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'view')
|
||||
@ApiOperation({ summary: 'List customers' })
|
||||
@ApiOkResponse({
|
||||
schema: {
|
||||
@@ -50,7 +53,7 @@ export class CustomersReadController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'view')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'view')
|
||||
@ApiOperation({ summary: 'Get customer detail' })
|
||||
@ApiOkResponse({ type: CustomerDto })
|
||||
@ApiNotFoundResponse()
|
||||
|
||||
@@ -29,7 +29,7 @@ import { CurrentUser } from '../../../common/decorators/current-user.decorator';
|
||||
import { RequirePrivilege } from '../../../common/decorators/require-privilege.decorator';
|
||||
import { BEARER_AUTH_NAME } from '../../../common/swagger/setup-swagger';
|
||||
import { isAllowedCsvUpload } from './customer-fields';
|
||||
import { CUSTOMER_PRIVILEGE_KEY } from './customers-read.controller';
|
||||
import { CUSTOMER_PRIVILEGE_KEYS } from './customers-read.controller';
|
||||
import { CustomersService } from './customers.service';
|
||||
import {
|
||||
BulkIdsDto,
|
||||
@@ -49,7 +49,7 @@ export class CustomersWriteController {
|
||||
constructor(private readonly customersService: CustomersService) {}
|
||||
|
||||
@Post('import')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'import')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'import')
|
||||
@UseInterceptors(
|
||||
FileInterceptor('file', {
|
||||
limits: { fileSize: 1_048_576 },
|
||||
@@ -88,7 +88,7 @@ export class CustomersWriteController {
|
||||
|
||||
@Post('bulk-delete')
|
||||
@HttpCode(200)
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'delete')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'delete')
|
||||
@ApiOperation({ summary: 'Bulk delete customers' })
|
||||
@ApiOkResponse({
|
||||
schema: { properties: { deleted: { type: 'number' } } },
|
||||
@@ -101,7 +101,7 @@ export class CustomersWriteController {
|
||||
|
||||
@Post('bulk-status')
|
||||
@HttpCode(200)
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'update')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'update')
|
||||
@ApiOperation({ summary: 'Bulk update customer status' })
|
||||
@ApiOkResponse({
|
||||
schema: { properties: { updated: { type: 'number' } } },
|
||||
@@ -116,7 +116,7 @@ export class CustomersWriteController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'create')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'create')
|
||||
@ApiOperation({ summary: 'Create customer' })
|
||||
@ApiCreatedResponse({ type: CustomerDto })
|
||||
@ApiUnauthorizedResponse()
|
||||
@@ -132,7 +132,7 @@ export class CustomersWriteController {
|
||||
}
|
||||
|
||||
@Post(':id/contacts')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'update')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'update')
|
||||
@ApiOperation({ summary: 'Add a customer contact' })
|
||||
@ApiOkResponse({ type: CustomerDto })
|
||||
@ApiNotFoundResponse()
|
||||
@@ -147,7 +147,7 @@ export class CustomersWriteController {
|
||||
}
|
||||
|
||||
@Patch(':id/contacts/:contactId')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'update')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'update')
|
||||
@ApiOperation({ summary: 'Update a customer contact' })
|
||||
@ApiOkResponse({ type: CustomerDto })
|
||||
@ApiNotFoundResponse()
|
||||
@@ -167,7 +167,7 @@ export class CustomersWriteController {
|
||||
|
||||
@Delete(':id/contacts/:contactId')
|
||||
@HttpCode(204)
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'update')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'update')
|
||||
@ApiOperation({ summary: 'Delete a customer contact' })
|
||||
@ApiNoContentResponse()
|
||||
@ApiNotFoundResponse()
|
||||
@@ -181,7 +181,7 @@ export class CustomersWriteController {
|
||||
}
|
||||
|
||||
@Patch(':id/status')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'update')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'update')
|
||||
@ApiOperation({ summary: 'Update customer status' })
|
||||
@ApiOkResponse({ type: CustomerDto })
|
||||
@ApiNotFoundResponse()
|
||||
@@ -196,7 +196,7 @@ export class CustomersWriteController {
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'update')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'update')
|
||||
@ApiOperation({ summary: 'Update customer (not status)' })
|
||||
@ApiOkResponse({ type: CustomerDto })
|
||||
@ApiNotFoundResponse()
|
||||
@@ -215,7 +215,7 @@ export class CustomersWriteController {
|
||||
|
||||
@Delete(':id')
|
||||
@HttpCode(204)
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEY, 'delete')
|
||||
@RequirePrivilege(CUSTOMER_PRIVILEGE_KEYS, 'delete')
|
||||
@ApiOperation({ summary: 'Delete customer' })
|
||||
@ApiNoContentResponse()
|
||||
@ApiNotFoundResponse()
|
||||
|
||||
Reference in New Issue
Block a user