import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { UserIdsNotMatchingError, UserNotFoundError } from '../errors/UserErrors'; import { UserGroupNotFoundError } from '../errors/UserGroupErrors'; import { CreateUser } from '../models/actions/CreateUser'; import { UpdateUser } from '../models/actions/UpdateUser'; import { User } from '../models/entities/User'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; import { ResponseUser } from '../models/responses/ResponseUser'; import { PermissionController } from './PermissionController'; @JsonController('/users') @OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] }) export class UserController { private userRepository: Repository; /** * Gets the repository of this controller's model/entity. */ constructor() { this.userRepository = getConnectionManager().get().getRepository(User); } @Get() @Authorized("USER:GET") @ResponseSchema(User, { isArray: true }) @OpenAPI({ description: 'Lists all users.' }) async getAll() { let responseUsers: ResponseUser[] = new Array(); const users = await this.userRepository.find({ relations: ['permissions', 'groups'] }); users.forEach(user => { responseUsers.push(new ResponseUser(user)); }); return responseUsers; } @Get('/:id') @Authorized("USER:GET") @ResponseSchema(User) @ResponseSchema(UserNotFoundError, { statusCode: 404 }) @OnUndefined(UserNotFoundError) @OpenAPI({ description: 'Returns a user of a specified id (if it exists)' }) async getOne(@Param('id') id: number) { let user = await this.userRepository.findOne({ id: id }, { relations: ['permissions', 'groups'] }) if (!user) { throw new UserNotFoundError(); } return new ResponseUser(user); } @Post() @Authorized("USER:CREATE") @ResponseSchema(User) @ResponseSchema(UserGroupNotFoundError) @OpenAPI({ description: 'Create a new user object (id will be generated automagicly).' }) async post(@Body({ validate: true }) createUser: CreateUser) { let user; try { user = await createUser.toUser(); } catch (error) { throw error; } user = await this.userRepository.save(user) return new ResponseUser(await this.userRepository.findOne({ id: user.id }, { relations: ['permissions', 'groups'] })); } @Put('/:id') @Authorized("USER:UPDATE") @ResponseSchema(User) @ResponseSchema(UserNotFoundError, { statusCode: 404 }) @ResponseSchema(UserIdsNotMatchingError, { statusCode: 406 }) @OpenAPI({ description: "Update a user object (id can't be changed)." }) async put(@Param('id') id: number, @Body({ validate: true }) updateUser: UpdateUser) { let oldUser = await this.userRepository.findOne({ id: id }); if (!oldUser) { throw new UserNotFoundError(); } if (oldUser.id != updateUser.id) { throw new UserIdsNotMatchingError(); } await this.userRepository.save(await updateUser.updateUser(oldUser)); return new ResponseUser(await this.userRepository.findOne({ id: id }, { relations: ['permissions', 'groups'] })); } @Delete('/:id') @Authorized("USER:DELETE") @ResponseSchema(User) @ResponseSchema(ResponseEmpty, { statusCode: 204 }) @OnUndefined(204) @OpenAPI({ description: 'Delete a user runner (if it exists).' }) async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { let user = await this.userRepository.findOne({ id: id }); if (!user) { return null; } const responseUser = await this.userRepository.findOne({ id: id }, { relations: ['permissions', 'groups'] });; const permissionControler = new PermissionController(); for (let permission of responseUser.permissions) { await permissionControler.remove(permission.id, true); } await this.userRepository.delete(user); return new ResponseUser(responseUser); } }