This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 3_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/3_0_X by this push:
new 17efc18b70 [SYNCOPE-1786] Allowing domain selection for Keymaster API
via Swagger UI + fixing KeymasterConfParamLoader for additional domains
17efc18b70 is described below
commit 17efc18b70d1a43f84c668e5578f435449b7e852
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Wed Mar 13 10:49:50 2024 +0100
[SYNCOPE-1786] Allowing domain selection for Keymaster API via Swagger UI +
fixing KeymasterConfParamLoader for additional domains
---
.../jpa/content/KeymasterConfParamLoader.java | 64 +++++++++++-----------
.../syncope/core/starter/SelfKeymasterContext.java | 34 ++++++++++++
2 files changed, 67 insertions(+), 31 deletions(-)
diff --git
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
index 0ee598824e..9745a1e90c 100644
---
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
+++
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
@@ -20,16 +20,19 @@ package org.apache.syncope.core.persistence.jpa.content;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.json.JsonMapper;
-import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Callable;
import javax.sql.DataSource;
import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
import org.apache.syncope.core.persistence.api.content.ConfParamLoader;
import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.transaction.annotation.Transactional;
/**
* Initialize Keymaster with default content if no data is present already.
@@ -53,41 +56,40 @@ public class KeymasterConfParamLoader implements
ConfParamLoader {
@Override
public void load(final String domain, final DataSource datasource) {
- boolean existingData;
- try {
- existingData = !confParamOps.list(domain).isEmpty();
- } catch (Exception e) {
- LOG.error("[{}] Could not access Keymaster", domain, e);
- existingData = true;
- }
+ AuthContextUtils.callAsAdmin(domain, new Callable<Void>() {
- if (existingData) {
- LOG.info("[{}] Data found in Keymaster, leaving untouched",
domain);
- } else {
- LOG.info("[{}] Empty Keymaster found, loading default content",
domain);
+ @Transactional
+ @Override
+ public Void call() throws Exception {
+ boolean existingData;
+ try {
+ existingData = !confParamOps.list(domain).isEmpty();
+ } catch (Exception e) {
+ LOG.error("[{}] Could not access Keymaster", domain, e);
+ existingData = true;
+ }
- try {
- InputStream contentJSON =
ApplicationContextProvider.getBeanFactory().
- getBean(domain + "KeymasterConfParamsJSON",
InputStream.class);
- loadDefaultContent(domain, contentJSON);
- } catch (Exception e) {
- LOG.error("[{}] While loading default Keymaster content",
domain, e);
- }
- }
- }
+ if (existingData) {
+ LOG.info("[{}] Data found in Keymaster, leaving
untouched", domain);
+ } else {
+ LOG.info("[{}] Empty Keymaster found, loading default
content", domain);
- protected void loadDefaultContent(final String domain, final InputStream
contentJSON)
- throws IOException {
+ try (InputStream contentJSON =
ApplicationContextProvider.getBeanFactory().
+ getBean(domain + "KeymasterConfParamsJSON",
InputStream.class)) {
- try (contentJSON) {
- JsonNode content = MAPPER.readTree(contentJSON);
- for (Iterator<Map.Entry<String, JsonNode>> itor =
content.fields(); itor.hasNext();) {
- Map.Entry<String, JsonNode> param = itor.next();
- Object value = MAPPER.treeToValue(param.getValue(),
Object.class);
- if (value != null) {
- confParamOps.set(domain, param.getKey(), value);
+ JsonNode content = MAPPER.readTree(contentJSON);
+ for (Iterator<Map.Entry<String, JsonNode>> itor =
content.fields(); itor.hasNext();) {
+ Map.Entry<String, JsonNode> param = itor.next();
+
Optional.ofNullable(MAPPER.treeToValue(param.getValue(), Object.class)).
+ ifPresent(value ->
confParamOps.set(domain, param.getKey(), value));
+ }
+ } catch (Exception e) {
+ LOG.error("[{}] While loading default Keymaster
content", domain, e);
+ }
}
+
+ return null;
}
- }
+ });
}
}
diff --git
a/core/self-keymaster-starter/src/main/java/org/apache/syncope/core/starter/SelfKeymasterContext.java
b/core/self-keymaster-starter/src/main/java/org/apache/syncope/core/starter/SelfKeymasterContext.java
index 127d9f76cf..dc42b8d375 100644
---
a/core/self-keymaster-starter/src/main/java/org/apache/syncope/core/starter/SelfKeymasterContext.java
+++
b/core/self-keymaster-starter/src/main/java/org/apache/syncope/core/starter/SelfKeymasterContext.java
@@ -20,11 +20,17 @@ package org.apache.syncope.core.starter;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import io.swagger.v3.oas.integration.api.OpenAPIConfiguration;
+import io.swagger.v3.oas.models.ExternalDocumentation;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.parameters.HeaderParameter;
+import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.SecurityScheme;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
@@ -45,6 +51,8 @@ import
org.apache.syncope.common.keymaster.client.api.ServiceOps;
import org.apache.syncope.common.keymaster.rest.api.service.ConfParamService;
import org.apache.syncope.common.keymaster.rest.api.service.DomainService;
import
org.apache.syncope.common.keymaster.rest.api.service.NetworkServiceService;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.core.keymaster.internal.InternalConfParamHelper;
import
org.apache.syncope.core.keymaster.internal.SelfKeymasterInternalConfParamOps;
import
org.apache.syncope.core.keymaster.internal.SelfKeymasterInternalDomainOps;
@@ -56,6 +64,7 @@ import
org.apache.syncope.core.keymaster.rest.security.SelfKeymasterUsernamePass
import org.apache.syncope.core.logic.ConfParamLogic;
import org.apache.syncope.core.logic.DomainLogic;
import org.apache.syncope.core.logic.NetworkServiceLogic;
+import org.apache.syncope.core.persistence.api.DomainHolder;
import org.apache.syncope.core.persistence.api.dao.ConfParamDAO;
import org.apache.syncope.core.persistence.api.dao.DomainDAO;
import org.apache.syncope.core.persistence.api.dao.NetworkServiceDAO;
@@ -109,6 +118,7 @@ public class SelfKeymasterContext {
@Bean
public Server selfKeymasterContainer(
+ final DomainHolder domainHolder,
final ConfParamService confParamService,
final NetworkServiceService networkServiceService,
final DomainService domainService,
@@ -162,6 +172,30 @@ public class SelfKeymasterContext {
return configuration;
}
+
+ @Override
+ protected void addParameters(final List<Parameter> parameters) {
+ Optional<Parameter> domainHeaderParameter =
parameters.stream().
+ filter(p -> p instanceof HeaderParameter &&
RESTHeaders.DOMAIN.equals(p.getName())).findFirst();
+ if (domainHeaderParameter.isEmpty()) {
+ HeaderParameter parameter = new HeaderParameter();
+ parameter.setName(RESTHeaders.DOMAIN);
+ parameter.setRequired(true);
+
+ ExternalDocumentation extDoc = new ExternalDocumentation();
+ extDoc.setDescription("Apache Syncope Reference Guide");
+
extDoc.setUrl("https://syncope.apache.org/docs/3.0/reference-guide.html#domains");
+
+ Schema<String> schema = new Schema<>();
+ schema.setDescription("Domains are built to facilitate
multitenancy.");
+ schema.setExternalDocs(extDoc);
+
schema.setEnum(domainHolder.getDomains().keySet().stream().sorted().collect(Collectors.toList()));
+ schema.setDefault(SyncopeConstants.MASTER_DOMAIN);
+ parameter.setSchema(schema);
+
+ parameters.add(parameter);
+ }
+ }
};
openApiCustomizer.setDynamicBasePath(false);
openApiCustomizer.setReplaceTags(false);