forked from loafle/openapi-generator-original
* [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.ArraySchema;
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
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.CodegenConfig;
|
||||||
import org.openapitools.codegen.CodegenConstants;
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
import org.openapitools.codegen.CodegenModel;
|
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;
|
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")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
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";
|
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
|
* 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.
|
* Collect the scopes to generate unique identifiers for each of them.
|
||||||
*/
|
*/
|
||||||
List<CodegenSecurity> authMethods = (List<CodegenSecurity>) objs.get("authMethods");
|
List<CodegenSecurity> authMethods = (List<CodegenSecurity>) objs.get("authMethods");
|
||||||
postProcessAuthMethod(authMethods);
|
postProcessAuthMethod(authMethods, null);
|
||||||
|
|
||||||
return super.postProcessSupportingFileData(objs);
|
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.
|
* Collect the scopes to generate a unique identifier for each of them.
|
||||||
*
|
*
|
||||||
* @param authMethods the auth methods with their scopes.
|
* @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) {
|
if (authMethods != null) {
|
||||||
for (CodegenSecurity authMethod : authMethods) {
|
for (CodegenSecurity authMethod : authMethods) {
|
||||||
if (authMethod.scopes != null) {
|
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);
|
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
|
package API_{{operationId}} is
|
||||||
new Swagger.Servers.Operation (Handler => {{operationId}},
|
new Swagger.Servers.Operation (Handler => {{operationId}},
|
||||||
Method => Swagger.Servers.{{httpMethod}},
|
Method => Swagger.Servers.{{httpMethod}},
|
||||||
URI => "{{path}}");
|
URI => URI_Prefix & "{{path}}");
|
||||||
|
|
||||||
-- {{summary}}
|
-- {{summary}}
|
||||||
procedure {{operationId}}
|
procedure {{operationId}}
|
||||||
@ -32,7 +32,7 @@ package body {{package}}.Skeletons is
|
|||||||
Result : {{returnType}};
|
Result : {{returnType}};
|
||||||
{{/returnType}}
|
{{/returnType}}
|
||||||
begin
|
begin
|
||||||
{{#authMethods}}
|
{{#vendorExtensions.x-auth-scopes}}
|
||||||
if not Context.Is_Authenticated then
|
if not Context.Is_Authenticated then
|
||||||
Context.Set_Error (401, "Not authenticated");
|
Context.Set_Error (401, "Not authenticated");
|
||||||
return;
|
return;
|
||||||
@ -43,7 +43,7 @@ package body {{package}}.Skeletons is
|
|||||||
return;
|
return;
|
||||||
end if;
|
end if;
|
||||||
{{/scopes}}
|
{{/scopes}}
|
||||||
{{/authMethods}}
|
{{/vendorExtensions.x-auth-scopes}}
|
||||||
{{#queryParams}}
|
{{#queryParams}}
|
||||||
Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}});
|
Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}});
|
||||||
{{/queryParams}}
|
{{/queryParams}}
|
||||||
@ -128,7 +128,7 @@ package body {{package}}.Skeletons is
|
|||||||
Result : {{returnType}};
|
Result : {{returnType}};
|
||||||
{{/returnType}}
|
{{/returnType}}
|
||||||
begin
|
begin
|
||||||
{{#authMethods}}
|
{{#vendorExtensions.x-auth-scopes}}
|
||||||
if not Context.Is_Authenticated then
|
if not Context.Is_Authenticated then
|
||||||
Context.Set_Error (401, "Not authenticated");
|
Context.Set_Error (401, "Not authenticated");
|
||||||
return;
|
return;
|
||||||
@ -139,7 +139,7 @@ package body {{package}}.Skeletons is
|
|||||||
return;
|
return;
|
||||||
end if;
|
end if;
|
||||||
{{/scopes}}
|
{{/scopes}}
|
||||||
{{/authMethods}}
|
{{/vendorExtensions.x-auth-scopes}}
|
||||||
{{#queryParams}}
|
{{#queryParams}}
|
||||||
Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}});
|
Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}});
|
||||||
{{/queryParams}}
|
{{/queryParams}}
|
||||||
@ -185,7 +185,7 @@ package body {{package}}.Skeletons is
|
|||||||
package API_{{operationId}} is
|
package API_{{operationId}} is
|
||||||
new Swagger.Servers.Operation (Handler => {{operationId}},
|
new Swagger.Servers.Operation (Handler => {{operationId}},
|
||||||
Method => Swagger.Servers.{{httpMethod}},
|
Method => Swagger.Servers.{{httpMethod}},
|
||||||
URI => "{{path}}");
|
URI => URI_Prefix & "{{path}}");
|
||||||
{{/operation}}
|
{{/operation}}
|
||||||
{{/operations}}
|
{{/operations}}
|
||||||
{{/apis}}
|
{{/apis}}
|
||||||
|
@ -32,6 +32,7 @@ package {{package}}.Skeletons is
|
|||||||
|
|
||||||
generic
|
generic
|
||||||
type Implementation_Type is limited new Server_Type with private;
|
type Implementation_Type is limited new Server_Type with private;
|
||||||
|
URI_Prefix : String := "";
|
||||||
package Skeleton is
|
package Skeleton is
|
||||||
|
|
||||||
procedure Register (Server : in out Swagger.Servers.Application_Type'Class);
|
procedure Register (Server : in out Swagger.Servers.Application_Type'Class);
|
||||||
@ -56,6 +57,7 @@ package {{package}}.Skeletons is
|
|||||||
|
|
||||||
generic
|
generic
|
||||||
type Implementation_Type is limited new Server_Type with private;
|
type Implementation_Type is limited new Server_Type with private;
|
||||||
|
URI_Prefix : String := "";
|
||||||
package Shared_Instance is
|
package Shared_Instance is
|
||||||
|
|
||||||
procedure Register (Server : in out Swagger.Servers.Application_Type'Class);
|
procedure Register (Server : in out Swagger.Servers.Application_Type'Class);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user