Merge pull request 'New org selfservice endpoint feature/146-more_selfservice_endpoints' (#147) from feature/146-more_selfservice_endpoints into dev
continuous-integration/drone/push Build is failing Details

Reviewed-on: #147
This commit is contained in:
Nicolai Ort 2021-02-24 19:58:47 +00:00
commit 45d61b487e
5 changed files with 146 additions and 4 deletions

View File

@ -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<Runner>;
private orgRepository: Repository<RunnerOrganization>;
@ -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. <br> This endpoint shoud be used to allow "everyday citizen" to register themselves. <br> 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. <br> 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(<RunnerOrganization>org);
}
/**
* Get's a runner by a provided jwt token.
* @param token The runner jwt provided by the runner to identitfy themselves.

View File

@ -21,6 +21,8 @@ export enum ResponseObjectType {
SCANSTATION = 'SCANSTATION',
SELFSERVICEDONATION = 'SELFSERVICEDONATION',
SELFSERVICERUNNER = 'SELFSERVICRUNNER',
SELFSERVICETEAM = 'SELFSERVICETEAM',
SELFSERVICEORGANIZATION = 'SELFSERVICEORGANIZATION',
STATS = 'STATS',
STATSCLIENT = 'STATSCLIENT',
STATSORGANIZATION = 'STATSORGANIZATION',

View File

@ -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<ResponseSelfServiceTeam>();
for (let team of org.teams) {
this.teams.push(new ResponseSelfServiceTeam(team));
}
}
}

View File

@ -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;
}
}

View File

@ -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 });
});
});