diff --git a/distro/docker-compose/.env.template b/distro/docker-compose/.env.template index 7fb1e8f29..7c845b331 100644 --- a/distro/docker-compose/.env.template +++ b/distro/docker-compose/.env.template @@ -64,3 +64,5 @@ APICURIO_UI_FEATURE_MICROCKS=true APICURIO_SHARE_FOR_EVERYONE=false APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE=false + +APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP='([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+' diff --git a/distro/docker-compose/docker-compose.apicurio.yml b/distro/docker-compose/docker-compose.apicurio.yml index 3250fb472..2f0d3211d 100644 --- a/distro/docker-compose/docker-compose.apicurio.yml +++ b/distro/docker-compose/docker-compose.apicurio.yml @@ -64,3 +64,4 @@ services: APICURIO_UI_FEATURE_MICROCKS: ${APICURIO_UI_FEATURE_MICROCKS} APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE: ${APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE} APICURIO_UI_LOGOUT_REDIRECT_URI: / + APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP: ${APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP} diff --git a/distro/helm/templates/apicurio-studio-ui-deployment.yaml b/distro/helm/templates/apicurio-studio-ui-deployment.yaml index 2ca17ebb1..023bdd136 100644 --- a/distro/helm/templates/apicurio-studio-ui-deployment.yaml +++ b/distro/helm/templates/apicurio-studio-ui-deployment.yaml @@ -41,6 +41,8 @@ spec: value: {{ .Values.ui.hub.api.url | default (print "https://" .Values.ui.hostname "/studio-api") }} - name: APICURIO_UI_EDITING_URL value: {{ .Values.ui.editing.url | default (print "wss://" .Values.ui.hostname "/ws") }} + - name: APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP + value: { { .values.ui.channelNameRegex } } - name: JAVA_TOOL_OPTIONS value: {{ .Values.ui.jvmArgs }} - name: APICURIO_MICROCKS_API_URL diff --git a/distro/helm/values.yaml b/distro/helm/values.yaml index d350448ed..5fb419eaf 100644 --- a/distro/helm/values.yaml +++ b/distro/helm/values.yaml @@ -12,6 +12,7 @@ ui: jvmArgs: -Djava.net.preferIPv4Stack=true port: 8093 imagePullPolicy: IfNotPresent + channelNameRegex: ([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+ hostname: APICURIO_URL extraVolumes: [] logout: diff --git a/distro/kubernetes/apicurio-studio-ui-deployment.yaml b/distro/kubernetes/apicurio-studio-ui-deployment.yaml index 42c36ce93..cb37caeed 100644 --- a/distro/kubernetes/apicurio-studio-ui-deployment.yaml +++ b/distro/kubernetes/apicurio-studio-ui-deployment.yaml @@ -66,6 +66,8 @@ spec: key: apicurio-ui-editing-url - name: JAVA_TOOL_OPTIONS value: -Djava.net.preferIPv4Stack=true + - name: APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP + value: '{([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+' - name: APICURIO_MICROCKS_API_URL valueFrom: configMapKeyRef: diff --git a/distro/quarkus/docker-compose/.env.template b/distro/quarkus/docker-compose/.env.template index 2051a884e..8ca24ac1b 100644 --- a/distro/quarkus/docker-compose/.env.template +++ b/distro/quarkus/docker-compose/.env.template @@ -63,6 +63,8 @@ APICURIO_UI_KC_CLIENT_ID=apicurio-studio APICURIO_UI_HUB_API_URL=http://$HOST:8091 APICURIO_UI_EDITING_URL=ws://$HOST:8092 APICURIO_UI_FEATURE_MICROCKS=true +APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP='([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+' + APICURIO_SHARE_FOR_EVERYONE=false APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE=false diff --git a/distro/quarkus/docker-compose/docker-compose.apicurio.yml b/distro/quarkus/docker-compose/docker-compose.apicurio.yml index 8ff57979a..a20c8ecc2 100644 --- a/distro/quarkus/docker-compose/docker-compose.apicurio.yml +++ b/distro/quarkus/docker-compose/docker-compose.apicurio.yml @@ -84,3 +84,4 @@ services: APICURIO_UI_FEATURE_MICROCKS: ${APICURIO_UI_FEATURE_MICROCKS} APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE: ${APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE} APICURIO_UI_LOGOUT_REDIRECT_URI: / + APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP: ${APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP} diff --git a/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/config/StudioUiConfiguration.java b/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/config/StudioUiConfiguration.java index 9b068ab9a..5879de004 100644 --- a/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/config/StudioUiConfiguration.java +++ b/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/config/StudioUiConfiguration.java @@ -54,6 +54,9 @@ public class StudioUiConfiguration extends Configuration { private static final String FEATURE_SHARE_WITH_EVERYONE_ENV = "APICURIO_UI_FEATURE_SHARE_WITH_EVERYONE"; private static final String FEATURE_SHARE_WITH_EVERYONE_SYSPROP = "apicurio-ui.feature.shareWithEveryone"; + private static final String VALIDATION_CHANNELNAME_REGEXP_ENV= "APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP"; + private static final String VALIDATION_CHANNELNAME_REGEXP_SYSPROP = "apicurio-ui.validation.channelName.regexp"; + /** * Returns the URL of the Apicurio Hub API. */ @@ -119,4 +122,10 @@ public String getUiUrl() { return getConfigurationProperty(HUB_UI_URL_ENV, HUB_UI_URL_SYSPROP, null); } + /** + * @return the configured REGEXP CHANNEL + */ + public String getAddChannelValidation() { + return getConfigurationProperty(VALIDATION_CHANNELNAME_REGEXP_ENV, VALIDATION_CHANNELNAME_REGEXP_SYSPROP, "([^{}\\/]*(\\{[a-zA-Z_][0-9a-zA-Z_]*\\})?)+"); + } } diff --git a/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/servlets/StudioConfigServlet.java b/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/servlets/StudioConfigServlet.java index c450dabc6..15960fd4f 100644 --- a/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/servlets/StudioConfigServlet.java +++ b/front-end/servlet/src/main/java/io/apicurio/studio/fe/servlet/servlets/StudioConfigServlet.java @@ -109,12 +109,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) config.setUi(new StudioConfigUi()); config.getUi().setUrl(this.uiConfig.getUiUrl()); + config.getUi().setChannelNameValidation(this.uiConfig.getAddChannelValidation()); config.setFeatures(new StudioConfigFeatures()); config.getFeatures().setMicrocks(uiConfig.isMicrocksEnabled()); config.getFeatures().setGraphql(uiConfig.isGraphQLEnabled()); config.getFeatures().setAsyncapi(uiConfig.isAsyncAPIEnabled()); config.getFeatures().setShareWithEveryone(uiConfig.isShareWithEveryoneEnabled()); + g.writeObject(config); diff --git a/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.html b/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.html index 282c24dee..78c0a4562 100644 --- a/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.html +++ b/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.html @@ -15,7 +15,7 @@
- +
Channel already exists.
Enter a valid channel. Channel is required. diff --git a/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.ts b/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.ts index d9f609a32..15322a63e 100644 --- a/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.ts +++ b/front-end/studio/src/app/pages/apis/{apiId}/editor/_components/dialogs/add-channel.component.ts @@ -18,6 +18,8 @@ import {Component, ElementRef, EventEmitter, Output, QueryList, ViewChildren} from "@angular/core"; import {ModalDirective} from "ngx-bootstrap"; import {AaiDocument} from "apicurio-data-models"; +import {ConfigService} from "../../../../../../services/config.service"; + @Component({ moduleId: module.id, @@ -33,11 +35,16 @@ export class AddChannelDialogComponent { private _isOpen: boolean = false; - channel: string = ""; + channelRegex: string = ""; + channel: string = ""; channels: string[] = []; channelExists: boolean = false; + constructor(configService: ConfigService){ + this.channelRegex = configService.channelNameValidation(); + } + /** * Called to open the dialog. * @param document @@ -111,4 +118,8 @@ export class AddChannelDialogComponent { validateChannel(newChannel: string) { this.channelExists = this.channels.indexOf(newChannel) != -1; } + + channelValidation(): string{ + return this.channelRegex; + } } diff --git a/front-end/studio/src/app/services/config.service.ts b/front-end/studio/src/app/services/config.service.ts index c8771d66e..539a076cf 100644 --- a/front-end/studio/src/app/services/config.service.ts +++ b/front-end/studio/src/app/services/config.service.ts @@ -29,7 +29,8 @@ let DEFAULT_CONFIG: any = { editingUrl: "http://localhost:8080/api-editing", }, ui: { - uiUrl: "http://localhost:8080/studio/" + uiUrl: "http://localhost:8080/studio/", + channelNameValidation: '([^{}\\/]*(\\{[a-zA-Z_][0-9a-zA-Z_]*\\})?)+', }, features: { "microcks": true, @@ -153,4 +154,11 @@ export class ConfigService { } return this.config.features.shareWithEveryone; } + + public channelNameValidation() :string { + if (!this.config.ui.channelNameValidation || !this.config.ui.channelNameValidation) { + return ""; + } + return this.config.ui.channelNameValidation; + } } diff --git a/platforms/quarkus/ui/src/main/resources/application.properties b/platforms/quarkus/ui/src/main/resources/application.properties index a73cdaaba..cef5cc31d 100644 --- a/platforms/quarkus/ui/src/main/resources/application.properties +++ b/platforms/quarkus/ui/src/main/resources/application.properties @@ -6,6 +6,7 @@ #apicurio %dev.apicurio-ui.editing.url=${APICURIO_UI_EDITING_URL:http://localhost:8091/api} %dev.apicurio-ui.hub-api.url=${APICURIO_UI_HUB_API_URL:https://localhost:8092/ws} +%dev.apicurio-ui.validation.channelName.regexp=${APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP:} # === Prod profile @@ -13,6 +14,7 @@ %prod.quarkus.oidc.client-id=${APICURIO_KC_CLIENT_ID} %prod.apicurio-ui.editing.url=${APICURIO_UI_EDITING_URL:} %prod.apicurio-ui.hub-api.url=${APICURIO_UI_HUB_API_URL:} +%prod.apicurio-ui.validation.channelName.regexp=${APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP:} quarkus.oidc.application-type=web-app quarkus.http.cors=true diff --git a/platforms/thorntail/api/Dockerfile b/platforms/thorntail/api/Dockerfile index 1e568d18d..69f5afc34 100644 --- a/platforms/thorntail/api/Dockerfile +++ b/platforms/thorntail/api/Dockerfile @@ -43,6 +43,7 @@ ENV APICURIO_MAX_HEAP=2048m ENV APICURIO_GITHUB_API_URL= ENV APICURIO_GITLAB_API_URL= ENV APICURIO_BITBUCKET_API_URL= +ENV APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP='([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+' CMD java -jar /opt/apicurio/apicurio-studio-api-thorntail.jar \ diff --git a/platforms/thorntail/ui/Dockerfile b/platforms/thorntail/ui/Dockerfile index ae3165a39..90e1631bc 100644 --- a/platforms/thorntail/ui/Dockerfile +++ b/platforms/thorntail/ui/Dockerfile @@ -32,6 +32,8 @@ ENV APICURIO_UI_HUB_API_URL=https://localhost:8443/api ENV APICURIO_UI_EDITING_URL=https://localhost:8443/ws ENV APICURIO_MIN_HEAP=512m ENV APICURIO_MAX_HEAP=2048m +ENV APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP='([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+' + CMD java -jar /opt/apicurio/apicurio-studio-ui-thorntail.jar \ diff --git a/platforms/thorntail/ui/README.md b/platforms/thorntail/ui/README.md index bbffad97a..2b0927ad9 100644 --- a/platforms/thorntail/ui/README.md +++ b/platforms/thorntail/ui/README.md @@ -28,6 +28,7 @@ The following environment variables control configuration of the app: APICURIO_LOGGING_LEVEL=INFO APICURIO_UI_LOGOUT_REDIRECT_URI=/logout APICURIO_UI_HUB_UI_URL=http://localhost:8080 + APICURIO_UI_VALIDATION_CHANNELNAME_REGEXP='([^{}\/]*(\{[a-zA-Z_][0-9a-zA-Z_]*\})?)+' APICURIO_UI_HUB_API_URL=http://localhost:8090/ APICURIO_UI_EDITING_URL=http://localhost:8091/ APICURIO_UI_FEATURE_MICROCKS=false diff --git a/shared/beans/src/main/java/io/apicurio/studio/shared/beans/StudioConfigUi.java b/shared/beans/src/main/java/io/apicurio/studio/shared/beans/StudioConfigUi.java index 824a6276a..ab19b0005 100644 --- a/shared/beans/src/main/java/io/apicurio/studio/shared/beans/StudioConfigUi.java +++ b/shared/beans/src/main/java/io/apicurio/studio/shared/beans/StudioConfigUi.java @@ -28,6 +28,8 @@ public class StudioConfigUi { private String url; + + private String channelNameValidation; /** * Constructor. @@ -49,4 +51,20 @@ public void setUrl(String url) { this.url = url; } + /** + * @return the channel Name Regex + */ + public String getChannelNameValidation() { + return channelNameValidation; + } + + /** + * @param channelNameRegex the channel Name Regex to set + */ + public void setChannelNameValidation(String channelNameValidation) { + this.channelNameValidation = channelNameValidation; + } + + + }