mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-07 02:55:19 +00:00
* [Ada] Operation security scopes are ignored when generating the server (#1043) - Update fromOperation() to keep the operation required scopes for each auth method and store that information in the x-scopes vendor extensions attribute - Update postProcessOperationsWithModels() to process the operation required scopes and build a list of authMethods which only contain the required scopes for the operation and store these authMethods in the x-auth-scopes attribute. - Update postProcessAuthMethod() to handle the logic of filtering and building the operation authMethod (new instances are created because we must not modify the global authMethod definitions) - Update the Ada server templates to use the x-auth-scopes instead of authMethods Add a URL prefix parameter for the Ada server instantiation * Fix the Ada server template to use the x-auth-scopes for operation scopes
This commit is contained in:
parent
0e045bee1b
commit
3cacbcb965
@ -24,6 +24,8 @@ import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
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 org.openapitools.codegen.CodegenConfig;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenModel;
|
||||
@ -414,9 +416,38 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a vendor extension attribute that provides a map of auth methods and the scopes
|
||||
// which are expected by the operation. This map is then used by postProcessOperationsWithModels
|
||||
// to build another vendor extension that provides a subset of the auth methods with only
|
||||
// the scopes required by the operation.
|
||||
final List<SecurityRequirement> securities = operation.getSecurity();
|
||||
if (securities != null && securities.size() > 0) {
|
||||
final Map<String, SecurityScheme> securitySchemes = openAPI.getComponents() != null ? openAPI.getComponents().getSecuritySchemes() : null;
|
||||
final List<SecurityRequirement> globalSecurities = openAPI.getSecurity();
|
||||
|
||||
Map<String, List<String>> scopes = getAuthScopes(securities, securitySchemes);
|
||||
if (scopes.isEmpty() && globalSecurities != null) {
|
||||
scopes = getAuthScopes(globalSecurities, securitySchemes);
|
||||
}
|
||||
op.vendorExtensions.put("x-scopes", scopes);
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getAuthScopes(List<SecurityRequirement> securities, Map<String, SecurityScheme> securitySchemes) {
|
||||
final Map<String, List<String>> scopes = new HashMap<>();
|
||||
for (SecurityRequirement requirement : securities) {
|
||||
for (String key : requirement.keySet()) {
|
||||
SecurityScheme securityScheme = securitySchemes.get(key);
|
||||
if (securityScheme != null) {
|
||||
scopes.put(key, requirement.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
return scopes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
||||
@ -449,7 +480,14 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
|
||||
p.dataType = "Swagger.File_Part_Type";
|
||||
}
|
||||
}
|
||||
postProcessAuthMethod(op1.authMethods);
|
||||
|
||||
// Given the operation scopes and the auth methods, build a list of auth methods that only
|
||||
// describe the auth methods and scopes required by the operation.
|
||||
final Map<String, List<String>> scopes = (Map<String, List<String>>) op1.vendorExtensions.get("x-scopes");
|
||||
List<CodegenSecurity> opScopes = postProcessAuthMethod(op1.authMethods, scopes);
|
||||
if (opScopes != null) {
|
||||
op1.vendorExtensions.put("x-auth-scopes", opScopes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the path parameter to construct a x-path-index that tells the index of
|
||||
@ -584,7 +622,7 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
|
||||
* Collect the scopes to generate unique identifiers for each of them.
|
||||
*/
|
||||
List<CodegenSecurity> authMethods = (List<CodegenSecurity>) objs.get("authMethods");
|
||||
postProcessAuthMethod(authMethods);
|
||||
postProcessAuthMethod(authMethods, null);
|
||||
|
||||
return super.postProcessSupportingFileData(objs);
|
||||
}
|
||||
@ -593,8 +631,11 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
|
||||
* Collect the scopes to generate a unique identifier for each of them.
|
||||
*
|
||||
* @param authMethods the auth methods with their scopes.
|
||||
* @param scopes the optional auth methods and scopes required by an operation
|
||||
* @return the authMethods to be used by the operation with its required scopes.
|
||||
*/
|
||||
private void postProcessAuthMethod(List<CodegenSecurity> authMethods) {
|
||||
private List<CodegenSecurity> postProcessAuthMethod(List<CodegenSecurity> authMethods, Map<String, List<String>> scopes) {
|
||||
List<CodegenSecurity> result = (scopes == null) ? null : new ArrayList<CodegenSecurity>();
|
||||
if (authMethods != null) {
|
||||
for (CodegenSecurity authMethod : authMethods) {
|
||||
if (authMethod.scopes != null) {
|
||||
@ -620,8 +661,39 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have operation scopes, filter the auth method to describe the operation auth
|
||||
// method with only the scope that it requires. We have to create a new auth method
|
||||
// instance because the original object must not be modified.
|
||||
List<String> opScopes = (scopes == null) ? null : scopes.get(authMethod.name);
|
||||
authMethod.name = org.openapitools.codegen.utils.StringUtils.camelize(sanitizeName(authMethod.name), true);
|
||||
if (opScopes != null) {
|
||||
CodegenSecurity opSecurity = new CodegenSecurity();
|
||||
opSecurity.name = authMethod.name;
|
||||
opSecurity.type = authMethod.type;
|
||||
opSecurity.hasMore = false;
|
||||
opSecurity.isBasic = authMethod.isBasic;
|
||||
opSecurity.isApiKey = authMethod.isApiKey;
|
||||
opSecurity.isKeyInCookie = authMethod.isKeyInCookie;
|
||||
opSecurity.isKeyInHeader = authMethod.isKeyInHeader;
|
||||
opSecurity.isKeyInQuery = authMethod.isKeyInQuery;
|
||||
opSecurity.flow = authMethod.flow;
|
||||
opSecurity.tokenUrl = authMethod.tokenUrl;
|
||||
List<Map<String, Object>> opAuthScopes = new ArrayList<Map<String, Object>>();
|
||||
for (String opScopeName : opScopes) {
|
||||
for (Map<String, Object> scope : authMethod.scopes) {
|
||||
String name = (String) scope.get("scope");
|
||||
if (opScopeName.equals(name)) {
|
||||
opAuthScopes.add(scope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
opSecurity.scopes = opAuthScopes;
|
||||
result.add(opSecurity);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ package body {{package}}.Skeletons is
|
||||
package API_{{operationId}} is
|
||||
new Swagger.Servers.Operation (Handler => {{operationId}},
|
||||
Method => Swagger.Servers.{{httpMethod}},
|
||||
URI => "{{path}}");
|
||||
URI => URI_Prefix & "{{path}}");
|
||||
|
||||
-- {{summary}}
|
||||
procedure {{operationId}}
|
||||
@ -32,7 +32,7 @@ package body {{package}}.Skeletons is
|
||||
Result : {{returnType}};
|
||||
{{/returnType}}
|
||||
begin
|
||||
{{#authMethods}}
|
||||
{{#vendorExtensions.x-auth-scopes}}
|
||||
if not Context.Is_Authenticated then
|
||||
Context.Set_Error (401, "Not authenticated");
|
||||
return;
|
||||
@ -43,7 +43,7 @@ package body {{package}}.Skeletons is
|
||||
return;
|
||||
end if;
|
||||
{{/scopes}}
|
||||
{{/authMethods}}
|
||||
{{/vendorExtensions.x-auth-scopes}}
|
||||
{{#queryParams}}
|
||||
Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}});
|
||||
{{/queryParams}}
|
||||
@ -128,7 +128,7 @@ package body {{package}}.Skeletons is
|
||||
Result : {{returnType}};
|
||||
{{/returnType}}
|
||||
begin
|
||||
{{#authMethods}}
|
||||
{{#vendorExtensions.x-auth-scopes}}
|
||||
if not Context.Is_Authenticated then
|
||||
Context.Set_Error (401, "Not authenticated");
|
||||
return;
|
||||
@ -139,7 +139,7 @@ package body {{package}}.Skeletons is
|
||||
return;
|
||||
end if;
|
||||
{{/scopes}}
|
||||
{{/authMethods}}
|
||||
{{/vendorExtensions.x-auth-scopes}}
|
||||
{{#queryParams}}
|
||||
Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}});
|
||||
{{/queryParams}}
|
||||
@ -185,7 +185,7 @@ package body {{package}}.Skeletons is
|
||||
package API_{{operationId}} is
|
||||
new Swagger.Servers.Operation (Handler => {{operationId}},
|
||||
Method => Swagger.Servers.{{httpMethod}},
|
||||
URI => "{{path}}");
|
||||
URI => URI_Prefix & "{{path}}");
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
|
@ -32,6 +32,7 @@ package {{package}}.Skeletons is
|
||||
|
||||
generic
|
||||
type Implementation_Type is limited new Server_Type with private;
|
||||
URI_Prefix : String := "";
|
||||
package Skeleton is
|
||||
|
||||
procedure Register (Server : in out Swagger.Servers.Application_Type'Class);
|
||||
@ -56,6 +57,7 @@ package {{package}}.Skeletons is
|
||||
|
||||
generic
|
||||
type Implementation_Type is limited new Server_Type with private;
|
||||
URI_Prefix : String := "";
|
||||
package Shared_Instance is
|
||||
|
||||
procedure Register (Server : in out Swagger.Servers.Application_Type'Class);
|
||||
|
Loading…
Reference in New Issue
Block a user