diff --git a/src/controllers/UserGroupController.ts b/src/controllers/UserGroupController.ts new file mode 100644 index 0000000..edb8658 --- /dev/null +++ b/src/controllers/UserGroupController.ts @@ -0,0 +1,86 @@ +import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; +import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; +import { getConnectionManager, Repository } from 'typeorm'; +import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { UserGroupIdsNotMatchingError, UserGroupNotFoundError } from '../errors/UserGroupErrors'; +import { CreateUserGroup } from '../models/creation/CreateUserGroup'; +import { UserGroup } from '../models/entities/UserGroup'; + + +@JsonController('/usergroups') +export class UserController { + private userGroupsRepository: Repository; + + /** + * Gets the repository of this controller's model/entity. + */ + constructor() { + this.userGroupsRepository = getConnectionManager().get().getRepository(UserGroup); + } + + @Get() + @ResponseSchema(UserGroup, { isArray: true }) + @OpenAPI({ description: 'Lists all usergroups.' }) + getAll() { + return this.userGroupsRepository.find(); + } + + @Get('/:id') + @ResponseSchema(UserGroup) + @ResponseSchema(UserGroupNotFoundError, { statusCode: 404 }) + @OnUndefined(UserGroupNotFoundError) + @OpenAPI({ description: 'Returns a usergroup of a specified id (if it exists)' }) + getOne(@Param('id') id: number) { + return this.userGroupsRepository.findOne({ id: id }); + } + + @Post() + @ResponseSchema(UserGroup) + @ResponseSchema(UserGroupNotFoundError) + @OpenAPI({ description: 'Create a new usergroup object (id will be generated automagicly).' }) + async post(@Body({ validate: true }) createUserGroup: CreateUserGroup) { + let userGroup; + try { + userGroup = await createUserGroup.toUserGroup(); + } catch (error) { + return error; + } + + return this.userGroupsRepository.save(userGroup); + } + + @Put('/:id') + @ResponseSchema(UserGroup) + @ResponseSchema(UserGroupNotFoundError, { statusCode: 404 }) + @ResponseSchema(UserGroupIdsNotMatchingError, { statusCode: 406 }) + @OpenAPI({ description: "Update a usergroup object (id can't be changed)." }) + async put(@Param('id') id: number, @EntityFromBody() userGroup: UserGroup) { + let oldUserGroup = await this.userGroupsRepository.findOne({ id: id }); + + if (!oldUserGroup) { + throw new UserGroupNotFoundError() + } + + if (oldUserGroup.id != userGroup.id) { + throw new UserGroupIdsNotMatchingError(); + } + + await this.userGroupsRepository.update(oldUserGroup, userGroup); + return userGroup; + } + + @Delete('/:id') + @ResponseSchema(UserGroup) + @ResponseSchema(UserGroupNotFoundError, { statusCode: 404 }) + @OpenAPI({ description: 'Delete a specified usergroup (if it exists).' }) + async remove(@Param('id') id: number) { + let userGroup = await this.userGroupsRepository.findOne({ id: id }); + + if (!userGroup) { + throw new UserGroupNotFoundError(); + } + + await this.userGroupsRepository.delete(userGroup); + return userGroup; + } +} diff --git a/src/errors/UserGroupErrors.ts b/src/errors/UserGroupErrors.ts new file mode 100644 index 0000000..15495b9 --- /dev/null +++ b/src/errors/UserGroupErrors.ts @@ -0,0 +1,36 @@ +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; + +/** + * Error to throw when no groupname is set + */ +export class GroupNameNeededError extends NotFoundError { + @IsString() + name = "GroupNameNeededError" + + @IsString() + message = "no groupname is set!" +} + +/** + * Error to throw when a usergroup couldn't be found. + */ +export class UserGroupNotFoundError extends NotFoundError { + @IsString() + name = "UserGroupNotFoundError" + + @IsString() + message = "User Group not found!" +} + +/** + * Error to throw when two usergroups' ids don't match. + * Usually occurs when a user tries to change a usergroups's id. + */ +export class UserGroupIdsNotMatchingError extends NotAcceptableError { + @IsString() + name = "UserGroupIdsNotMatchingError" + + @IsString() + message = "The id's don't match!! \n If you wanted to change a usergroup's id: This isn't allowed" +} \ No newline at end of file diff --git a/src/models/creation/CreateUserGroup.ts b/src/models/creation/CreateUserGroup.ts new file mode 100644 index 0000000..d55618c --- /dev/null +++ b/src/models/creation/CreateUserGroup.ts @@ -0,0 +1,28 @@ +import { IsOptional, IsString } from 'class-validator'; +import { GroupNameNeededError } from '../../errors/UserGroupErrors'; +import { UserGroup } from '../entities/UserGroup'; + +export class CreateUserGroup { + @IsOptional() + @IsString() + name: string; + @IsOptional() + @IsString() + description?: string; + + public async toUserGroup(): Promise { + let newUserGroup: UserGroup = new UserGroup(); + + if (this.name === undefined) { + throw new GroupNameNeededError(); + } + + newUserGroup.name = this.name + if (this.description) { + newUserGroup.description = this.description + } + + console.log(newUserGroup) + return newUserGroup; + } +} \ No newline at end of file diff --git a/src/models/entities/UserGroup.ts b/src/models/entities/UserGroup.ts index c3b2f0c..2156d14 100644 --- a/src/models/entities/UserGroup.ts +++ b/src/models/entities/UserGroup.ts @@ -1,17 +1,17 @@ -import { PrimaryGeneratedColumn, Column, OneToMany, Entity, ManyToOne } from "typeorm"; import { IsInt, IsNotEmpty, IsOptional, - IsString, + IsString } from "class-validator"; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; import { Permission } from "./Permission"; /** * Defines the UserGroup interface. */ @Entity() -export abstract class UserGroup { +export class UserGroup { /** * Autogenerated unique id (primary key). */ @@ -37,7 +37,7 @@ export abstract class UserGroup { /** * The group's description */ - @Column({nullable: true}) + @Column({ nullable: true }) @IsOptional() @IsString() description?: string;