diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts index 82fc1f0..846653f 100644 --- a/src/controllers/UserController.ts +++ b/src/controllers/UserController.ts @@ -8,6 +8,7 @@ import { UpdateUser } from '../models/actions/update/UpdateUser'; import { User } from '../models/entities/User'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; import { ResponseUser } from '../models/responses/ResponseUser'; +import { ResponseUserPermissions } from '../models/responses/ResponseUserPermissions'; import { PermissionController } from './PermissionController'; @@ -26,7 +27,7 @@ export class UserController { @Get() @Authorized("USER:GET") @ResponseSchema(ResponseUser, { isArray: true }) - @OpenAPI({ description: 'Lists all users.
This includes their groups and permissions directly granted to them (if existing/associated).' }) + @OpenAPI({ description: 'Lists all users.
This includes their groups and permissions granted to them.' }) async getAll() { let responseUsers: ResponseUser[] = new Array(); const users = await this.userRepository.find({ relations: ['permissions', 'groups', 'groups.permissions'] }); @@ -41,13 +42,25 @@ export class UserController { @ResponseSchema(ResponseUser) @ResponseSchema(UserNotFoundError, { statusCode: 404 }) @OnUndefined(UserNotFoundError) - @OpenAPI({ description: 'Lists all information about the user whose id got provided.
Please remember that only permissions granted directly to the user will show up here, not permissions inherited from groups.' }) + @OpenAPI({ description: 'Lists all information about the user whose id got provided.
Please remember that all permissions granted to the user will show up here.' }) async getOne(@Param('id') id: number) { let user = await this.userRepository.findOne({ id: id }, { relations: ['permissions', 'groups', 'groups.permissions'] }) if (!user) { throw new UserNotFoundError(); } return new ResponseUser(user); } + @Get('/:id/permissions') + @Authorized("USER:GET") + @ResponseSchema(ResponseUser) + @ResponseSchema(UserNotFoundError, { statusCode: 404 }) + @OnUndefined(UserNotFoundError) + @OpenAPI({ description: 'Lists all permissions granted to the user sorted into directly granted and inherited as permission response objects.' }) + async getPermissions(@Param('id') id: number) { + let user = await this.userRepository.findOne({ id: id }, { relations: ['permissions', 'groups', 'groups.permissions', 'permissions.principal', 'groups.permissions.principal'] }) + if (!user) { throw new UserNotFoundError(); } + return new ResponseUserPermissions(user); + } + @Post() @Authorized("USER:CREATE") @ResponseSchema(ResponseUser) diff --git a/src/models/responses/ResponseUser.ts b/src/models/responses/ResponseUser.ts index 3da5434..526d537 100644 --- a/src/models/responses/ResponseUser.ts +++ b/src/models/responses/ResponseUser.ts @@ -70,6 +70,7 @@ export class ResponseUser extends ResponsePrincipal { /** * The user's permissions. + * Directly granted or inherited converted to their string form and deduplicated. */ @IsArray() @IsOptional() diff --git a/src/models/responses/ResponseUserPermissions.ts b/src/models/responses/ResponseUserPermissions.ts new file mode 100644 index 0000000..d5a8a7b --- /dev/null +++ b/src/models/responses/ResponseUserPermissions.ts @@ -0,0 +1,40 @@ +import { + IsArray, + + + IsOptional +} from "class-validator"; +import { User } from '../entities/User'; +import { ResponsePermission } from './ResponsePermission'; + +/** + * Defines the user permission response (get /api/users/:id/permissions). +*/ +export class ResponseUserPermissions { + /** + * The permissions directly granted to the user. + */ + @IsArray() + @IsOptional() + directlyGranted: ResponsePermission[] = new Array(); + + /** + * The permissions directly inherited the user. + */ + @IsArray() + @IsOptional() + inherited: ResponsePermission[] = new Array(); + + /** + * Creates a ResponseUserPermissions object from a user. + * @param user The user the response shall be build for. + */ + public constructor(user: User) { + for (let permission of user.permissions) { + this.directlyGranted.push(permission.toResponse()); + } + for (let permission of user.inheritedPermissions) { + this.inherited.push(permission.toResponse()); + } + } +}