From 980d75ba7a25820a7746ef386e21c554e65b2860 Mon Sep 17 00:00:00 2001 From: altro3 Date: Tue, 27 Aug 2024 13:48:21 +0700 Subject: [PATCH] Add genarate security roles by security scopes --- .../generator/JavaMicronautServerCodegen.java | 24 ++++++++++-- .../KotlinMicronautServerCodegen.java | 24 ++++++++++-- .../JavaMicronautServerCodegenTest.java | 18 +++++++++ .../KotlinMicronautServerCodegenTest.java | 18 +++++++++ .../src/test/resources/3_0/security.yml | 38 +++++++++++++++++++ 5 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 openapi-generator/src/test/resources/3_0/security.yml diff --git a/openapi-generator/src/main/java/io/micronaut/openapi/generator/JavaMicronautServerCodegen.java b/openapi-generator/src/main/java/io/micronaut/openapi/generator/JavaMicronautServerCodegen.java index b7fb2ac334..118adc3e0e 100644 --- a/openapi-generator/src/main/java/io/micronaut/openapi/generator/JavaMicronautServerCodegen.java +++ b/openapi-generator/src/main/java/io/micronaut/openapi/generator/JavaMicronautServerCodegen.java @@ -28,6 +28,7 @@ import org.openapitools.codegen.utils.StringUtils; import java.io.File; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -281,14 +282,29 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allOperations = (List) operations.get("operation"); + var allOperations = (List) operations.get("operation"); if (useAuth) { for (CodegenOperation operation : allOperations) { if (!operation.vendorExtensions.containsKey(EXTENSION_ROLES)) { - String role = operation.hasAuthMethods ? AUTHORIZED_ROLE : ANONYMOUS_ROLE; - operation.vendorExtensions.put(EXTENSION_ROLES, Collections.singletonList(role)); + + var roles = new ArrayList(); + var authMethods = operation.authMethods; + if (authMethods != null && !authMethods.isEmpty()) { + var scopes = authMethods.get(0).scopes; + if (scopes != null && !scopes.isEmpty()) { + for (var scope : scopes) { + roles.add("\"" + escapeText(scope.get("scope").toString()) + "\""); + } + } else { + roles.add(AUTHORIZED_ROLE); + } + } else { + roles.add(ANONYMOUS_ROLE); + } + + operation.vendorExtensions.put(EXTENSION_ROLES, roles); } else { - List roles = (List) operation.vendorExtensions.get(EXTENSION_ROLES); + var roles = (List) operation.vendorExtensions.get(EXTENSION_ROLES); roles = roles.stream().map(role -> switch (role) { case ANONYMOUS_ROLE_KEY -> ANONYMOUS_ROLE; case AUTHORIZED_ROLE_KEY -> AUTHORIZED_ROLE; diff --git a/openapi-generator/src/main/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegen.java b/openapi-generator/src/main/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegen.java index dbf5f27ef8..302e945645 100644 --- a/openapi-generator/src/main/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegen.java +++ b/openapi-generator/src/main/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegen.java @@ -28,6 +28,7 @@ import org.openapitools.codegen.utils.StringUtils; import java.io.File; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -266,14 +267,29 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allOperations = (List) operations.get("operation"); + var allOperations = (List) operations.get("operation"); if (useAuth) { for (CodegenOperation operation : allOperations) { if (!operation.vendorExtensions.containsKey(EXTENSION_ROLES)) { - String role = operation.hasAuthMethods ? AUTHORIZED_ROLE : ANONYMOUS_ROLE; - operation.vendorExtensions.put(EXTENSION_ROLES, Collections.singletonList(role)); + + var roles = new ArrayList(); + var authMethods = operation.authMethods; + if (authMethods != null && !authMethods.isEmpty()) { + var scopes = authMethods.get(0).scopes; + if (scopes != null && !scopes.isEmpty()) { + for (var scope : scopes) { + roles.add("\"" + escapeText(scope.get("scope").toString()) + "\""); + } + } else { + roles.add(AUTHORIZED_ROLE); + } + } else { + roles.add(ANONYMOUS_ROLE); + } + + operation.vendorExtensions.put(EXTENSION_ROLES, roles); } else { - List roles = (List) operation.vendorExtensions.get(EXTENSION_ROLES); + var roles = (List) operation.vendorExtensions.get(EXTENSION_ROLES); roles = roles.stream().map(role -> switch (role) { case ANONYMOUS_ROLE_KEY -> ANONYMOUS_ROLE; case AUTHORIZED_ROLE_KEY -> AUTHORIZED_ROLE; diff --git a/openapi-generator/src/test/java/io/micronaut/openapi/generator/JavaMicronautServerCodegenTest.java b/openapi-generator/src/test/java/io/micronaut/openapi/generator/JavaMicronautServerCodegenTest.java index e2031ab03e..d6617f2cd6 100644 --- a/openapi-generator/src/test/java/io/micronaut/openapi/generator/JavaMicronautServerCodegenTest.java +++ b/openapi-generator/src/test/java/io/micronaut/openapi/generator/JavaMicronautServerCodegenTest.java @@ -491,4 +491,22 @@ void testOperationDescription() { assertFileContains(path + "api/DatasetsApi.java", "description = \"Creates a brand new dataset.\""); } + + @Test + void testSecurity() { + + var codegen = new JavaMicronautServerCodegen(); + String outputPath = generateFiles(codegen, "src/test/resources/3_0/security.yml", CodegenConstants.APIS, CodegenConstants.MODELS); + String path = outputPath + "src/main/java/org/openapitools/"; + + assertFileContains(path + "api/DefaultApi.java", + """ + @Secured({"read", "admin"}) + Mono get(); + """, + """ + @Secured({"write", "admin"}) + Mono save(); + """); + } } diff --git a/openapi-generator/src/test/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegenTest.java b/openapi-generator/src/test/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegenTest.java index 7d951a5274..4266773d64 100644 --- a/openapi-generator/src/test/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegenTest.java +++ b/openapi-generator/src/test/java/io/micronaut/openapi/generator/KotlinMicronautServerCodegenTest.java @@ -576,4 +576,22 @@ void testOperationDescription() { assertFileContains(path + "api/DatasetsApi.kt", "description = \"Creates a brand new dataset.\""); } + + @Test + void testSecurity() { + + var codegen = new KotlinMicronautServerCodegen(); + String outputPath = generateFiles(codegen, "src/test/resources/3_0/security.yml", CodegenConstants.APIS, CodegenConstants.MODELS); + String path = outputPath + "src/main/kotlin/org/openapitools/"; + + assertFileContains(path + "api/DefaultApi.kt", + """ + @Secured("read", "admin") + fun get(): Mono + """, + """ + @Secured("write", "admin") + fun save(): Mono + """); + } } diff --git a/openapi-generator/src/test/resources/3_0/security.yml b/openapi-generator/src/test/resources/3_0/security.yml new file mode 100644 index 0000000000..0162d6a13e --- /dev/null +++ b/openapi-generator/src/test/resources/3_0/security.yml @@ -0,0 +1,38 @@ +openapi: 3.0.3 +info: + description: This is an example of the openapi documentation + title: OpenAPI + version: 0.0.0 +paths: + /pet: + post: + operationId: save + security: + - OAuth2: [ write, admin ] + responses: + 200: + description: Successfully saved + get: + operationId: get + security: + - OAuth2: [ read, admin ] + responses: + 200: + description: Successfully retrieved information +components: + securitySchemes: + OAuth2: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: https://example.com/oauth/authorize + tokenUrl: https://example.com/oauth/token + scopes: + read: Grants read access + write: Grants write access + admin: Grants access to admin operations +security: + - OAuth2: + - read + - write + - admin