Skip to content

Commit

Permalink
feat: Bearer token based auth for PactFlow Broker
Browse files Browse the repository at this point in the history
  • Loading branch information
YOU54F committed Sep 26, 2024
1 parent a08ac4c commit f42f3ed
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,22 @@ pacts from the broker by Pact Broker version tags.
If the pact broker has basic auth enabled, pass a --user option with username and password joined by a colon
(i.e. THE_USERNAME:THE_PASSWORD) to access the pact broker resources.

If the pact broker has bearer token auth enabled, pass a --token option along with the token to access the pact broker resources.

You can also set the following environment variables

- Basic Auth
- `PACT_BROKER_USERNAME`
- `PACT_BROKER_PASSWORD`
- Bearer Auth
- `PACT_BROKER_TOKEN`

Options:
-V, --version output the version number
-p, --provider [string] The name of the provider in the pact broker
-t, --tag [string] The tag to filter pacts retrieved from the pact broker
-u, --user [USERNAME:PASSWORD] The basic auth username and password to access the pact broker
-u, --token [string] The bearer token to access the pact broker
-a, --analyticsUrl [string] The url to send analytics events to as a http post
-o, --outputDepth [integer] Specifies the number of times to recurse while formatting the output objects. This is useful in case of large complicated objects or schemas. (default: 4)
-A, --additionalPropertiesInResponse [boolean] allow additional properties in response bodies, default false
Expand Down Expand Up @@ -356,6 +367,22 @@ If the Pact Broker is behind basic auth, you can pass credentials with the `--us
swagger-mock-validator /path/to/swagger.json https://pact-broker.com --provider my-provider-name --user BASIC_AUTH_USER:BASIC_AUTH_PASSWORD
```
You can also use environment variables
```
PACT_BROKER_USERNAME=BASIC_AUTH_USER PACT_BROKER_PASSWORD=BASIC_AUTH_PASSWORD swagger-mock-validator /path/to/swagger.json https://pact-broker.com --provider my-provider-name
```
If the Pact Broker is behind bearer auth, you can pass credentials with the `--token` option while invoking the tool.
```
swagger-mock-validator /path/to/swagger.json https://pact-broker.com --provider my-provider-name --token bar
```
You can also use environment variables
```
PACT_BROKER_TOKEN=bar swagger-mock-validator /path/to/swagger.json https://pact-broker.com --provider my-provider-name
```
### Analytics (Opt-In)
The tool can be configured to send analytics events to a server of your choosing. Use the `--analyticsUrl` flag to pass a url that the tool should post the event to. The tool will send this event via a http post request and will timeout after 5 seconds. See [analytics.ts](lib/swagger-mock-validator/analytics.ts) for the post body schema.
Expand Down
8 changes: 7 additions & 1 deletion lib/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ program
.option('-p, --provider [string]', 'The name of the provider in the pact broker')
.option('-t, --tag [string]', 'The tag to filter pacts retrieved from the pact broker')
.option('-u, --user [USERNAME:PASSWORD]', 'The basic auth username and password to access the pact broker')
.option('-b, --token [string]', 'The bearer token to access the pact broker')
.option('-a, --analyticsUrl [string]', 'The url to send analytics events to as a http post')
.option('-o, --outputDepth [integer]', 'Specifies the number of times to recurse ' +
'while formatting the output objects. ' +
Expand Down Expand Up @@ -76,7 +77,12 @@ If the pact broker has basic auth enabled, pass a --user option with username an
)
.action(async (swagger, mock, options) => {
try {
const swaggerMockValidator = SwaggerMockValidatorFactory.create(options.user);
if (!options.user && process.env.PACT_BROKER_USERNAME != '' && process.env.PACT_BROKER_PASSWORD != '') {
options.user = process.env.PACT_BROKER_USERNAME + ':' + process.env.PACT_BROKER_PASSWORD;
} else if (!options.token && process.env.PACT_BROKER_TOKEN != '') {
options.token = process.env.PACT_BROKER_TOKEN;
}
const swaggerMockValidator = SwaggerMockValidatorFactory.create(options.user ?? options.token);

const result = await swaggerMockValidator.validate({
analyticsUrl: options.analyticsUrl,
Expand Down
12 changes: 11 additions & 1 deletion lib/swagger-mock-validator/clients/http-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ import axios from 'axios';

export class HttpClient {
public async get(url: string, auth?: string): Promise<string> {
let authHeader: string | undefined;

if (auth) {
if (auth.includes(':')) {
authHeader = 'Basic ' + Buffer.from(auth).toString('base64');
} else {
authHeader = 'Bearer ' + auth;
}
}

const response = await axios.get(url, {
headers: {
...(auth ? {authorization: 'Basic ' + Buffer.from(auth).toString('base64')} : {})
...(authHeader ? { Authorization: authHeader } : {})
},
timeout: 30000,
transformResponse: (data) => data,
Expand Down
15 changes: 15 additions & 0 deletions test/e2e/cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,21 @@ describe('swagger-mock-validator/cli', () => {
jasmine.stringMatching('test/e2e/fixtures/pact-broker.json')
);
}, 30000);
it('should make an bearer token authenticated request to the provided pact broker url when asked to do so', async () => {
const auth = 'token';

await invokeCommand({
auth,
mock: urlTo('test/e2e/fixtures/pact-broker.json'),
providerName: 'provider-1',
swagger: urlTo('test/e2e/fixtures/swagger-provider.json')
});

expect(mockPactBroker.get).toHaveBeenCalledWith(
jasmine.objectContaining({authorization: 'Bearer token'}),
jasmine.stringMatching('test/e2e/fixtures/pact-broker.json')
);
}, 30000);

it('should format output objects to depth 0', async () => {
const result = await invokeCommand({
Expand Down

0 comments on commit f42f3ed

Please sign in to comment.