From 92d57e032c6803172defe9dd2b0950c86a9d95f6 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 30 Nov 2023 10:08:33 -0700 Subject: [PATCH] Adding support for multiple auth clients in OpenAPI Spec --- .../vertx/openapi/BaseGeneratorGen.java | 1 + .../vertx/openapi/Swagger2GeneratorGen.java | 1 + .../computate/vertx/writer/ApiWriterGen.java | 111 +++++++++++++++--- .../vertx/config/ComputateConfigKeys.java | 20 ++++ .../vertx/openapi/BaseGenerator.java | 2 + .../vertx/openapi/Swagger2Generator.java | 78 +++++++----- .../org/computate/vertx/writer/ApiWriter.java | 9 +- 7 files changed, 171 insertions(+), 51 deletions(-) diff --git a/src/gen/java/org/computate/vertx/openapi/BaseGeneratorGen.java b/src/gen/java/org/computate/vertx/openapi/BaseGeneratorGen.java index b1acd3f..27c91ff 100644 --- a/src/gen/java/org/computate/vertx/openapi/BaseGeneratorGen.java +++ b/src/gen/java/org/computate/vertx/openapi/BaseGeneratorGen.java @@ -1750,6 +1750,7 @@ public static String staticSearchFqBaseGenerator(String entityVar, ComputateSite public static final String[] BaseGeneratorVals = new String[] { configureConfigComplete1, configureConfigFail1 }; public static final String CLASS_SIMPLE_NAME = "BaseGenerator"; + public static final String CLASS_API_ADDRESS = "computate-vertx-enUS-BaseGenerator"; public static final String VAR_vertx_ = "vertx_"; public static final String VAR_webClient = "webClient"; public static final String VAR_siteRequest_ = "siteRequest_"; diff --git a/src/gen/java/org/computate/vertx/openapi/Swagger2GeneratorGen.java b/src/gen/java/org/computate/vertx/openapi/Swagger2GeneratorGen.java index 0b5eef6..1723721 100644 --- a/src/gen/java/org/computate/vertx/openapi/Swagger2GeneratorGen.java +++ b/src/gen/java/org/computate/vertx/openapi/Swagger2GeneratorGen.java @@ -259,6 +259,7 @@ public static String staticSearchFqSwagger2Generator(String entityVar, Computate public static final String[] Swagger2GeneratorVals = new String[] { writeApiError1, writeApiError21 }; public static final String CLASS_SIMPLE_NAME = "Swagger2Generator"; + public static final String CLASS_API_ADDRESS = "computate-vertx-enUS-Swagger2Generator"; public static String displayNameForClass(String var) { diff --git a/src/gen/java/org/computate/vertx/writer/ApiWriterGen.java b/src/gen/java/org/computate/vertx/writer/ApiWriterGen.java index dd467c8..a7149ef 100644 --- a/src/gen/java/org/computate/vertx/writer/ApiWriterGen.java +++ b/src/gen/java/org/computate/vertx/writer/ApiWriterGen.java @@ -58,9 +58,9 @@ import io.vertx.core.Promise; import io.vertx.core.Future; -/** -
    -0

    Suggestions that can generate more code for you:

+/** + *
    +

    Suggestions that can generate more code for you:

    *
*
  • You can add a class comment "Api: true" if you wish to GET, POST, PATCH or PUT these ApiWriter objects in a RESTful API. *
  • *

    About the ApiWriter class and it's generated class ApiWriterGen<Object>:

    extends ApiWriterGen @@ -79,22 +79,22 @@ * The generated class ApiWriterGen extends Object which means that ApiWriter extends ApiWriterGen which extends Object. * This generated inheritance is a powerful feature that allows a lot of boiler plate code to be created for you automatically while still preserving inheritance through the power of Java Generic classes. *

    - * Api: true - * ApiTag.enUS: true - * ApiUri.enUS: null - * Color: null - * IconGroup: null - * IconName: null - * Indexed: true - * {@inheritDoc} + *

    Api: true

    + *

    ApiTag.enUS: true

    + *

    ApiUri.enUS: null

    + *

    Color: null

    + *

    IconGroup: null

    + *

    IconName: null

    + *

    Indexed: true

    + *

    {@inheritDoc}

    *

    By adding a class comment "{@inheritDoc}", the ApiWriter class will inherit the helpful inherited class comments from the super class ApiWriterGen. *

    - * Rows: null - * Model: true - * Page: true - * SuperPage.enUS: null - * Promise: true - * AName.enUS: null + *

    Rows: null

    + *

    Model: true

    + *

    Page: true

    + *

    SuperPage.enUS: null

    + *

    Promise: true

    + *

    AName.enUS: null

    *

    * Delete the class ApiWriter in Solr: * curl -k 'https://solr-solr.apps-crc.testing/solr/computate/update?commitWithin=1000&overwrite=true&wt=json' -X POST -H 'Content-type: text/xml' --data-raw '<add><delete><query>classeNomCanonique_enUS_indexed_string:org.computate.vertx.writer.ApiWriter</query></delete></add>' @@ -107,6 +107,7 @@ * Delete the project computate-vertx in Solr: * curl -k 'https://solr-solr.apps-crc.testing/solr/computate/update?commitWithin=1000&overwrite=true&wt=json' -X POST -H 'Content-type: text/xml' --data-raw '<add><delete><query>siteNom_indexed_string:computate\-vertx</query></delete></add>' *

    + * Generated: true **/ public abstract class ApiWriterGen extends Object { protected static final Logger LOG = LoggerFactory.getLogger(ApiWriter.class); @@ -847,6 +848,66 @@ public static String staticSearchFqConfig(ComputateSiteRequest siteRequest_, Str return ApiWriter.staticSearchStrConfig(siteRequest_, ApiWriter.staticSearchConfig(siteRequest_, ApiWriter.staticSetConfig(siteRequest_, o))); } + ///////////////// + // authClients // + ///////////////// + + + /** The entity authClients + * is defined as null before being initialized. + */ + @JsonProperty + @JsonInclude(Include.NON_NULL) + protected JsonObject authClients; + + /**
    The entity authClients + * is defined as null before being initialized. + *
    Find the entity authClients in Solr + *
    + * @param c is for wrapping a value to assign to this entity during initialization. + **/ + protected abstract void _authClients(Wrap c); + + public JsonObject getAuthClients() { + return authClients; + } + + public void setAuthClients(JsonObject authClients) { + this.authClients = authClients; + } + @JsonIgnore + public void setAuthClients(String o) { + this.authClients = ApiWriter.staticSetAuthClients(siteRequest_, o); + } + public static JsonObject staticSetAuthClients(ComputateSiteRequest siteRequest_, String o) { + if(o != null) { + return new JsonObject(o); + } + return null; + } + protected ApiWriter authClientsInit() { + Wrap authClientsWrap = new Wrap().var("authClients"); + if(authClients == null) { + _authClients(authClientsWrap); + Optional.ofNullable(authClientsWrap.getO()).ifPresent(o -> { + setAuthClients(o); + }); + } + return (ApiWriter)this; + } + + public static String staticSearchAuthClients(ComputateSiteRequest siteRequest_, JsonObject o) { + return o.toString(); + } + + public static String staticSearchStrAuthClients(ComputateSiteRequest siteRequest_, String o) { + return o == null ? null : o.toString(); + } + + public static String staticSearchFqAuthClients(ComputateSiteRequest siteRequest_, String o) { + return ApiWriter.staticSearchStrAuthClients(siteRequest_, ApiWriter.staticSearchAuthClients(siteRequest_, ApiWriter.staticSetAuthClients(siteRequest_, o))); + } + ///////////////////// // wRequestHeaders // ///////////////////// @@ -2794,6 +2855,7 @@ public void initApiWriter() { wRequestBodiesInit(); wSchemasInit(); configInit(); + authClientsInit(); wRequestHeadersInit(); wRequestDescriptionInit(); wResponseDescriptionInit(); @@ -2917,6 +2979,8 @@ public Object obtainApiWriter(String var) { return oApiWriter.wSchemas; case "config": return oApiWriter.config; + case "authClients": + return oApiWriter.authClients; case "wRequestHeaders": return oApiWriter.wRequestHeaders; case "wRequestDescription": @@ -3040,6 +3104,8 @@ public static Object staticSetApiWriter(String entityVar, ComputateSiteRequest s return ApiWriter.staticSetTabsResponses(siteRequest_, o); case "config": return ApiWriter.staticSetConfig(siteRequest_, o); + case "authClients": + return ApiWriter.staticSetAuthClients(siteRequest_, o); case "classApiTag": return ApiWriter.staticSetClassApiTag(siteRequest_, o); case "classExtendsBase": @@ -3124,6 +3190,8 @@ public static Object staticSearchApiWriter(String entityVar, ComputateSiteReques return ApiWriter.staticSearchTabsResponses(siteRequest_, (Integer)o); case "config": return ApiWriter.staticSearchConfig(siteRequest_, (JsonObject)o); + case "authClients": + return ApiWriter.staticSearchAuthClients(siteRequest_, (JsonObject)o); case "classApiTag": return ApiWriter.staticSearchClassApiTag(siteRequest_, (String)o); case "classExtendsBase": @@ -3208,6 +3276,8 @@ public static String staticSearchStrApiWriter(String entityVar, ComputateSiteReq return ApiWriter.staticSearchStrTabsResponses(siteRequest_, (Integer)o); case "config": return ApiWriter.staticSearchStrConfig(siteRequest_, (String)o); + case "authClients": + return ApiWriter.staticSearchStrAuthClients(siteRequest_, (String)o); case "classApiTag": return ApiWriter.staticSearchStrClassApiTag(siteRequest_, (String)o); case "classExtendsBase": @@ -3292,6 +3362,8 @@ public static String staticSearchFqApiWriter(String entityVar, ComputateSiteRequ return ApiWriter.staticSearchFqTabsResponses(siteRequest_, o); case "config": return ApiWriter.staticSearchFqConfig(siteRequest_, o); + case "authClients": + return ApiWriter.staticSearchFqAuthClients(siteRequest_, o); case "classApiTag": return ApiWriter.staticSearchFqClassApiTag(siteRequest_, o); case "classExtendsBase": @@ -3361,6 +3433,7 @@ public static String staticSearchFqApiWriter(String entityVar, ComputateSiteRequ } public static final String CLASS_SIMPLE_NAME = "ApiWriter"; + public static final String CLASS_API_ADDRESS = "computate-vertx-enUS-ApiWriter"; public static final String VAR_siteRequest_ = "siteRequest_"; public static final String VAR_classDoc = "classDoc"; public static final String VAR_classSolrDocument = "classSolrDocument"; @@ -3375,6 +3448,7 @@ public static String staticSearchFqApiWriter(String entityVar, ComputateSiteRequ public static final String VAR_wRequestBodies = "wRequestBodies"; public static final String VAR_wSchemas = "wSchemas"; public static final String VAR_config = "config"; + public static final String VAR_authClients = "authClients"; public static final String VAR_wRequestHeaders = "wRequestHeaders"; public static final String VAR_wRequestDescription = "wRequestDescription"; public static final String VAR_wResponseDescription = "wResponseDescription"; @@ -3426,6 +3500,7 @@ public static String staticSearchFqApiWriter(String entityVar, ComputateSiteRequ public static final String DISPLAY_NAME_wRequestBodies = ""; public static final String DISPLAY_NAME_wSchemas = ""; public static final String DISPLAY_NAME_config = ""; + public static final String DISPLAY_NAME_authClients = ""; public static final String DISPLAY_NAME_wRequestHeaders = ""; public static final String DISPLAY_NAME_wRequestDescription = ""; public static final String DISPLAY_NAME_wResponseDescription = ""; @@ -3496,6 +3571,8 @@ public static String displayNameApiWriter(String var) { return DISPLAY_NAME_wSchemas; case VAR_config: return DISPLAY_NAME_config; + case VAR_authClients: + return DISPLAY_NAME_authClients; case VAR_wRequestHeaders: return DISPLAY_NAME_wRequestHeaders; case VAR_wRequestDescription: diff --git a/src/main/java/org/computate/vertx/config/ComputateConfigKeys.java b/src/main/java/org/computate/vertx/config/ComputateConfigKeys.java index 4d2f9f4..24b0588 100644 --- a/src/main/java/org/computate/vertx/config/ComputateConfigKeys.java +++ b/src/main/java/org/computate/vertx/config/ComputateConfigKeys.java @@ -159,6 +159,11 @@ public class ComputateConfigKeys { **/ public static final String AUTH_REALM = "AUTH_REALM"; + /** + * The Auth clients of the site. + **/ + public static final String AUTH_CLIENTS = "AUTH_CLIENTS"; + /** * The Auth client ID of the site. **/ @@ -169,6 +174,21 @@ public class ComputateConfigKeys { **/ public static final String AUTH_SECRET = "AUTH_SECRET"; + /** + * The Auth Client callback URI + **/ + public static final String AUTH_CALLBACK_URI = "AUTH_CALLBACK_URI"; + + /** + * The Auth Client logout URI + **/ + public static final String AUTH_LOGOUT_URI = "AUTH_LOGOUT_URI"; + + /** + * The Auth Client OpenAPI ID + **/ + public static final String AUTH_OPEN_API_ID = "AUTH_OPEN_API_ID"; + /** * The Auth client secret of the site. **/ diff --git a/src/main/java/org/computate/vertx/openapi/BaseGenerator.java b/src/main/java/org/computate/vertx/openapi/BaseGenerator.java index da5df1f..15276bd 100644 --- a/src/main/java/org/computate/vertx/openapi/BaseGenerator.java +++ b/src/main/java/org/computate/vertx/openapi/BaseGenerator.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -269,6 +270,7 @@ public Future loadClass(List docs, Integer i) { apiWriter.setWSchemas(wSchemas); apiWriter.setOpenApiVersion(openApiVersion); apiWriter.setClassUris(classUris); + apiWriter.setAuthClients(Optional.ofNullable(config.getValue(ComputateConfigKeys.AUTH_CLIENTS)).map(v -> v instanceof JsonObject ? (JsonObject)v : new JsonObject(v.toString())).orElse(new JsonObject())); apiWriter.initDeepApiWriter(siteRequest_); apiWriters.add(apiWriter); } diff --git a/src/main/java/org/computate/vertx/openapi/Swagger2Generator.java b/src/main/java/org/computate/vertx/openapi/Swagger2Generator.java index d02a88c..7baffbe 100644 --- a/src/main/java/org/computate/vertx/openapi/Swagger2Generator.java +++ b/src/main/java/org/computate/vertx/openapi/Swagger2Generator.java @@ -13,10 +13,13 @@ */ package org.computate.vertx.openapi; +import java.util.Optional; + import org.computate.vertx.config.ComputateConfigKeys; import io.vertx.core.Future; import io.vertx.core.Promise; +import io.vertx.core.json.JsonObject; /** * InitDeepBefore: true @@ -69,45 +72,56 @@ public Future writeApi() { Promise promise = Promise.promise(); try { + JsonObject authClients = Optional.ofNullable(config.getValue(ComputateConfigKeys.AUTH_CLIENTS)).map(v -> v instanceof JsonObject ? (JsonObject)v : new JsonObject(v.toString())).orElse(new JsonObject()); + wPaths.tl(0, "paths:"); - wPaths.l(); - wPaths.tl(1, "/callback:"); - wPaths.tl(2, "get:"); - wPaths.tl(3, "operationId: callback"); - wPaths.tl(3, "x-vertx-event-bus: ", appName, "-", languageName, "-callback"); - wPaths.tl(3, "description: >+"); - wPaths.tl(3, "responses:"); - wPaths.tl(4, "'200':"); - wPaths.tl(5, "description: >+"); - wPaths.tl(5, "content:"); - wPaths.tl(6, "application/json; charset=utf-8:"); - wPaths.tl(7, "schema:"); - wPaths.tl(8, "type: string"); - wPaths.l(); - wPaths.tl(1, "/logout:"); - wPaths.tl(2, "get:"); - wPaths.tl(3, "operationId: logout"); - wPaths.tl(3, "x-vertx-event-bus: ", appName, "-", languageName, "-logout"); - wPaths.tl(3, "description: >+"); - wPaths.tl(3, "responses:"); - wPaths.tl(4, "'200':"); - wPaths.tl(5, "description: >+"); - wPaths.tl(5, "content:"); - wPaths.tl(6, "application/json; charset=utf-8:"); - wPaths.tl(7, "schema:"); - wPaths.tl(8, "type: string"); - wPaths.l(); + authClients.fieldNames().forEach(authClientOpenApiId -> { + JsonObject authClient = authClients.getJsonObject(authClientOpenApiId); + String authCallbackUri = authClient.getString(ComputateConfigKeys.AUTH_CALLBACK_URI); + String authLogoutUri = authClient.getString(ComputateConfigKeys.AUTH_LOGOUT_URI); + + wPaths.l(); + wPaths.tl(1, authCallbackUri, ":"); + wPaths.tl(2, "get:"); + wPaths.tl(3, "operationId: callback"); + wPaths.tl(3, "x-vertx-event-bus: ", appName, "-", languageName, "-", authClientOpenApiId, "-callback"); + wPaths.tl(3, "description: >+"); + wPaths.tl(3, "responses:"); + wPaths.tl(4, "'200':"); + wPaths.tl(5, "description: >+"); + wPaths.tl(5, "content:"); + wPaths.tl(6, "application/json; charset=utf-8:"); + wPaths.tl(7, "schema:"); + wPaths.tl(8, "type: string"); + wPaths.l(); + wPaths.tl(1, authLogoutUri, ":"); + wPaths.tl(2, "get:"); + wPaths.tl(3, "operationId: logout"); + wPaths.tl(3, "x-vertx-event-bus: ", appName, "-", languageName, "-", authClientOpenApiId, "-logout"); + wPaths.tl(3, "description: >+"); + wPaths.tl(3, "responses:"); + wPaths.tl(4, "'200':"); + wPaths.tl(5, "description: >+"); + wPaths.tl(5, "content:"); + wPaths.tl(6, "application/json; charset=utf-8:"); + wPaths.tl(7, "schema:"); + wPaths.tl(8, "type: string"); + wPaths.l(); + }); if(openApiVersionNumber == 2) { wSchemas.tl(0, "definitions:"); } else { wRequestBodies.tl(0, "components:"); - if(config.getString(ComputateConfigKeys.AUTH_URL) != null) { - wRequestBodies.tl(1, "securitySchemes:"); - wRequestBodies.tl(2, "openIdConnect:"); - wRequestBodies.tl(3, "type: openIdConnect"); - wRequestBodies.tl(3, "openIdConnectUrl: ", config.getString(ComputateConfigKeys.AUTH_URL), "/realms/", config.getString(ComputateConfigKeys.AUTH_REALM), "/.well-known/openid-configuration"); + if(authClients.size() > 0) { + authClients.fieldNames().forEach(authClientOpenApiId -> { + JsonObject authClient = authClients.getJsonObject(authClientOpenApiId); + wRequestBodies.tl(1, "securitySchemes:"); + wRequestBodies.tl(2, authClientOpenApiId, ":"); + wRequestBodies.tl(3, "type: openIdConnect"); + wRequestBodies.tl(3, "openIdConnectUrl: ", authClient.getString(ComputateConfigKeys.AUTH_URL), "/realms/", authClient.getString(ComputateConfigKeys.AUTH_REALM), "/.well-known/openid-configuration"); + }); } wRequestBodies.tl(1, "requestBodies:"); diff --git a/src/main/java/org/computate/vertx/writer/ApiWriter.java b/src/main/java/org/computate/vertx/writer/ApiWriter.java index 147fcb0..2a72cd7 100644 --- a/src/main/java/org/computate/vertx/writer/ApiWriter.java +++ b/src/main/java/org/computate/vertx/writer/ApiWriter.java @@ -79,6 +79,9 @@ protected void _wSchemas(Wrap c) { protected void _config(Wrap c) { } + protected void _authClients(Wrap c) { + } + protected void _wRequestHeaders(Wrap c) { c.o(AllWriter.create(siteRequest_, " ")); } @@ -486,8 +489,10 @@ public void writeApi(Boolean id) throws Exception, Exception { if(roleSecurity == null || roleSecurity.equals("true")) { wPaths.tl(3, "security:"); // wPaths.tl(4, "- basicAuth: []"); - wPaths.tl(4, "- openIdConnect:"); - wPaths.tl(5, "- profile"); + authClients.fieldNames().forEach(authClientOpenApiId -> { + wPaths.tl(4, "- ", authClientOpenApiId, ":"); + wPaths.tl(5, "- profile"); + }); } else { roleSecurity.toString(); }