forked from loafle/openapi-generator-original
Add support for global token based auth for k6 script generation (#19348)
* Add global token based auth support (basic, bearer) for k6 * config files and generated code files after the changes * Handle empty or null auth at path level * files changed after update with master and run build
This commit is contained in:
parent
2b40a2c058
commit
f13a11b53c
4
bin/configs/k6-basic-auth.yaml
Normal file
4
bin/configs/k6-basic-auth.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
generatorName: k6
|
||||
outputDir: samples/client/others/k6/basicAuth
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/k6/basic_auth.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/k6
|
4
bin/configs/k6-bearer-auth.yaml
Normal file
4
bin/configs/k6-bearer-auth.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
generatorName: k6
|
||||
outputDir: samples/client/others/k6/bearerAuth
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/k6/bearer_auth.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/k6
|
@ -362,6 +362,7 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public static final String PROJECT_DESCRIPTION = "projectDescription";
|
||||
public static final String PROJECT_VERSION = "projectVersion";
|
||||
public static final String BASE_URL = "baseURL";
|
||||
public static final String TOKEN = "authToken";
|
||||
public static final String PRESERVE_LEADING_PARAM_CHAR = "preserveLeadingParamChar";
|
||||
static final Collection<String> INVOKER_PKG_SUPPORTING_FILES = Arrays.asList("script.mustache", "README.mustache");
|
||||
static final String[][] JAVASCRIPT_SUPPORTING_FILES = {
|
||||
@ -666,7 +667,7 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
pathVariables.put(groupName, variables);
|
||||
|
||||
// put auth medthods in header or cookie
|
||||
// put auth methods in header or cookie
|
||||
for (CodegenSecurity globalAuthMethod : globalAuthMethods) {
|
||||
if (globalAuthMethod.isKeyInHeader) {
|
||||
httpParams.add(new Parameter(globalAuthMethod.keyParamName, getTemplateString(toVarName(globalAuthMethod.keyParamName))));
|
||||
@ -676,6 +677,25 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
cookieParams.add(new Parameter(globalAuthMethod.keyParamName, getTemplateString(toVarName(globalAuthMethod.keyParamName))));
|
||||
extraParameters.add(new Parameter(toVarName(globalAuthMethod.keyParamName), globalAuthMethod.keyParamName.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
// when security is specifically given empty for an end point, it should not be included
|
||||
if (operation.getSecurity() != null && operation.getSecurity().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if ("bearerAuth".equalsIgnoreCase(globalAuthMethod.name)) {
|
||||
if (operation.getSecurity() == null ||
|
||||
operation.getSecurity().stream().anyMatch(securityRequirement -> securityRequirement.containsKey("bearerAuth"))) {
|
||||
httpParams.add(new Parameter("Authorization", "`Bearer ${TOKEN}`"));
|
||||
additionalProperties.put(TOKEN, true);
|
||||
}
|
||||
}
|
||||
if ("basicAuth".equalsIgnoreCase(globalAuthMethod.name)) {
|
||||
if (operation.getSecurity() == null ||
|
||||
operation.getSecurity().stream().anyMatch(securityRequirement -> securityRequirement.containsKey("basicAuth"))) {
|
||||
httpParams.add(new Parameter("Authorization", "`Basic ${TOKEN}`"));
|
||||
additionalProperties.put(TOKEN, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final HTTPParameters params = new HTTPParameters(null, cookieParams, httpParams, null, null, null, null, null,
|
||||
|
@ -4,6 +4,9 @@ import http from "k6/http";
|
||||
import { group, check, sleep } from "k6";
|
||||
|
||||
const BASE_URL = "{{baseURL}}";
|
||||
{{#authToken}}
|
||||
const TOKEN = "TOKEN_VALUE_HERE";
|
||||
{{/authToken}}
|
||||
// Sleep duration between successive requests.
|
||||
// You might want to edit the value of this variable or remove calls to the sleep function on the script.
|
||||
const SLEEP_DURATION = 0.1;
|
||||
|
@ -0,0 +1,56 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Sample API
|
||||
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
|
||||
version: 0.1.9
|
||||
servers:
|
||||
- url: http://api.example.com/v1
|
||||
description: Optional server description, e.g. Main (production) server
|
||||
- url: http://staging-api.example.com
|
||||
description: Optional server description, e.g. Internal staging server for testing
|
||||
security:
|
||||
- basicAuth: []
|
||||
paths:
|
||||
/users:
|
||||
get:
|
||||
summary: Returns a list of users.
|
||||
description: Optional extended description in CommonMark or HTML.
|
||||
responses:
|
||||
"200": # status code
|
||||
description: A JSON array of user names
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
security:
|
||||
- basicAuth: []
|
||||
/public:
|
||||
get:
|
||||
summary: Returns public information.
|
||||
description: This endpoint does not require authentication.
|
||||
responses:
|
||||
"200":
|
||||
description: A JSON object with public information
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
security: []
|
||||
/private:
|
||||
get:
|
||||
summary: Returns private information.
|
||||
description: This endpoint requires global security settings.
|
||||
responses:
|
||||
"200":
|
||||
description: A JSON object with private information
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
components:
|
||||
securitySchemes:
|
||||
basicAuth:
|
||||
type: http
|
||||
scheme: basic
|
@ -0,0 +1,57 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Sample API
|
||||
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
|
||||
version: 0.1.9
|
||||
servers:
|
||||
- url: http://api.example.com/v1
|
||||
description: Optional server description, e.g. Main (production) server
|
||||
- url: http://staging-api.example.com
|
||||
description: Optional server description, e.g. Internal staging server for testing
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/users:
|
||||
get:
|
||||
summary: Returns a list of users.
|
||||
description: Optional extended description in CommonMark or HTML.
|
||||
responses:
|
||||
"200": # status code
|
||||
description: A JSON array of user names
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
security:
|
||||
- bearerAuth: []
|
||||
/public:
|
||||
get:
|
||||
summary: Returns public information.
|
||||
description: This endpoint does not require authentication.
|
||||
responses:
|
||||
"200":
|
||||
description: A JSON object with public information
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
security: []
|
||||
/private:
|
||||
get:
|
||||
summary: Returns private information.
|
||||
description: This endpoint requires global security settings.
|
||||
responses:
|
||||
"200":
|
||||
description: A JSON object with private information
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT # Optional: specify the format (e.g., JWT) if applicable
|
23
samples/client/others/k6/basicAuth/.openapi-generator-ignore
Normal file
23
samples/client/others/k6/basicAuth/.openapi-generator-ignore
Normal file
@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
@ -0,0 +1,2 @@
|
||||
README.md
|
||||
script.js
|
@ -0,0 +1 @@
|
||||
7.9.0-SNAPSHOT
|
15
samples/client/others/k6/basicAuth/README.md
Normal file
15
samples/client/others/k6/basicAuth/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Generated k6 script
|
||||
|
||||
The `script.js` file contains most of the Swagger/OpenAPI specification and you can customize it to your needs.
|
||||
|
||||
Global header variables are defined at the top of the file, like `api_key`. Each path in the specification is converted into a [group](https://docs.k6.io/docs/tags-and-groups) in k6 and each group contains all the request methods related to that path. Path and query parameters are extracted from the specification and put at the start of the group. The URL is constructed from the base URL plus path and query.
|
||||
|
||||
If the Swagger/OpenAPI specification used as the input spec contains examples at parameter level, those will be extracted and utilized as parameter values. The `handleParamValue` custom Mustache lambda registered for use in the K6 `script.mustache` template handles the conditional checks, formatting, and outputting of parameter values. If a given parameter has value specified – either in `example` or `examples` field, defined at the parameter level – that value will be used. For list (`examples`), entire list will be output in the generated script and the first element from that list will be assigned as parameter value. If a given parameter does not have an example defined, a placeholder value with `TODO_EDIT_THE_` prefix will be generated for that parameter, and you will have to assign a value before you can run the script. In other words, you can now generate K6 test scripts which are ready to run, provided the Swagger/OpenAPI specification used as the input spec contains examples for all of the path/query parameters; see `modules/openapi-generator/src/test/resources/3_0/examples.yaml` for an example of such specification, and https://swagger.io/docs/specification/adding-examples/ for more information about adding examples.
|
||||
|
||||
k6 specific parameters are in the [`params`](https://docs.k6.io/docs/params-k6http) object, and `body` contains the [request](https://docs.k6.io/docs/http-requests) body which is in the form of `identifier: type`, which the `type` should be substituted by a proper value. Then goes the request and the check.
|
||||
|
||||
[Check](https://docs.k6.io/docs/checks) are like asserts but differ in that they don't halt execution, instead they just store the result of the check, pass or fail, and let the script execution continue.
|
||||
|
||||
Each request is always followed by a 0.1 second [sleep](https://docs.k6.io/docs/sleep-t-1) to prevent the script execution from flooding the system with too many requests simultaneously.
|
||||
|
||||
Note that the default iteration count and VU count is 1. So each request in each group will be executed once. For more information, see the [k6 options](https://docs.k6.io/docs/options).
|
74
samples/client/others/k6/basicAuth/script.js
Normal file
74
samples/client/others/k6/basicAuth/script.js
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Sample API
|
||||
* Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
|
||||
*
|
||||
* OpenAPI spec version: 0.1.9
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
* https://github.com/OpenAPITools/openapi-generator
|
||||
*
|
||||
* Generator version: 7.9.0-SNAPSHOT
|
||||
*/
|
||||
|
||||
|
||||
import http from "k6/http";
|
||||
import { group, check, sleep } from "k6";
|
||||
|
||||
const BASE_URL = "http://api.example.com/v1";
|
||||
const TOKEN = "TOKEN_VALUE_HERE";
|
||||
// Sleep duration between successive requests.
|
||||
// You might want to edit the value of this variable or remove calls to the sleep function on the script.
|
||||
const SLEEP_DURATION = 0.1;
|
||||
// Global variables should be initialized.
|
||||
|
||||
export default function() {
|
||||
group("/users", () => {
|
||||
|
||||
// Request No. 1:
|
||||
{
|
||||
let url = BASE_URL + `/users`;
|
||||
let params = {
|
||||
headers: {
|
||||
"Authorization": `Basic ${TOKEN}`, "Accept": "application/json"
|
||||
}
|
||||
};
|
||||
let request = http.get(url, params);
|
||||
|
||||
check(request, {
|
||||
"A JSON array of user names": (r) => r.status === 200
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group("/public", () => {
|
||||
|
||||
// Request No. 1:
|
||||
{
|
||||
let url = BASE_URL + `/public`;
|
||||
let request = http.get(url);
|
||||
|
||||
check(request, {
|
||||
"A JSON object with public information": (r) => r.status === 200
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group("/private", () => {
|
||||
|
||||
// Request No. 1:
|
||||
{
|
||||
let url = BASE_URL + `/private`;
|
||||
let params = {
|
||||
headers: {
|
||||
"Authorization": `Basic ${TOKEN}`, "Accept": "application/json"
|
||||
}
|
||||
};
|
||||
let request = http.get(url, params);
|
||||
|
||||
check(request, {
|
||||
"A JSON object with private information": (r) => r.status === 200
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
@ -0,0 +1,2 @@
|
||||
README.md
|
||||
script.js
|
@ -0,0 +1 @@
|
||||
7.9.0-SNAPSHOT
|
15
samples/client/others/k6/bearerAuth/README.md
Normal file
15
samples/client/others/k6/bearerAuth/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Generated k6 script
|
||||
|
||||
The `script.js` file contains most of the Swagger/OpenAPI specification and you can customize it to your needs.
|
||||
|
||||
Global header variables are defined at the top of the file, like `api_key`. Each path in the specification is converted into a [group](https://docs.k6.io/docs/tags-and-groups) in k6 and each group contains all the request methods related to that path. Path and query parameters are extracted from the specification and put at the start of the group. The URL is constructed from the base URL plus path and query.
|
||||
|
||||
If the Swagger/OpenAPI specification used as the input spec contains examples at parameter level, those will be extracted and utilized as parameter values. The `handleParamValue` custom Mustache lambda registered for use in the K6 `script.mustache` template handles the conditional checks, formatting, and outputting of parameter values. If a given parameter has value specified – either in `example` or `examples` field, defined at the parameter level – that value will be used. For list (`examples`), entire list will be output in the generated script and the first element from that list will be assigned as parameter value. If a given parameter does not have an example defined, a placeholder value with `TODO_EDIT_THE_` prefix will be generated for that parameter, and you will have to assign a value before you can run the script. In other words, you can now generate K6 test scripts which are ready to run, provided the Swagger/OpenAPI specification used as the input spec contains examples for all of the path/query parameters; see `modules/openapi-generator/src/test/resources/3_0/examples.yaml` for an example of such specification, and https://swagger.io/docs/specification/adding-examples/ for more information about adding examples.
|
||||
|
||||
k6 specific parameters are in the [`params`](https://docs.k6.io/docs/params-k6http) object, and `body` contains the [request](https://docs.k6.io/docs/http-requests) body which is in the form of `identifier: type`, which the `type` should be substituted by a proper value. Then goes the request and the check.
|
||||
|
||||
[Check](https://docs.k6.io/docs/checks) are like asserts but differ in that they don't halt execution, instead they just store the result of the check, pass or fail, and let the script execution continue.
|
||||
|
||||
Each request is always followed by a 0.1 second [sleep](https://docs.k6.io/docs/sleep-t-1) to prevent the script execution from flooding the system with too many requests simultaneously.
|
||||
|
||||
Note that the default iteration count and VU count is 1. So each request in each group will be executed once. For more information, see the [k6 options](https://docs.k6.io/docs/options).
|
74
samples/client/others/k6/bearerAuth/script.js
Normal file
74
samples/client/others/k6/bearerAuth/script.js
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Sample API
|
||||
* Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
|
||||
*
|
||||
* OpenAPI spec version: 0.1.9
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
* https://github.com/OpenAPITools/openapi-generator
|
||||
*
|
||||
* Generator version: 7.9.0-SNAPSHOT
|
||||
*/
|
||||
|
||||
|
||||
import http from "k6/http";
|
||||
import { group, check, sleep } from "k6";
|
||||
|
||||
const BASE_URL = "http://api.example.com/v1";
|
||||
const TOKEN = "TOKEN_VALUE_HERE";
|
||||
// Sleep duration between successive requests.
|
||||
// You might want to edit the value of this variable or remove calls to the sleep function on the script.
|
||||
const SLEEP_DURATION = 0.1;
|
||||
// Global variables should be initialized.
|
||||
|
||||
export default function() {
|
||||
group("/users", () => {
|
||||
|
||||
// Request No. 1:
|
||||
{
|
||||
let url = BASE_URL + `/users`;
|
||||
let params = {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${TOKEN}`, "Accept": "application/json"
|
||||
}
|
||||
};
|
||||
let request = http.get(url, params);
|
||||
|
||||
check(request, {
|
||||
"A JSON array of user names": (r) => r.status === 200
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group("/public", () => {
|
||||
|
||||
// Request No. 1:
|
||||
{
|
||||
let url = BASE_URL + `/public`;
|
||||
let request = http.get(url);
|
||||
|
||||
check(request, {
|
||||
"A JSON object with public information": (r) => r.status === 200
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group("/private", () => {
|
||||
|
||||
// Request No. 1:
|
||||
{
|
||||
let url = BASE_URL + `/private`;
|
||||
let params = {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${TOKEN}`, "Accept": "application/json"
|
||||
}
|
||||
};
|
||||
let request = http.get(url, params);
|
||||
|
||||
check(request, {
|
||||
"A JSON object with private information": (r) => r.status === 200
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user