Skip to content

Commit

Permalink
fix: add security as a component
Browse files Browse the repository at this point in the history
  • Loading branch information
Tommy Gunnarsson authored and tgun89 committed Aug 20, 2019
1 parent 5cd1dbd commit c2389a3
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 24 deletions.
8 changes: 6 additions & 2 deletions lib/bagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { BaggerResponse } from './response';
import { BaggerRequest, Method } from './request';
import { BaggerRequestBody } from './request_body';
import { BaggerConfiguration, BaggerConfigurationInternal } from './configuration';
import { OpenAPIObject } from 'openapi3-ts';
import { OpenAPIObject, SecuritySchemeType } from 'openapi3-ts';
import { BaggerParameter, ParameterType } from './parameters';
import { BaggerComponentAdder, BaggerComponentGetter } from './component';
import { BaggerComponentAdder, BaggerComponentGetter, BaggerSecurityComponent } from './component';
import { schemaStorage, SchemaDefinition } from './schema_storage';

const internalConfiguration = new BaggerConfigurationInternal();
Expand Down Expand Up @@ -66,6 +66,10 @@ export function addRequest(path: string, method: Method): BaggerRequest {
return request;
}

export function securityComponent(name: string, type: SecuritySchemeType): BaggerSecurityComponent {
return new BaggerSecurityComponent(name, type);
}

/**
* Add a reusable component that can be referenced to.
*/
Expand Down
64 changes: 63 additions & 1 deletion lib/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Schema } from '@hapi/joi';
import { SchemaObject, ReferenceObject } from 'openapi3-ts';
import { SchemaObject, ReferenceObject, SecuritySchemeType, SecuritySchemeObject } from 'openapi3-ts';
import { createSwaggerDefinition } from './utils/create_swagger_definition';
import { BaggerConfigurationInternal } from './configuration';

Expand All @@ -9,11 +9,68 @@ export interface SchemaComponentObject {
[schema: string]: SchemaObject | ReferenceObject;
}

