Skip to content

Commit

Permalink
[k6] Add authentication variables in headers and cookies (#19060)
Browse files Browse the repository at this point in the history
* Add global auth parsing including headers and cookies for k6.

* Add global auth statements.

* Generate samples.

* Revert "Generate samples."

This reverts commit b8cff86.

* Copy petstore-with-fake-endpoints-models-for-testing.yaml to a seperate k6 path as its example yaml file.

* Add global security statement in k6 example yaml instead of using the generic one.
  • Loading branch information
willie5588912 committed Jul 10, 2024
1 parent 5fdcd48 commit 42b0b20
Show file tree
Hide file tree
Showing 5 changed files with 2,449 additions and 51 deletions.
2 changes: 1 addition & 1 deletion bin/configs/k6.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
generatorName: k6
outputDir: samples/client/petstore/k6
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/k6/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/k6
additionalProperties:
appName: PetstoreClient
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;

public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
Expand Down Expand Up @@ -300,6 +302,7 @@ static class HTTPRequest {
@Nullable
HTTPBody body;
boolean hasBodyExample;
boolean hasCookie;
@Nullable
HTTPParameters params;
@Nullable
Expand All @@ -308,7 +311,7 @@ static class HTTPRequest {
DataExtractSubstituteParameter dataExtract;

public HTTPRequest(String operationId, String method, String path, @Nullable List<Parameter> query, @Nullable HTTPBody body,
boolean hasBodyExample, @Nullable HTTPParameters params, @Nullable List<k6Check> k6Checks,
boolean hasBodyExample, boolean hasCookie, @Nullable HTTPParameters params, @Nullable List<k6Check> k6Checks,
DataExtractSubstituteParameter dataExtract) {
// NOTE: https://k6.io/docs/javascript-api/k6-http/del-url-body-params
this.method = method.equals("delete") ? "del" : method;
Expand All @@ -318,6 +321,7 @@ public HTTPRequest(String operationId, String method, String path, @Nullable Lis
this.query = query;
this.body = body;
this.hasBodyExample = hasBodyExample;
this.hasCookie = hasCookie;
this.params = params;
this.k6Checks = k6Checks;
this.dataExtract = dataExtract;
Expand Down Expand Up @@ -494,6 +498,29 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
Set<Parameter> extraParameters = new HashSet<>();
Map<String, Set<Parameter>> pathVariables = new HashMap<>();

// get security schema from components
Map<String, SecurityScheme> securitySchemeMap = openAPI != null ?
(openAPI.getComponents() != null ? openAPI.getComponents().getSecuritySchemes() : null) : null;

// get global security requirements
List<SecurityRequirement> securityRequirements = openAPI.getSecurity();

// match global security requirements with security schemes and transform them to global auth methods
// global auth methods is a list of auth methods that are used in all requests
List<CodegenSecurity> globalAuthMethods = new ArrayList<>();
Map<String, SecurityScheme> globalSecurityMap = new HashMap<>();
if (securityRequirements != null) {
for (SecurityRequirement securityRequirement : securityRequirements) {
for (String securityRequirementKey : securityRequirement.keySet()) {
SecurityScheme securityScheme = securitySchemeMap.get(securityRequirementKey);
if (securityScheme != null) {
globalSecurityMap.put(securityRequirementKey, securityScheme);
}
}
}
globalAuthMethods = fromSecurity(globalSecurityMap);
}

for (String path : openAPI.getPaths().keySet()) {
Map<Integer, HTTPRequest> requests = new HashMap<>();
Set<Parameter> variables = new HashSet<>();
Expand All @@ -503,6 +530,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
for (Map.Entry<PathItem.HttpMethod, Operation> methodOperation : openAPI.getPaths().get(path).
readOperationsMap().entrySet()) {
List<Parameter> httpParams = new ArrayList<>();
List<Parameter> cookieParams = new ArrayList<>();
List<Parameter> queryParams = new ArrayList<>();
List<Parameter> bodyOrFormParams = new ArrayList<>();
List<k6Check> k6Checks = new ArrayList<>();
Expand Down Expand Up @@ -638,7 +666,19 @@ public void preprocessOpenAPI(OpenAPI openAPI) {

pathVariables.put(groupName, variables);

final HTTPParameters params = new HTTPParameters(null, null, httpParams, null, null, null, null, null,
// put auth medthods in header or cookie
for (CodegenSecurity globalAuthMethod : globalAuthMethods) {
if (globalAuthMethod.isKeyInHeader) {
httpParams.add(new Parameter(globalAuthMethod.keyParamName, getTemplateString(toVarName(globalAuthMethod.keyParamName))));
extraParameters.add(new Parameter(toVarName(globalAuthMethod.keyParamName), globalAuthMethod.keyParamName.toUpperCase(Locale.ROOT)));
}
if (globalAuthMethod.isKeyInCookie) {
cookieParams.add(new Parameter(globalAuthMethod.keyParamName, getTemplateString(toVarName(globalAuthMethod.keyParamName))));
extraParameters.add(new Parameter(toVarName(globalAuthMethod.keyParamName), globalAuthMethod.keyParamName.toUpperCase(Locale.ROOT)));
}
}

final HTTPParameters params = new HTTPParameters(null, cookieParams, httpParams, null, null, null, null, null,
responseType.length() > 0 ? responseType : null);

assert params.headers != null;
Expand All @@ -650,11 +690,18 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
// calculate order for this current request
Integer requestOrder = calculateRequestOrder(operationGroupingOrder, requests.size());

requests.put(requestOrder, new HTTPRequest(operationId, method.toString().toLowerCase(Locale.ROOT), path,
queryParams.size() > 0 ? queryParams : null,
bodyOrFormParams.size() > 0 ? new HTTPBody(bodyOrFormParams) : null, hasRequestBodyExample,
params.headers.size() > 0 ? params : null, k6Checks.size() > 0 ? k6Checks : null,
dataExtract.orElse(null)));
requests.put(requestOrder, new HTTPRequest(
operationId,
method.toString().toLowerCase(Locale.ROOT),
path,
queryParams.size() > 0 ? queryParams : null,
bodyOrFormParams.size() > 0 ? new HTTPBody(bodyOrFormParams) : null,
hasRequestBodyExample,
params.cookies.size() > 0 ? true : false,
params.headers.size() > 0 ? params : null,
k6Checks.size() > 0 ? k6Checks : null,
dataExtract.orElse(null))
);
}

addOrUpdateRequestGroup(requestGroups, groupName, pathVariables.get(groupName), requests);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ export default function() {
let body = {{#body}}{{=<% %>=}}{<%#parameters%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/parameters%>}<%={{ }}=%>{{/body}};
{{/body}}
{{#params}}
let params = {{#params}}{{=<% %>=}}{headers: {<%# headers%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/headers%><%#responseType%>, "Accept": <%& responseType%><%/responseType%>}<%# auth%>, auth: "<%& auth%>"<%/auth%>}<%={{ }}=%>{{/params}};
let params = {{#params}}{{=<% %>=}}{
headers: {
<%# headers%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/headers%><%#responseType%>, "Accept": <%& responseType%><%/responseType%>
}<%#hasCookie%>, cookies: {
<%# cookies%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/cookies%>
}<%/hasCookie%><%# auth%>, auth: "<%& auth%>"<%/auth%>
}<%={{ }}=%>{{/params}};
{{/params}}
{{#isDelete}}
{{#params}}
Expand Down
Loading

0 comments on commit 42b0b20

Please sign in to comment.