Skip to content

Commit

Permalink
feat(security): add support for OAS securitySchemes (http & apiKey)
Browse files Browse the repository at this point in the history
  • Loading branch information
uglow committed Oct 6, 2020
1 parent 987fd49 commit a5459bf
Show file tree
Hide file tree
Showing 14 changed files with 954 additions and 77 deletions.
87 changes: 63 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [Linting](#linting)
- [Building](#building)
- [Comparing](#comparing)
- [Validating](#validating)
- Deploying (Coming soon)
- [Config file](#config-file)

Expand All @@ -32,11 +33,12 @@ oaat --help

## Usage

This tool does 4 things:
This tool does 5 things:
- `oaat record` records API responses to requests specified in `x-examples` fields in an OpenAPI 3.x spec file.
- `oaat lint` lints an OpenAPI 3.x spec file (basic formatting; tools like [speccy](https://www.npmjs.com/package/speccy) provide more capability, but don't do formatting).
- `oaat compare` compares the earlier-recorded responses to the last responses for endpoints in an OpenAPI 3.x spec file.
- `oaat build` creates an OpenAPI 3.x spec file with [API Gateway][api-gateway-url] headers, optionally with mock responses for the APIs.
- `oaat compare` compares the earlier-recorded responses to the last responses for endpoints in an OpenAPI 3.x spec file.
- `oaat validate` validates that a spec-file is compliant with the OpenAPI 3.x specification.
- (Coming soon) `oaat deploy` deploys an OpenAPI 3.x spec file that has the API Gateway headers to API Gateway.

## Recording
Expand All @@ -54,12 +56,13 @@ Usage: oaat record [options] <jsonFile> [serverUrl]
Record the responses of API spec file endpoint requests (optionally use a different server to make requests)

Options:
-o, --output <file> Output file (if different to jsonFile)
-c, --config <file> Config file to override default config
-q, --quiet No logging
-v, --verbose Verbose logging
-d, --dry-run Dry run (no changes made)
-h, --help display help for command
-o, --output <file> Output file (if different to jsonFile)
-c, --config <file> Config file to override default config
-s, --sec-tokens <key=val,> Pass security token(s) matching the "key" in spec.securitySchemes, with a "value"
-q, --quiet No logging
-v, --verbose Verbose logging
-d, --dry-run Dry run (no changes made)
-h, --help display help for command
```

To get valid example responses - to use for mocking & as documentation - we need to add some custom
Expand Down Expand Up @@ -190,6 +193,15 @@ The above JavaScript module exports an async function which returns an object as
The `queueWrapper()` function is there to combine multiple requests into a single request, in scenarios where
multiple endpoint-examples require the same async-value.

### Security tokens and headers

APIs are often protected with security tokens and headers. To call these APIs, the security token can
be passed to the command line via `-s securityHeaderType=123someValue,nextToken=nextValue,...`. Alternatively,
the security token values can be specified in the `securitySchemes` section of [configuration file](config-file).
By default, `securitySchemes` contains no keys.

`oaat` will **always** pick the first security scheme when there are multiple security schemes available for an endpoint.

### Disabling endpoint recording

Sometimes it may be necessary to disable the recording of certain endpoints, while keeping the endpoint in the spec.
Expand Down Expand Up @@ -249,18 +261,21 @@ There are lots of good tools that can check the syntax and style of Open API Sep

```shell script
$ oaat lint --help
Usage: oaat lint [options] <jsonFile>
Usage: oaat lint [options] <jsonFile> [serverUrl]

Tidy the API Spec up a bit

Options:
-o, --output <file> Output file (if different to jsonFile)
-c, --config <file> Config file to override default config
-q, --quiet no logging
-v, --verbose verbose logging
-h, --help display help for command
-o, --output <file> Output file (if different to jsonFile)
-c, --config <file> Config file to override default config
-s, --sec-tokens <key=val,> Pass security token(s) matching the "key" in spec.securitySchemes, with a "value"
-q, --quiet no logging
-v, --verbose verbose logging
-h, --help display help for command
```

Note: `serverUrl` and `sec-tokens` are only required when the `config.lint.syncExamples` is `true`.

See the [configuration file](config-file) for further options.

## Building
Expand All @@ -270,7 +285,7 @@ Creates an OpenAPI 3.x spec file with [API Gateway][api-gateway-url] headers, op
### Command

```shell script
$ oaat lint --help
$ oaat build --help
Usage: oaat build [options] <jsonFile> <outputJsonFile> [serverUrl]

Adds custom headers & Swagger UI endpoint to allow deployment of spec file to AWS API Gateway with documentation
Expand Down Expand Up @@ -339,7 +354,6 @@ by specifying multiple API paths as property keys (see example below).
}
```


## Comparing

Compares the earlier-recorded responses to the last responses for endpoints in an OpenAPI 3.x spec file.
Expand All @@ -349,17 +363,35 @@ snapshots, and comparing those to the latest responses.
### Command

```shell script
$ oaat lint --help
Usage: oaat compare [options] <jsonFile> <outputJsonFile> [serverUrl]
Usage: oaat compare [options] <jsonFile> [serverUrl]

Adds custom headers & Swagger UI endpoint to allow deployment of spec file to AWS API Gateway with documentation
Compares recorded responses (referenced by the spec file) to the latest responses

Options:
-c, --config <file> Config file to override default config
-s, --sec-tokens <key=val,> Pass security token(s) matching the "key" in spec.securitySchemes, with a "value"
-m --compare-mode <mode> Comparison mode: "value" (default), "type", "schema"
-q, --quiet no logging
-v, --verbose verbose logging
-h, --help display help for command
```

## Validating

This command validates the JSON spec file against the Open API 3.x schema.
Any errors are listed in the output.

### Command

```shell script
$ oaat validate --help
Usage: oaat validate [options] <jsonFile>

Validate the API spec file against the OAS 3.x schema

Options:
-c, --config <file> Config file to override default config
-m, --compare-mode <mode> Compares by "value" (default), "type", "schema"
-q, --quiet No logging
-v, --verbose Verbose logging
-h, --help display help for command
-h, --help display help for command

```

## Config file
Expand Down Expand Up @@ -426,6 +458,8 @@ module.exports = {
sortComponentsAlphabetically: true,

// Updates the parameter and requestBody examples using the x-examples from the 200 response
// Requires a API server to be in the spec or specified in the command line if any paramaters come from scripts
// Requires config.securitySchemes (or `sec-tokens` on the command line) to be specified if any APIs specify the "security" property.
syncExamples: true
},

Expand All @@ -447,6 +481,11 @@ module.exports = {
// A URI (URL or data:image/x-icon;base64 encode image) for the favicon
webFaviconHref: 'url or data:image/x-icon;base64',
},
// If you wish to record your security tokens here, you may.
securitySchemes: {
schemeName1: { value: 'static value' },
schemeName2: { script: 'path/to/script.js' }
}
};
```

Expand Down
3 changes: 3 additions & 0 deletions fixtures/invalidSpecV2.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"swagger": "2.0",
"servers": [{
"url": "foo"
}],
"info": {
"description": "VFE API",
"version": "1.0.0",
Expand Down
3 changes: 0 additions & 3 deletions fixtures/output/lint2.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@
},
"id_2": {
"value": "2"
},
"badParam": {
"value": "wrong-param"
}
}
}
Expand Down
183 changes: 183 additions & 0 deletions fixtures/specWithValidExamples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
{
"openapi": "3.0.0",
"info": {
"description": "Fake Online REST API for Testing and Prototyping",
"version": "1.0.0",
"title": "JSON Placeholder"
},
"tags": [
{
"name": "posts"
}
],
"servers": [
{
"url": "https://jsonplaceholder.typicode.com"
}
],
"paths": {
"/posts": {
"get": {
"tags": [
"posts"
],
"summary": "Get all available posts",
"parameters": [
{
"name": "id",
"in": "query",
"description": "Filter by post ID",
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "userId",
"in": "query",
"description": "Filter by user ID",
"required": false,
"schema": {
"type": "string"
},
"examples": {
"products": {
"value": "products"
},
"service": {
"value": "services"
},
"eligibility-enterprise": {
"value": "eligibility"
},
"eligibility-inactive": {
"value": "eligibility"
},
"invalidToken": {
"value": "eligibility"
}
}
}
],
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
},
"x-mock-file": "",
"x-examples": {
"default": {
"parameters": [
{
"value": null
},
{
"value": null
}
]
}
}
}
}
}
}
},
"components": {
"schemas": {
"Post": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"userId": {
"type": "integer",
"format": "int64"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
}
}
},
"User": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"username": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"phone": {
"type": "string"
},
"website": {
"type": "string"
},
"company": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"catchPhrase": {
"type": "string"
},
"bs": {
"type": "string"
}
}
},
"address": {
"type": "object",
"properties": {
"street": {
"type": "string"
},
"suite": {
"type": "string"
},
"city": {
"type": "string"
},
"zipcode": {
"type": "string"
},
"geo": {
"type": "object",
"properties": {
"lat": {
"type": "string"
},
"lng": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
8 changes: 4 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ module.exports = {
coverageDirectory: '<rootDir>/test-reports/coverage',
coverageThreshold: {
global: {
statements: 50,
branches: 50,
functions: 50,
lines: 50,
statements: 55,
branches: 55,
functions: 55,
lines: 55,
},
},
testTimeout: 20000,
Expand Down
Loading

0 comments on commit a5459bf

Please sign in to comment.