import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { Repository, getConnectionManager } from 'typeorm'; import { PermissionIdsNotMatchingError, PermissionNeedsPrincipalError, PermissionNotFoundError } from '../errors/PermissionErrors'; import { PrincipalNotFoundError } from '../errors/PrincipalErrors'; import { CreatePermission } from '../models/actions/create/CreatePermission'; import { UpdatePermission } from '../models/actions/update/UpdatePermission'; import { Permission } from '../models/entities/Permission'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; import { ResponsePermission } from '../models/responses/ResponsePermission'; import { ResponsePrincipal } from '../models/responses/ResponsePrincipal'; @JsonController('/permissions') @OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] }) export class PermissionController { private permissionRepository: Repository; /** * Gets the repository of this controller's model/entity. */ constructor() { this.permissionRepository = getConnectionManager().get().getRepository(Permission); } @Get() @Authorized("PERMISSION:GET") @ResponseSchema(ResponsePermission, { isArray: true }) @OpenAPI({ description: 'Lists all permissions for all users and groups.' }) async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100) { let responsePermissions: ResponsePermission[] = new Array(); let permissions: Array; if (page != undefined) { permissions = await this.permissionRepository.find({ relations: ['principal'], skip: page * page_size, take: page_size }); } else { permissions = await this.permissionRepository.find({ relations: ['principal'] }); } permissions.forEach(permission => { responsePermissions.push(new ResponsePermission(permission)); }); return responsePermissions; } @Get('/:id') @Authorized("PERMISSION:GET") @ResponseSchema(ResponsePermission) @ResponseSchema(PermissionNotFoundError, { statusCode: 404 }) @OnUndefined(PermissionNotFoundError) @OpenAPI({ description: 'Lists all information about the permission whose id got provided.' }) async getOne(@Param('id') id: number) { let permission = await this.permissionRepository.findOne({ id: id }, { relations: ['principal'] }); if (!permission) { throw new PermissionNotFoundError(); } return new ResponsePermission(permission); } @Post() @Authorized("PERMISSION:CREATE") @ResponseSchema(ResponsePermission) @ResponseSchema(PrincipalNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Create a new permission for a existing principal(user/group).
If a permission with this target, action and prinicpal already exists that permission will be returned instead of creating a new one.' }) async post(@Body({ validate: true }) createPermission: CreatePermission) { let permission; try { permission = await createPermission.toEntity(); } catch (error) { throw error; } let existingPermission = await this.permissionRepository.findOne({ target: permission.target, action: permission.action, principal: permission.principal }, { relations: ['principal'] }); if (existingPermission) { return new ResponsePermission(existingPermission); } permission = await this.permissionRepository.save(permission); permission = await this.permissionRepository.findOne(permission, { relations: ['principal'] }); return new ResponsePermission(permission); } @Put('/:id') @Authorized("PERMISSION:UPDATE") @ResponseSchema(ResponsePrincipal) @ResponseSchema(PermissionNotFoundError, { statusCode: 404 }) @ResponseSchema(PrincipalNotFoundError, { statusCode: 404 }) @ResponseSchema(PermissionIdsNotMatchingError, { statusCode: 406 }) @ResponseSchema(PermissionNeedsPrincipalError, { statusCode: 406 }) @OpenAPI({ description: "Update a permission object.
If updateing the permission object would result in duplicate permission (same target, action and principal) this permission will get deleted and the existing permission will be returned.
Please remember that ids can't be changed." }) async put(@Param('id') id: number, @Body({ validate: true }) permission: UpdatePermission) { let oldPermission = await this.permissionRepository.findOne({ id: id }, { relations: ['principal'] }); if (!oldPermission) { throw new PermissionNotFoundError(); } if (oldPermission.id != permission.id) { throw new PermissionIdsNotMatchingError(); } let existingPermission = await this.permissionRepository.findOne({ target: permission.target, action: permission.action, principal: await permission.getPrincipal() }, { relations: ['principal'] }); if (existingPermission) { await this.remove(permission.id, true); return new ResponsePermission(existingPermission); } await this.permissionRepository.save(await permission.update(oldPermission)); return new ResponsePermission(await this.permissionRepository.findOne({ id: permission.id }, { relations: ['principal'] })); } @Delete('/:id') @Authorized("PERMISSION:DELETE") @ResponseSchema(ResponsePermission) @ResponseSchema(ResponseEmpty, { statusCode: 204 }) @OnUndefined(204) @OpenAPI({ description: 'Deletes the permission whose id you provide.
If no permission with this id exists it will just return 204(no content).' }) async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { let permission = await this.permissionRepository.findOne({ id: id }, { relations: ['principal'] }); if (!permission) { return null; } const responsePermission = new ResponsePermission(permission); await this.permissionRepository.delete(permission); return responsePermission; } }