export interface SecuritySchemeComponentObject {
[name: string]: SecuritySchemeObject;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isReference(value: any): value is ReferenceObject {
return value.$ref && typeof value.$ref === 'string';
}

export class BaggerSecurityComponent {
private key: string;
private _name?: string;
private type: SecuritySchemeType;
private _scheme?: string;
private _in?: string;
private _openIdConnectUrl?: string;
private _description?: string;

public constructor(key: string, type: SecuritySchemeType) {
this.key = key;
this.type = type;
}

public scheme(scheme: string): BaggerSecurityComponent {
this._scheme = scheme;
return this;
}

public in(location: string): BaggerSecurityComponent {
this._in = location;
return this;
}

public openIdConnectUrl(openIdConnectUrl: string): BaggerSecurityComponent {
this._openIdConnectUrl = openIdConnectUrl;
return this;
}

public description(description: string): BaggerSecurityComponent {
this._description = description;
return this;
}

public name(name: string): BaggerSecurityComponent {
this._name = name;
return this;
}

public compile(): { [key: string]: SecuritySchemeObject } {
return {
[this.key]: {
type: this.type,
description: this._description,
in: this._in,
scheme: this._scheme,
openIdConnectUrl: this._openIdConnectUrl,
name: this._name
}
};
}
}

export class BaggerSchemaComponent {
private name: string;
private schema: Schema | ReferenceObject;
Expand Down Expand Up @@ -54,6 +111,11 @@ export class BaggerComponentAdder {
this.internalConfiguration = internalConfiguration;
}

public security(component: BaggerSecurityComponent): BaggerSecurityComponent {
this.internalConfiguration.addSecurityComponent(component);
return component;
}

/**
* Add a reusable data model (schema).
* @param name A unique id that is used to referance the component.
Expand Down
48 changes: 27 additions & 21 deletions lib/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { BaggerRequest } from './request';
import {
ExternalDocumentationObject,
SecurityRequirementObject,
ServerObject,
InfoObject,
OpenAPIObject,
Expand All @@ -10,7 +9,12 @@ import {
} from 'openapi3-ts';
import { cleanObject } from './utils/clean_object';
import { validateSchema } from './utils/validate_schema';
import { BaggerSchemaComponent, SchemaComponentObject } from './component';
import {
BaggerSchemaComponent,
SchemaComponentObject,
BaggerSecurityComponent,
SecuritySchemeComponentObject
} from './component';
import { Schema } from '@hapi/joi';

class BaggerMultipleComponentsWithSameNameFoundError extends Error {}
Expand All @@ -19,7 +23,6 @@ class BaggerComponentNotFoundError extends Error {}
interface SwaggerConfiguration {
info: InfoObject;
servers?: ServerObject[];
security?: SecurityRequirementObject[];
externalDocs?: ExternalDocumentationObject;
}

Expand Down Expand Up @@ -48,15 +51,6 @@ export class BaggerConfiguration {
return this;
}

/**
* Add an authentication component to the OpenAPI schema.
* @param security The authentication object.
*/
public addSecurity(security: SecurityRequirementObject): BaggerConfiguration {
this.internalConfiguration.addSecurity(security);
return this;
}

/**
* Define external documentation for the OpenAPI schema.
* @param externalDocs The external documentation object. Containing an URL.
Expand All @@ -69,12 +63,14 @@ export class BaggerConfiguration {

interface BaggerComponents {
schemas: BaggerSchemaComponent[];
securitySchemes: BaggerSecurityComponent[];
}

export class BaggerConfigurationInternal {
private requests: BaggerRequest[] = [];
private components: BaggerComponents = {
schemas: []
schemas: [],
securitySchemes: []
};
private configuration: SwaggerConfiguration = {
info: {
Expand All @@ -87,6 +83,10 @@ export class BaggerConfigurationInternal {
this.requests.push(request);
}

public addSecurityComponent(component: BaggerSecurityComponent): void {
this.components.securitySchemes.push(component);
}

public addSchemaComponent(component: BaggerSchemaComponent): void {
this.components.schemas.push(component);
}
Expand All @@ -113,13 +113,6 @@ export class BaggerConfigurationInternal {
this.configuration.servers.push(server);
}

public addSecurity(security: SecurityRequirementObject): void {
if (!this.configuration.security) {
this.configuration.security = [];
}
this.configuration.security.push(security);
}

public setExternalDocs(externalDocs: ExternalDocumentationObject): void {
this.configuration.externalDocs = externalDocs;
}
Expand Down Expand Up @@ -150,10 +143,23 @@ export class BaggerConfigurationInternal {
}, {});
}

public compileSecurityComponents(): SecuritySchemeComponentObject {
const unmergedComponents = this.components.securitySchemes.map(component => component.compile());
return unmergedComponents.reduce((securitySchemes: SecuritySchemeComponentObject, component) => {
securitySchemes = {
...securitySchemes,
...component
};
return securitySchemes;
}, {});
}

private compileComponents(): ComponentsObject {
const schemas = this.compileSchemaComponents();
const securitySchemes = this.compileSecurityComponents();
return {
schemas
schemas,
securitySchemes
};
}

Expand Down
1 change: 1 addition & 0 deletions test/__snapshots__/component.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Object {
"type": "object",
},
},
"securitySchemes": Object {},
},
"info": Object {
"title": "",
Expand Down
3 changes: 3 additions & 0 deletions test/__snapshots__/configuration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`Bagger compiler A request can be included 1`] = `
Object {
"components": Object {
"schemas": Object {},
"securitySchemes": Object {},
},
"info": Object {
"description": "Provides resources related to building swagger definitions",
Expand Down Expand Up @@ -33,6 +34,7 @@ exports[`Bagger compiler Add a request and get the schema 1`] = `
Object {
"components": Object {
"schemas": Object {},
"securitySchemes": Object {},
},
"info": Object {
"description": "Provides resources related to building swagger definitions",
Expand Down Expand Up @@ -94,6 +96,7 @@ exports[`Bagger compiler An empty definition should compile 1`] = `
Object {
"components": Object {
"schemas": Object {},
"securitySchemes": Object {},
},
"info": Object {
"description": "Provides resources related to building swagger definitions",
Expand Down
15 changes: 15 additions & 0 deletions test/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,19 @@ describe('Bagger compiler', () => {
expect(bagger.getRequestSchema('/bags', 'post')).toEqual({ body: schema });
expect(bagger.compile()).toMatchSnapshot();
});

test('Add security scheme and compile', () => {
bagger.configure().info(defaultInfo);
bagger.addComponent().security(
bagger
.securityComponent('ApiKeyAuth', 'apiKey')
.in('header')
.name('Authorization')
);
bagger
.addRequest('/bags', 'get')
.addTag('bags')
.addResponse(bagger.response(200).description('Got bags!'));
//expect(bagger.compile()).toMatchSnapshot();
});
});

0 comments on commit c2389a3

Please sign in to comment.