From 3c11d88557a2612bf4320ff669323bc048634e94 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 24 Feb 2021 18:17:30 +0100 Subject: [PATCH 1/5] Added new response types ref #146 --- src/models/enums/ResponseObjectType.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/enums/ResponseObjectType.ts b/src/models/enums/ResponseObjectType.ts index e0622be..a25ebd4 100644 --- a/src/models/enums/ResponseObjectType.ts +++ b/src/models/enums/ResponseObjectType.ts @@ -21,6 +21,8 @@ export enum ResponseObjectType { SCANSTATION = 'SCANSTATION', SELFSERVICEDONATION = 'SELFSERVICEDONATION', SELFSERVICERUNNER = 'SELFSERVICRUNNER', + SELFSERVICETEAM = 'SELFSERVICETEAM', + SELFSERVICEORGANIZATION = 'SELFSERVICEORGANIZATION', STATS = 'STATS', STATSCLIENT = 'STATSCLIENT', STATSORGANIZATION = 'STATSORGANIZATION', From ba396e0eba15647b3004437a5a9949c7a69e828d Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 24 Feb 2021 18:18:10 +0100 Subject: [PATCH 2/5] Added selfservice team response model ref #146 --- .../responses/ResponseSelfServiceTeam.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/models/responses/ResponseSelfServiceTeam.ts diff --git a/src/models/responses/ResponseSelfServiceTeam.ts b/src/models/responses/ResponseSelfServiceTeam.ts new file mode 100644 index 0000000..3e43343 --- /dev/null +++ b/src/models/responses/ResponseSelfServiceTeam.ts @@ -0,0 +1,36 @@ +import { IsInt, IsNotEmpty, IsPositive, IsString } from 'class-validator'; +import { RunnerTeam } from '../entities/RunnerTeam'; +import { ResponseObjectType } from '../enums/ResponseObjectType'; +import { IResponse } from './IResponse'; + +/** + * Defines the runner selfservice team response. + * Why? B/C runner's are not allowed to view all information available to admin users. +*/ +export class ResponseSelfServiceTeam implements IResponse { + /** + * The responseType. + * This contains the type of class/entity this response contains. + */ + responseType: ResponseObjectType = ResponseObjectType.SELFSERVICETEAM; + + /** + * The team's name. + */ + @IsNotEmpty() + @IsString() + name: string; + + /** + * The team's id. + * Will be used to insert runners it into that team. + */ + @IsInt() + @IsPositive() + id: number; + + public constructor(team: RunnerTeam) { + this.name = team.name; + this.id = team.id; + } +} \ No newline at end of file From ba3b5eeefc45f9bd94aef24f9f509f6835f5ea7c Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 24 Feb 2021 18:20:31 +0100 Subject: [PATCH 3/5] Added selfservice org response model ref #146 --- .../ResponseSelfServiceOrganisation.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/models/responses/ResponseSelfServiceOrganisation.ts diff --git a/src/models/responses/ResponseSelfServiceOrganisation.ts b/src/models/responses/ResponseSelfServiceOrganisation.ts new file mode 100644 index 0000000..aa8ae8b --- /dev/null +++ b/src/models/responses/ResponseSelfServiceOrganisation.ts @@ -0,0 +1,38 @@ +import { IsArray, IsNotEmpty, IsString } from 'class-validator'; +import { RunnerOrganization } from '../entities/RunnerOrganization'; +import { ResponseObjectType } from '../enums/ResponseObjectType'; +import { IResponse } from './IResponse'; +import { ResponseSelfServiceTeam } from './ResponseSelfServiceTeam'; + +/** + * Defines the runner selfservice organization response. + * Why? B/C runner's are not allowed to view all information available to admin users. +*/ +export class ResponseSelfServiceOrganisation implements IResponse { + /** + * The responseType. + * This contains the type of class/entity this response contains. + */ + responseType: ResponseObjectType = ResponseObjectType.SELFSERVICEORGANIZATION; + + /** + * The org's name. + */ + @IsNotEmpty() + @IsString() + name: string; + + /** + * The org's teams (just containing name and id). + */ + @IsArray() + teams: ResponseSelfServiceTeam[]; + + public constructor(org: RunnerOrganization) { + this.name = org.name; + this.teams = new Array(); + for (let team of org.teams) { + this.teams.push(new ResponseSelfServiceTeam(team)); + } + } +} \ No newline at end of file From 656f63dfd5fdbe13554fc98440e416be7e56d909 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 24 Feb 2021 18:23:08 +0100 Subject: [PATCH 4/5] Added selfservice org info endpoint ref #146 --- .../RunnerSelfServiceController.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/controllers/RunnerSelfServiceController.ts b/src/controllers/RunnerSelfServiceController.ts index eb35f48..324f9c1 100644 --- a/src/controllers/RunnerSelfServiceController.ts +++ b/src/controllers/RunnerSelfServiceController.ts @@ -12,10 +12,11 @@ import { CreateSelfServiceRunner } from '../models/actions/create/CreateSelfServ import { Runner } from '../models/entities/Runner'; import { RunnerGroup } from '../models/entities/RunnerGroup'; import { RunnerOrganization } from '../models/entities/RunnerOrganization'; +import { ResponseSelfServiceOrganisation } from '../models/responses/ResponseSelfServiceOrganisation'; import { ResponseSelfServiceRunner } from '../models/responses/ResponseSelfServiceRunner'; -@JsonController('/runners') +@JsonController() export class RunnerSelfServiceController { private runnerRepository: Repository; private orgRepository: Repository; @@ -28,7 +29,7 @@ export class RunnerSelfServiceController { this.orgRepository = getConnectionManager().get().getRepository(RunnerOrganization); } - @Get('/me/:jwt') + @Get('/runners/me/:jwt') @ResponseSchema(ResponseSelfServiceRunner) @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OnUndefined(RunnerNotFoundError) @@ -37,7 +38,7 @@ export class RunnerSelfServiceController { return (new ResponseSelfServiceRunner(await this.getRunner(token))); } - @Post('/register') + @Post('/runners/register') @ResponseSchema(ResponseSelfServiceRunner) @ResponseSchema(RunnerEmailNeededError, { statusCode: 406 }) @OpenAPI({ description: 'Create a new selfservice runner in the citizen org.
This endpoint shoud be used to allow "everyday citizen" to register themselves.
You have to provide a mail address, b/c the future we\'ll implement email verification.' }) @@ -50,7 +51,7 @@ export class RunnerSelfServiceController { return response; } - @Post('/register/:token') + @Post('/runners/register/:token') @ResponseSchema(ResponseSelfServiceRunner) @ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Create a new selfservice runner in a provided org.
The orgs get provided and authorized via api tokens that can be optained via the /organizations endpoint.' }) @@ -65,6 +66,17 @@ export class RunnerSelfServiceController { return response; } + @Get('/organizations/selfservice/:token') + @ResponseSchema(ResponseSelfServiceOrganisation, { isArray: false }) + @ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 }) + @OpenAPI({ description: 'Get the basic info and teams for a org.' }) + async getSelfserviceOrg(@Param('token') token: string) { + const orgid = (await this.getOrgansisation(token)).id; + const org = await this.orgRepository.findOne({ id: orgid }, { relations: ['teams'] }) + + return new ResponseSelfServiceOrganisation(org); + } + /** * Get's a runner by a provided jwt token. * @param token The runner jwt provided by the runner to identitfy themselves. From 28ef139a70e0c063982b2eb9167b7abe41db1621 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 24 Feb 2021 18:32:56 +0100 Subject: [PATCH 5/5] Added tests for the new org selfservice endpoints ref #146 --- src/tests/selfservice/selfservice_org.ts | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/tests/selfservice/selfservice_org.ts diff --git a/src/tests/selfservice/selfservice_org.ts b/src/tests/selfservice/selfservice_org.ts new file mode 100644 index 0000000..f269285 --- /dev/null +++ b/src/tests/selfservice/selfservice_org.ts @@ -0,0 +1,54 @@ +import axios from 'axios'; +import { config } from '../../config'; +const base = "http://localhost:" + config.internal_port + +let access_token; +let axios_config; + +beforeAll(async () => { + const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); + access_token = res.data["access_token"]; + axios_config = { + headers: { "authorization": "Bearer " + access_token }, + validateStatus: undefined + }; +}); + +// --------------- +describe('get invalid org', () => { + it('getting random org via selfservice should return 4040', async () => { + const res = await axios.get(base + '/api/organizations/selfservice/asfdasfasdfsdafsadfsadfasdfasdfsdf', axios_config); + expect(res.status).toEqual(404); + }); +}); + +// --------------- +describe('get valid org w/teams', () => { + let added_org; + let added_team; + it('creating a new org with just a name and registration enabled should return 200', async () => { + const res = await axios.post(base + '/api/organizations', { + "name": "test123", + "registrationEnabled": true + }, axios_config); + added_org = res.data; + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json") + }); + it('creating a new team with a parent org should return 200', async () => { + const res = await axios.post(base + '/api/teams', { + "name": "test_team", + "parentGroup": added_org.id + }, axios_config); + added_team = res.data; + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json") + }); + it('getting org via selfservice should return 200', async () => { + const res = await axios.get(base + '/api/organizations/selfservice/' + added_org.registrationKey, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + expect(res.data.name).toEqual(added_org.name); + expect(res.data.teams[0]).toEqual({ name: added_team.name, id: added_team.id }); + }); +}); \ No newline at end of file