Skip to content

Commit

Permalink
UI config now primarily pulled from backend endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
EricWittmann committed Jan 29, 2024
1 parent d17b372 commit c52f7fd
Show file tree
Hide file tree
Showing 13 changed files with 434 additions and 153 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package io.apicurio.registry.rest.v3;

import java.util.HashMap;
import java.util.Map;

import io.apicurio.common.apps.core.System;
import io.apicurio.common.apps.logging.Logged;
import io.apicurio.registry.auth.AuthConfig;
import io.apicurio.registry.auth.Authorized;
import io.apicurio.registry.auth.AuthorizedLevel;
import io.apicurio.registry.auth.AuthorizedStyle;
import io.apicurio.registry.limits.RegistryLimitsConfiguration;
import io.apicurio.registry.metrics.health.liveness.ResponseErrorLivenessCheck;
import io.apicurio.registry.metrics.health.readiness.ResponseTimeoutReadinessCheck;
import io.apicurio.registry.limits.RegistryLimitsConfiguration;
import io.apicurio.registry.rest.v3.beans.Limits;
import io.apicurio.registry.rest.v3.beans.SystemInfo;

import io.apicurio.registry.rest.v3.beans.UserInterfaceConfig;
import io.apicurio.registry.rest.v3.beans.UserInterfaceConfigAuth;
import io.apicurio.registry.rest.v3.beans.UserInterfaceConfigFeatures;
import io.apicurio.registry.rest.v3.beans.UserInterfaceConfigUi;
import io.apicurio.registry.ui.UserInterfaceConfigProperties;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.interceptor.Interceptors;
Expand All @@ -22,6 +30,12 @@ public class SystemResourceImpl implements SystemResource {

@Inject
System system;

@Inject
AuthConfig authConfig;

@Inject
UserInterfaceConfigProperties uiConfig;

@Inject
RegistryLimitsConfiguration registryLimitsConfiguration;
Expand All @@ -44,6 +58,7 @@ public SystemInfo getSystemInfo() {
* @see io.apicurio.registry.rest.v3.SystemResource#getResourceLimits()
*/
@Override
@Authorized(style=AuthorizedStyle.None, level=AuthorizedLevel.None)
public Limits getResourceLimits() {
var limitsConfig = registryLimitsConfiguration;
var limits = new Limits();
Expand All @@ -61,4 +76,41 @@ public Limits getResourceLimits() {
limits.setMaxRequestsPerSecondCount(limitsConfig.getMaxRequestsPerSecondCount());
return limits;
}

/**
* @see io.apicurio.registry.rest.v3.SystemResource#getUIConfig()
*/
@Override
@Authorized(style=AuthorizedStyle.None, level=AuthorizedLevel.None)
public UserInterfaceConfig getUIConfig() {
return UserInterfaceConfig.builder()
.ui(UserInterfaceConfigUi.builder()
.contextPath(uiConfig.contextPath)
.navPrefixPath(uiConfig.navPrefixPath)
.oaiDocsUrl(uiConfig.docsUrl)
.build())
.auth(uiAuthConfig())
.features(UserInterfaceConfigFeatures.builder()
.readOnly("true".equals(uiConfig.featureReadOnly))
.breadcrumbs("true".equals(uiConfig.featureBreadcrumbs))
.roleManagement(authConfig.isRbacEnabled())
.settings("true".equals(uiConfig.featureSettings))
.build())
.build();
}

private UserInterfaceConfigAuth uiAuthConfig() {
UserInterfaceConfigAuth rval = new UserInterfaceConfigAuth();
rval.setObacEnabled(authConfig.isObacEnabled());
rval.setRbacEnabled(authConfig.isRbacEnabled());
rval.setType(authConfig.isAuthEnabled() ? UserInterfaceConfigAuth.Type.oidc : UserInterfaceConfigAuth.Type.none);
if (authConfig.isAuthEnabled()) {
Map<String, String> options = new HashMap<>();
options.put("url", uiConfig.authOidcUrl);
options.put("redirectUri", uiConfig.authOidcRedirectUri);
options.put("clientId", uiConfig.authOidcClientId);
rval.setOptions(options);
}
return rval;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.apicurio.registry.ui;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import io.apicurio.common.apps.config.Info;
import jakarta.inject.Singleton;

@Singleton
public class UserInterfaceConfigProperties {

@ConfigProperty(name = "registry.ui.contextPath", defaultValue = "/")
@Info(category = "ui", description = "Context path of the UI", availableSince = "3.0.0")
public String contextPath;
@ConfigProperty(name = "registry.ui.navPrefixPath", defaultValue = "/")
@Info(category = "ui", description = "Navigation prefix for all UI paths", availableSince = "3.0.0")
public String navPrefixPath;
@ConfigProperty(name = "registry.ui.docsUrl", defaultValue = "/docs/")
@Info(category = "ui", description = "URL of the Documentation component", availableSince = "3.0.0")
public String docsUrl;


@ConfigProperty(name = "registry.auth.url.configured")
public String authOidcUrl;
@ConfigProperty(name = "registry.ui.auth.oidc.redirectUri", defaultValue = "/")
@Info(category = "ui", description = "The OIDC redirectUri", availableSince = "3.0.0")
public String authOidcRedirectUri;
@ConfigProperty(name = "registry.ui.auth.oidc.clientId", defaultValue = "apicurio-registry-ui")
@Info(category = "ui", description = "The OIDC clientId", availableSince = "3.0.0")
public String authOidcClientId;


@ConfigProperty(name = "registry.ui.features.readOnly", defaultValue = "false")
@Info(category = "ui", description = "Enabled to set the UI to read-only mode", availableSince = "3.0.0")
public String featureReadOnly;
@ConfigProperty(name = "registry.ui.features.breadcrumbs", defaultValue = "true")
@Info(category = "ui", description = "Enabled to show breadcrumbs in the UI", availableSince = "3.0.0")
public String featureBreadcrumbs;
@ConfigProperty(name = "registry.ui.features.settings", defaultValue = "true")
@Info(category = "ui", description = "Enabled to show the Settings tab in the UI", availableSince = "3.0.0")
public String featureSettings;

}
203 changes: 203 additions & 0 deletions common/src/main/resources/META-INF/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3380,6 +3380,33 @@
}
]
},
"/system/uiConfig": {
"summary": "Get UI configuration",
"description": "This endpoint is used by the user interface to retrieve UI specific configuration\nin a JSON payload. This allows the UI and the backend to be configured in the \nsame place (the backend process/pod). When the UI loads, it will make an API call\nto this endpoint to determine what UI features and options are configured.",
"get": {
"tags": [
"System"
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserInterfaceConfig"
}
}
},
"description": "The UI config."
},
"500": {
"$ref": "#/components/responses/ServerError"
}
},
"operationId": "getUIConfig",
"summary": "Get UI config",
"description": "Returns the UI configuration properties for this server. The registry UI can be\nconnected to a backend using just a URL. The rest of the UI configuration can then\nbe fetched from the backend using this operation. This allows UI and backend to\nboth be configured in the same place.\n\nThis operation may fail for one of the following reasons:\n\n* A server error occurred (HTTP error `500`)\n"
}
},
"x-codegen-contextRoot": "/apis/registry/v3"
},
"components": {
Expand Down Expand Up @@ -4711,6 +4738,182 @@
}
]
}
},
"UserInterfaceConfig": {
"title": "Root Type for UserInterfaceConfig",
"description": "Defines the user interface configuration data type.",
"required": [
"auth"
],
"type": "object",
"properties": {
"ui": {
"$ref": "#/components/schemas/UserInterfaceConfigUi",
"properties": {
"contextPath": {
"type": "string"
},
"navPrefixPath": {
"type": "string"
},
"oaiDocsUrl": {
"type": "string"
}
}
},
"auth": {
"$ref": "#/components/schemas/UserInterfaceConfigAuth",
"properties": {
"type": {
"type": "string"
},
"rbacEnabled": {
"type": "boolean"
},
"obacEnabled": {
"type": "boolean"
},
"options": {
"type": "object",
"properties": {
"url": {
"type": "string"
},
"redirectUri": {
"type": "string"
},
"clientId": {
"type": "string"
}
}
}
}
},
"features": {
"$ref": "#/components/schemas/UserInterfaceConfigFeatures",
"properties": {
"readOnly": {
"type": "boolean"
},
"breadcrumbs": {
"type": "boolean"
},
"roleManagement": {
"type": "boolean"
},
"settings": {
"type": "boolean"
}
}
}
},
"example": {
"ui": {
"contextPath": "/",
"navPrefixPath": "/",
"oaiDocsUrl": "https://registry.apicur.io/docs"
},
"auth": {
"type": "oidc",
"rbacEnabled": true,
"obacEnabled": false,
"options": {
"url": "https://auth.apicur.io/realms/apicurio",
"redirectUri": "http://registry.apicur.io",
"clientId": "apicurio-registry-ui"
}
},
"features": {
"readOnly": false,
"breadcrumbs": true,
"roleManagement": false,
"settings": true
}
}
},
"UserInterfaceConfigAuth": {
"title": "Root Type for UserInterfaceConfigAuth",
"description": "",
"required": [
"obacEnabled",
"rbacEnabled"
],
"type": "object",
"properties": {
"type": {
"enum": [
"none",
"oidc"
],
"type": "string"
},
"rbacEnabled": {
"type": "boolean"
},
"obacEnabled": {
"type": "boolean"
},
"options": {
"$ref": "#/components/schemas/Properties"
}
},
"example": {
"type": "oidc",
"rbacEnabled": true,
"obacEnabled": false,
"options": {
"url": "https://auth.apicur.io/realms/apicurio",
"redirectUri": "https://registry.apicur.io",
"clientId": "registry-ui"
}
}
},
"UserInterfaceConfigFeatures": {
"title": "Root Type for UserInterfaceConfigFeatures",
"description": "",
"required": [],

Check failure on line 4874 in common/src/main/resources/META-INF/openapi.json

View workflow job for this annotation

GitHub Actions / Validate

oas3-schema "required" property must not have fewer than 1 items.
"type": "object",
"properties": {
"readOnly": {
"type": "boolean"
},
"breadcrumbs": {
"type": "boolean"
},
"roleManagement": {
"type": "boolean"
},
"settings": {
"type": "boolean"
}
},
"example": {
"readOnly": false,
"breadcrumbs": true,
"roleManagement": false,
"settings": true
}
},
"UserInterfaceConfigUi": {
"title": "Root Type for UserInterfaceConfigUi",
"description": "",
"type": "object",
"properties": {
"contextPath": {
"type": "string"
},
"navPrefixPath": {
"type": "string"
},
"oaiDocsUrl": {
"type": "string"
}
},
"example": {
"contextPath": "/",
"navPrefixPath": "/",
"oaiDocsUrl": "https://registry.apicur.io/docs"
}
}
},
"responses": {
Expand Down
Loading

0 comments on commit c52f7fd

Please sign in to comment.