Skip to content

Commit

Permalink
validate API ID
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagobustamante committed Dec 14, 2017
1 parent 37369eb commit ff075c8
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 6 deletions.
6 changes: 4 additions & 2 deletions src/admin/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { ApiConfig, validateApiConfig } from '../../config/api';
import { ApiService } from '../../service/api';
import { Inject } from 'typescript-ioc';
import * as swagger from 'typescript-rest-swagger';
import { Configuration } from '../../configuration';

@Path('apis')
@swagger.Tags('APIs')
@swagger.Security('Bearer')
export class APIRest {
@Inject private service: ApiService;
@Inject private config: Configuration;

@GET
list( @QueryParam('name') name?: string,
Expand All @@ -23,7 +25,7 @@ export class APIRest {
@POST
addApi(api: ApiConfig): Promise<Return.NewResource<void>> {
return new Promise<Return.NewResource<void>>((resolve, reject) => {
validateApiConfig(api)
validateApiConfig(api, this.config.gateway.disableApiIdValidation)
.then(() => this.service.create(api))
.then((apiId) => resolve(new Return.NewResource<void>(`apis/${apiId}`)))
.catch(reject);
Expand All @@ -36,7 +38,7 @@ export class APIRest {
return new Promise<void>((resolve, reject) => {
api.id = id;

validateApiConfig(api)
validateApiConfig(api, this.config.gateway.disableApiIdValidation)
.then(() => this.service.update(api))
.then(() => resolve())
.catch(reject);
Expand Down
2 changes: 1 addition & 1 deletion src/admin/config/cli-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const parser = new ArgumentParser({
parser.addArgument(
['-c', '--config'],
{
help: 'The Tree-Gateway config file (tree-gateway.json).'
help: 'The Tree-Gateway config file (tree-gateway.yml).'
}
);

Expand Down
11 changes: 9 additions & 2 deletions src/config/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CircuitBreakerConfig, circuitBreakerConfigValidatorSchema } from './cir
import { Filter, filterSchema } from './filter';
import { ValidationError } from '../error/errors';
import { MiddlewareConfig, middlewareConfigValidatorSchema } from './middleware';
import { ObjectID } from 'bson';

/**
* The API config descriptor.
Expand Down Expand Up @@ -112,13 +113,19 @@ export let apiConfigValidatorSchema = Joi.object().keys({
version: Joi.alternatives(Joi.string(), Joi.number()).required()
});

export function validateApiConfig(apiConfig: ApiConfig) {
export function validateApiConfig(apiConfig: ApiConfig, disableApiIdValidation: boolean) {
return new Promise((resolve, reject) => {
Joi.validate(apiConfig, apiConfigValidatorSchema, (err, value) => {
if (err) {
reject(new ValidationError(err));
} else {
resolve(value);
if (disableApiIdValidation) {
return resolve(value);
}
if (value.id && !ObjectID.isValid(value.id)) {
return reject(new ValidationError(`Invalid API Id ${value.id}. The Id must be a valid ObjectID. To skip this validation, configure the 'disableApiIdValidation' property on tree-gateway.yml config file.`));
}
return resolve(value);
}
});
});
Expand Down
6 changes: 6 additions & 0 deletions src/config/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export interface GatewayConfig {
* If we are behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
*/
underProxy?: boolean;
/**
* Force the validation of any API Id. If the id is not validated, the data could not be synchronizable
* to Leanty dashboard.
*/
disableApiIdValidation?: boolean;
/**
* Configurations for gateway logger.
*/
Expand Down Expand Up @@ -138,6 +143,7 @@ export const gatewayConfigValidatorSchema = Joi.object().keys({
accessLogger: accessLoggerConfigSchema,
admin: adminConfigValidatorSchema,
cors: corsConfigSchema,
disableApiIdValidation: Joi.boolean(),
errorHandler: middlewareConfigValidatorSchema,
filter: Joi.array().items(middlewareConfigValidatorSchema),
healthcheck: Joi.string(),
Expand Down
2 changes: 1 addition & 1 deletion src/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export class Gateway extends EventEmitter {

private loadApi(api: ApiConfig): Promise<void> {
return new Promise<void>((resolve, reject) => {
validateApiConfig(api)
validateApiConfig(api, this.config.gateway.disableApiIdValidation)
.then((value: ApiConfig) => {
this.loadValidateApi(value);
resolve();
Expand Down
23 changes: 23 additions & 0 deletions test/unit/install-apis.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,29 @@ describe('Gateway APIs install', () => {
});
});

it('should be able to reject APIs with invalid IDs', () => {
return new Promise<void>((resolve, reject) => {
sdk.apis.addApi({
id: 'INVALID_ID',
name: 'Invalid API',
path: '/invalid',
proxy: {
target: {
host: 'http://httpbin.org'
}
},
version: '1.0.0'
})
.then((apiId) => {
reject('API could not be created with invalid ID');
})
.catch(err => {
expect(err.statusCode).to.eq(403);
resolve();
});
});
});

it('should be able to export Gateway Configuration', () => {
return new Promise<void>((resolve, reject) => {
sdk.config.get()
Expand Down

0 comments on commit ff075c8

Please sign in to comment.