@@ -3,8 +3,22 @@ import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiTags } from '@nestjs
import { map } from 'rxjs' ;
import { CoreGrpcService } from '../core-grpc.service' ;
import { CurrentAdmin } from '../decorators/current-admin.decorator' ;
import { AssignUserRoleDto , CreateOAuthClientDto , CreateRoleDto , UpdateOAuthClientDto } from '../dto/rbac.dto' ;
import { AdminGuard , AdminRequestUser , assertAdminAnyPermission , assertAdminPermission , SuperAdminGuard } from '../guards/admin.guard' ;
import {
AssignUserPermissionDto ,
AssignUserRoleDto ,
CreateOAuthClientDto ,
CreateRoleDto ,
UpdateOAuthClientDto ,
UpdateRoleDto
} from '../dto/rbac.dto' ;
import {
AdminGuard ,
AdminRequestUser ,
assertAdminAnyPermission ,
assertAdminPermission ,
RbacManageGuard ,
SuperAdminGuard
} from '../guards/admin.guard' ;
@ApiTags ( 'RBAC и OAuth' )
@ApiBearerAuth ( )
@@ -30,7 +44,7 @@ export class RbacController {
}
@Get ( 'permissions' )
@UseGuards ( SuperAdmin Guard)
@UseGuards ( RbacManage Guard)
@ApiOperation ( { summary : 'Список прав' , description : 'Возвращает все доступные permissions.' } )
listPermissions() {
return this . core . rbac . ListPermissions ( { } ) ;
@@ -51,16 +65,33 @@ export class RbacController {
}
@Post ( 'roles' )
@UseGuards ( SuperAdmin Guard)
@ApiOperation ( { summary : 'Создать роль' , description : 'Создаёт новую роль с набором прав. Только супер-администратор. ' } )
@UseGuards ( RbacManage Guard)
@ApiOperation ( { summary : 'Создать роль' , description : 'Создаёт новую роль с набором прав.' } )
@ApiBody ( { type : CreateRoleDto } )
createRole ( @Body ( ) dto : CreateRoleDto , @CurrentAdmin ( ) admin : AdminRequestUser ) {
return this . core . rbac . CreateRole ( { actorUserId : admin.id , . . . dto } ) ;
}
@Patch ( 'roles/:roleSlug' )
@UseGuards ( RbacManageGuard )
@ApiOperation ( { summary : 'Обновить роль' , description : 'Изменяет название, описание и права роли.' } )
@ApiParam ( { name : 'roleSlug' , description : 'Slug роли' } )
@ApiBody ( { type : UpdateRoleDto } )
updateRole ( @Param ( 'roleSlug' ) roleSlug : string , @Body ( ) dto : UpdateRoleDto , @CurrentAdmin ( ) admin : AdminRequestUser ) {
return this . core . rbac . UpdateRole ( { actorUserId : admin.id , roleSlug , . . . dto } ) ;
}
@Delete ( 'roles/:roleSlug' )
@UseGuards ( RbacManageGuard )
@ApiOperation ( { summary : 'Удалить роль' , description : 'Удаляет пользовательскую роль. Системные роли удалить нельзя.' } )
@ApiParam ( { name : 'roleSlug' , description : 'Slug роли' } )
deleteRole ( @Param ( 'roleSlug' ) roleSlug : string , @CurrentAdmin ( ) admin : AdminRequestUser ) {
return this . core . rbac . DeleteRole ( { actorUserId : admin.id , roleSlug } ) ;
}
@Post ( 'users/:userId/roles' )
@UseGuards ( SuperAdmin Guard)
@ApiOperation ( { summary : 'Назначить роль пользователю' , description : 'Только супер-администратор может назначать роли.' } )
@UseGuards ( RbacManage Guard)
@ApiOperation ( { summary : 'Назначить роль пользователю' } )
@ApiParam ( { name : 'userId' , description : 'ID пользователя' } )
@ApiBody ( { type : AssignUserRoleDto } )
assignRole ( @Param ( 'userId' ) userId : string , @Body ( ) dto : AssignUserRoleDto , @CurrentAdmin ( ) admin : AdminRequestUser ) {
@@ -68,14 +99,36 @@ export class RbacController {
}
@Delete ( 'users/:userId/roles/:roleSlug' )
@UseGuards ( SuperAdmin Guard)
@ApiOperation ( { summary : 'Снять роль с пользователя' , description : 'Только супер-администратор может снимать роли.' } )
@UseGuards ( RbacManage Guard)
@ApiOperation ( { summary : 'Снять роль с пользователя' } )
@ApiParam ( { name : 'userId' , description : 'ID пользователя' } )
@ApiParam ( { name : 'roleSlug' , description : 'Slug роли' } )
removeRole ( @Param ( 'userId' ) userId : string , @Param ( 'roleSlug' ) roleSlug : string , @CurrentAdmin ( ) admin : AdminRequestUser ) {
return this . core . rbac . RemoveUserRole ( { actorUserId : admin.id , userId , roleSlug } ) ;
}
@Post ( 'users/:userId/permissions' )
@UseGuards ( RbacManageGuard )
@ApiOperation ( { summary : 'Назначить право пользователю' , description : 'Прямое назначение permission без смены роли.' } )
@ApiParam ( { name : 'userId' , description : 'ID пользователя' } )
@ApiBody ( { type : AssignUserPermissionDto } )
assignPermission ( @Param ( 'userId' ) userId : string , @Body ( ) dto : AssignUserPermissionDto , @CurrentAdmin ( ) admin : AdminRequestUser ) {
return this . core . rbac . AssignUserPermission ( { actorUserId : admin.id , userId , permissionSlug : dto.permissionSlug } ) ;
}
@Delete ( 'users/:userId/permissions/:permissionSlug' )
@UseGuards ( RbacManageGuard )
@ApiOperation ( { summary : 'Снять право с пользователя' } )
@ApiParam ( { name : 'userId' , description : 'ID пользователя' } )
@ApiParam ( { name : 'permissionSlug' , description : 'Slug права' } )
removePermission (
@Param ( 'userId' ) userId : string ,
@Param ( 'permissionSlug' ) permissionSlug : string ,
@CurrentAdmin ( ) admin : AdminRequestUser
) {
return this . core . rbac . RemoveUserPermission ( { actorUserId : admin.id , userId , permissionSlug } ) ;
}
@Post ( 'oauth-clients' )
@ApiOperation ( { summary : 'Создать OAuth-приложение' , description : 'Создаёт OAuth2-клиент и возвращает client secret один раз.' } )
@ApiBody ( { type : CreateOAuthClientDto } )
@@ -93,6 +146,14 @@ export class RbacController {
return this . core . rbac . UpdateOAuthClient ( { actorUserId : admin.id , clientId , . . . dto } ) ;
}
@Delete ( 'oauth-clients/:clientId' )
@ApiOperation ( { summary : 'Удалить OAuth-приложение' , description : 'Полностью удаляет OAuth2-клиент и связанные данные.' } )
@ApiParam ( { name : 'clientId' , description : 'Client ID приложения' } )
deleteOAuthClient ( @Param ( 'clientId' ) clientId : string , @CurrentAdmin ( ) admin : AdminRequestUser ) {
assertAdminPermission ( admin , 'canManageOAuth' ) ;
return this . core . rbac . DeleteOAuthClient ( { actorUserId : admin.id , clientId } ) ;
}
@Post ( 'oauth-clients/:clientId/rotate-secret' )
@ApiOperation ( { summary : 'Перевыпустить client secret' , description : 'Генерирует новый secret для confidential-клиента.' } )
@ApiParam ( { name : 'clientId' , description : 'Client ID приложения' } )