Skip to content

Commit de0d2e4

Browse files
committed
feat: expand access control for keyrings resource
- Added comprehensive access grants for the `keyrings` resource, including permissions for read, create, update, and delete actions for the `AC_INTERNAL_ROLE_GESTION`. - Updated the `KeyringsController` to utilize the new `@UseRoles` decorator for enforcing access control on keyrings operations. - Enhanced the `useAccessControl` composable to improve type safety and normalize action patterns for better access management.
1 parent f274364 commit de0d2e4

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

apps/api/src/_common/types/ac-types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ export const AC_INTERNAL_DEFAULT_ROLES_GRANTS: IAccessInfo[] = [
6969
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.UPDATE, resource: '/core/cron' },
7070
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.DELETE, resource: '/core/cron' },
7171

72+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.READ, resource: '/core/roles' },
73+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.CREATE, resource: '/core/roles' },
74+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.UPDATE, resource: '/core/roles' },
75+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.DELETE, resource: '/core/roles' },
76+
77+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.READ, resource: '/core/keyrings' },
78+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.CREATE, resource: '/core/keyrings' },
79+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.UPDATE, resource: '/core/keyrings' },
80+
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.DELETE, resource: '/core/keyrings' },
81+
7282
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.READ, resource: '/core/jobs' },
7383
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.CREATE, resource: '/core/jobs' },
7484
{ role: AC_INTERNAL_ROLE_GESTION, action: AC_ACTIONS.UPDATE, resource: '/core/jobs' },

apps/api/src/core/keyrings/keyrings.controller.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { ApiParam, ApiTags } from '@nestjs/swagger';
55
import { ApiDeletedResponseDecorator } from '~/_common/decorators/api-deleted-response.decorator';
66
import { ObjectIdValidationPipe } from '~/_common/pipes/object-id-validation.pipe';
77
import { Response } from 'express';
8-
import { ApiReadResponseDecorator } from '~/_common/decorators/api-read-response.decorator';
98
import { PickProjectionHelper } from '~/_common/helpers/pick-projection.helper';
109
import {
1110
FilterOptions,
@@ -18,6 +17,8 @@ import { ApiPaginatedDecorator } from '~/_common/decorators/api-paginated.decora
1817
import { PartialProjectionType } from '~/_common/types/partial-projection.type';
1918
import { KeyringsService } from '~/core/keyrings/keyrings.service';
2019
import { KeyringsCreateDto, KeyringsDto } from '~/core/keyrings/_dto/keyrings.dto';
20+
import { UseRoles } from '~/_common/decorators/use-roles.decorator';
21+
import { AC_ACTIONS, AC_DEFAULT_POSSESSION } from '~/_common/types/ac-types';
2122

2223
@ApiTags('core/keyrings')
2324
@Controller('keyrings')
@@ -38,6 +39,11 @@ export class KeyringsController extends AbstractController {
3839
}
3940

4041
@Post()
42+
@UseRoles({
43+
resource: '/core/keyrings',
44+
action: AC_ACTIONS.CREATE,
45+
possession: AC_DEFAULT_POSSESSION,
46+
})
4147
@ApiCreateDecorator(KeyringsCreateDto, KeyringsDto)
4248
public async create(@Res() res: Response, @Body() body: KeyringsCreateDto): Promise<Response> {
4349
const data = await this._service.create(body);
@@ -48,6 +54,11 @@ export class KeyringsController extends AbstractController {
4854
}
4955

5056
@Get()
57+
@UseRoles({
58+
resource: '/core/keyrings',
59+
action: AC_ACTIONS.READ,
60+
possession: AC_DEFAULT_POSSESSION,
61+
})
5162
@ApiPaginatedDecorator(PickProjectionHelper(KeyringsDto, KeyringsController.projection))
5263
public async search(
5364
@Res() res: Response,
@@ -76,6 +87,11 @@ export class KeyringsController extends AbstractController {
7687
}
7788

7889
@Delete(':_id([0-9a-fA-F]{24})')
90+
@UseRoles({
91+
resource: '/core/keyrings',
92+
action: AC_ACTIONS.DELETE,
93+
possession: AC_DEFAULT_POSSESSION,
94+
})
7995
@ApiParam({ name: '_id', type: String })
8096
@ApiDeletedResponseDecorator(KeyringsDto)
8197
public async remove(

apps/web/src/composables/useAccessControl.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const useAccessControl = () => {
6868
visiting.add(role)
6969
result.add(role)
7070

71-
const grants = access?.[role] as any
71+
const grants = access?.[role] as (AccessObjectAction & { $extend?: string[] }) | undefined
7272
const extend = grants?.$extend
7373
if (Array.isArray(extend)) {
7474
for (const parent of extend) {
@@ -159,6 +159,7 @@ export const useAccessControl = () => {
159159
}
160160

161161
const effectiveRoles = resolveEffectiveRoles(roles)
162+
const normalizedPatterns = (Array.isArray(patterns) ? patterns : [patterns]).map((pattern) => pattern.replace(/^\//, ''))
162163

163164
// Cas "menu public" : si aucun rôle et aucune ACL chargée, on laisse afficher les tuiles non restreintes.
164165
if (!effectiveRoles.length && (!access || Object.keys(access).length === 0)) {
@@ -168,8 +169,11 @@ export const useAccessControl = () => {
168169
for (const role of effectiveRoles) {
169170
const actions = access[role] as AccessObjectAction || {}
170171
for (const action of Object.keys(actions)) {
172+
if (action.startsWith('$')) {
173+
continue
174+
}
171175
const normalizedKey = action.replace(/^\//, '')
172-
if (Array.isArray(patterns) ? patterns.some((pattern) => normalizedKey.startsWith(pattern)) : normalizedKey.startsWith(patterns)) {
176+
if (normalizedPatterns.some((pattern) => normalizedKey.startsWith(pattern))) {
173177
return true
174178
}
175179
}

0 commit comments

Comments
 (0)