You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by di...@apache.org on 2020/03/26 08:42:37 UTC
[syncope] branch SYNCOPE-163-1 updated: [SYNCOPE-160] initial WA
service implementation
This is an automated email from the ASF dual-hosted git repository.
dimaayash pushed a commit to branch SYNCOPE-163-1
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/SYNCOPE-163-1 by this push:
new 3936168 [SYNCOPE-160] initial WA service implementation
3936168 is described below
commit 393616890558afab52981559c81a97f351b19e13
Author: dima.ayash <di...@tirasa.net>
AuthorDate: Thu Mar 26 09:42:08 2020 +0100
[SYNCOPE-160] initial WA service implementation
---
.../lib/policy/AbstractAccessPolicyConf.java | 6 +-
.../common/lib/policy/AccessPolicyConf.java | 4 +-
.../common/lib/to/RegisteredClientAppTO.java | 70 +++++++++++++
.../syncope/common/lib/types/AMEntitlement.java | 4 +
.../api/service/RegisteredClientAppService.java | 65 ++++++++++++
.../core/logic/RegisteredClientAppLogic.java | 50 ++++++++++
.../service/RegisteredClientAppServiceImpl.java | 60 +++++++++++
.../jpa/inner/AbstractClientAppTest.java | 3 +-
.../core/persistence/jpa/inner/PolicyTest.java | 3 +-
.../api/data/RegisteredClientAppBinder.java | 23 +----
.../java/data/RegisteredClientAppBinderImpl.java | 110 +++++++++++++++++++++
.../org/apache/syncope/fit/core/PolicyITCase.java | 6 +-
.../org/apache/syncope/fit/core/RealmITCase.java | 3 +-
wa/starter/pom.xml | 10 ++
.../syncope/wa/mapper/RegisteredServiceMapper.java | 109 ++++++++++++++++++++
.../wa/starter/rest/SyncopeServiceRegistry.java | 11 ++-
16 files changed, 506 insertions(+), 31 deletions(-)
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractAccessPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractAccessPolicyConf.java
index cdf5d8e..653fe11 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractAccessPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractAccessPolicyConf.java
@@ -23,8 +23,8 @@ import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
import java.io.Serializable;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -43,7 +43,7 @@ public abstract class AbstractAccessPolicyConf implements Serializable, AccessPo
private boolean ssoEnabled = true;
@XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
- private final Map<String, List<String>> requiredAttributes = new LinkedHashMap<>();
+ private final Map<String, Set<String>> requiredAttributes = new LinkedHashMap<>();
public AbstractAccessPolicyConf() {
setName(getClass().getName());
@@ -80,7 +80,7 @@ public abstract class AbstractAccessPolicyConf implements Serializable, AccessPo
@XmlElement(name = "requiredAttribute")
@JsonProperty("requiredAttributes")
@Override
- public Map<String, List<String>> getRequiredAttributes() {
+ public Map<String, Set<String>> getRequiredAttributes() {
return requiredAttributes;
}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java
index 698e171..3cb0505 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java
@@ -20,8 +20,8 @@ package org.apache.syncope.common.lib.policy;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import java.io.Serializable;
-import java.util.List;
import java.util.Map;
+import java.util.Set;
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
public interface AccessPolicyConf extends Serializable {
@@ -37,5 +37,5 @@ public interface AccessPolicyConf extends Serializable {
boolean isSsoEnabled();
- Map<String, List<String>> getRequiredAttributes();
+ Map<String, Set<String>> getRequiredAttributes();
}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/RegisteredClientAppTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/RegisteredClientAppTO.java
new file mode 100644
index 0000000..0a33113
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/RegisteredClientAppTO.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import java.io.Serializable;
+import org.apache.syncope.common.lib.policy.AccessPolicyConf;
+import org.apache.syncope.common.lib.policy.AttrReleasePolicyConf;
+import org.apache.syncope.common.lib.to.client.ClientAppTO;
+
+public class RegisteredClientAppTO implements Serializable {
+
+ private static final long serialVersionUID = 6633251825655119506L;
+
+ private ClientAppTO clientAppTO;
+
+ private AccessPolicyConf accessPolicyConf;
+
+ private AuthPolicyTO authPolicyTO;
+
+ private AttrReleasePolicyConf attrReleasePolicyConf;
+
+ public ClientAppTO getClientAppTO() {
+ return clientAppTO;
+ }
+
+ public void setClientAppTO(final ClientAppTO clientAppTO) {
+ this.clientAppTO = clientAppTO;
+ }
+
+ public AccessPolicyConf getAccessPolicyConf() {
+ return accessPolicyConf;
+ }
+
+ public void setAccessPolicyConf(final AccessPolicyConf accessPolicyConf) {
+ this.accessPolicyConf = accessPolicyConf;
+ }
+
+ public AuthPolicyTO getAuthPolicyTO() {
+ return authPolicyTO;
+ }
+
+ public void setAuthPolicyTO(final AuthPolicyTO authPolicyTO) {
+ this.authPolicyTO = authPolicyTO;
+ }
+
+ public AttrReleasePolicyConf getAttrReleasePolicyConf() {
+ return attrReleasePolicyConf;
+ }
+
+ public void setAttrReleasePolicyConf(final AttrReleasePolicyConf attrReleasePolicyConf) {
+ this.attrReleasePolicyConf = attrReleasePolicyConf;
+ }
+
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
index 046f61b..16939e6 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
@@ -56,6 +56,10 @@ public final class AMEntitlement {
private static final Set<String> VALUES;
+ public static final String REGISTERED_CLIENT_APP_READ = "REGISTERED_CLIENT_APP_READ";
+
+ public static final String REGISTERED_CLIENT_APP_LIST = "REGISTERED_CLIENT_APP_READ";
+
static {
Set<String> values = new TreeSet<>();
for (Field field : AMEntitlement.class.getDeclaredFields()) {
diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RegisteredClientAppService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RegisteredClientAppService.java
new file mode 100644
index 0000000..1a4bba6
--- /dev/null
+++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RegisteredClientAppService.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.rest.api.service;
+
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.security.SecurityRequirements;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.RegisteredClientAppTO;
+
+/**
+ * REST operations for resgistered client applications.
+ */
+@Tag(name = "RegisteredClientAppss")
+@SecurityRequirements({
+ @SecurityRequirement(name = "BasicAuthentication"),
+ @SecurityRequirement(name = "Bearer") })
+@Path("registeredClientApps")
+public interface RegisteredClientAppService extends JAXRSService {
+
+ /**
+ * Returns a list of all client applications to be registered.
+ *
+ * @return list of all client applications.
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ List<RegisteredClientAppTO> list();
+
+ /**
+ * Returns a client application with matching key.
+ *
+ * @param key registered client application key to be read
+ * @return registered client application with matching key
+ */
+ @GET
+ @Path("{key}")
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ RegisteredClientAppTO read(@NotNull @PathParam("key") String key);
+
+}
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/RegisteredClientAppLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/RegisteredClientAppLogic.java
new file mode 100644
index 0000000..a83b63e
--- /dev/null
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/RegisteredClientAppLogic.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.to.RegisteredClientAppTO;
+import org.apache.syncope.common.lib.to.client.ClientAppTO;
+import org.apache.syncope.common.lib.types.AMEntitlement;
+import org.apache.syncope.core.provisioning.api.data.RegisteredClientAppBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class RegisteredClientAppLogic {
+
+ @Autowired
+ private RegisteredClientAppBinder binder;
+
+ @PreAuthorize("hasRole('" + AMEntitlement.REGISTERED_CLIENT_APP_LIST + "')")
+ @Transactional(readOnly = true)
+ public List<RegisteredClientAppTO> list(final List<ClientAppTO> clientApps) {
+ return clientApps.stream().map(binder::getRegisteredClientAppTO).collect(Collectors.toList());
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.REGISTERED_CLIENT_APP_READ + "')")
+ @Transactional(readOnly = true)
+ public RegisteredClientAppTO read(final ClientAppTO clientApp) {
+ return binder.getRegisteredClientAppTO(clientApp);
+ }
+
+}
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RegisteredClientAppServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RegisteredClientAppServiceImpl.java
new file mode 100644
index 0000000..5549c8c
--- /dev/null
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RegisteredClientAppServiceImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf.service;
+
+import org.apache.syncope.common.lib.to.client.ClientAppTO;
+import org.apache.syncope.core.logic.ClientAppLogic;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.syncope.common.lib.to.RegisteredClientAppTO;
+import org.apache.syncope.common.lib.types.ClientAppType;
+import org.apache.syncope.common.rest.api.service.RegisteredClientAppService;
+import org.apache.syncope.core.logic.RegisteredClientAppLogic;
+
+@Service
+public class RegisteredClientAppServiceImpl extends AbstractServiceImpl implements RegisteredClientAppService {
+
+ @Autowired
+ private ClientAppLogic clientAppLogic;
+
+ @Autowired
+ private RegisteredClientAppLogic logic;
+
+ @Override
+ public List<RegisteredClientAppTO> list() {
+ List<ClientAppTO> applications = new ArrayList<>();
+ Arrays.asList(ClientAppType.values()).forEach(type -> applications.addAll(clientAppLogic.list(type)));
+ return logic.list(applications);
+ }
+
+ @Override
+ public RegisteredClientAppTO read(final String key) {
+ try {
+ return logic.read(clientAppLogic.read(ClientAppType.SAML2SP, key));
+ } catch (NotFoundException e) {
+ return logic.read(clientAppLogic.read(ClientAppType.OIDCRP, key));
+ }
+ }
+
+}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AbstractClientAppTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AbstractClientAppTest.java
index 360e076..9c9c17e 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AbstractClientAppTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AbstractClientAppTest.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.inner;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf;
import org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf;
import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
@@ -71,7 +72,7 @@ public class AbstractClientAppTest extends AbstractTest {
DefaultAccessPolicyConf conf = new DefaultAccessPolicyConf();
conf.setEnabled(true);
conf.setName("Example Access Policy for an application");
- conf.getRequiredAttributes().putAll(Map.of("attribute1", List.of("value1", "value2")));
+ conf.getRequiredAttributes().putAll(Map.of("attribute1", Set.of("value1", "value2")));
conf.setSsoEnabled(false);
Implementation type = entityFactory.newEntity(Implementation.class);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
index 304d97a..09b5a67 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -55,6 +55,7 @@ import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
+import java.util.Set;
import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
@Transactional("Master")
@@ -207,7 +208,7 @@ public class PolicyTest extends AbstractTest {
accessPolicy.setDescription("This is a sample attr release policy that releases everything");
DefaultAccessPolicyConf conf = new DefaultAccessPolicyConf();
- conf.getRequiredAttributes().putAll(Map.of("cn", List.of("syncope")));
+ conf.getRequiredAttributes().putAll(Map.of("cn", Set.of("syncope")));
conf.setName("AttrReleasePolicyAllowEverything");
Implementation type = entityFactory.newEntity(Implementation.class);
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RegisteredClientAppBinder.java
similarity index 58%
copy from common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java
copy to core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RegisteredClientAppBinder.java
index 698e171..7a10d03 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyConf.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RegisteredClientAppBinder.java
@@ -16,26 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.common.lib.policy;
+package org.apache.syncope.core.provisioning.api.data;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
+import org.apache.syncope.common.lib.to.RegisteredClientAppTO;
+import org.apache.syncope.common.lib.to.client.ClientAppTO;
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public interface AccessPolicyConf extends Serializable {
+public interface RegisteredClientAppBinder {
- /**
- * Give name of related access policy.
- *
- * @return name of this access policy
- */
- String getName();
+ RegisteredClientAppTO getRegisteredClientAppTO(ClientAppTO clientAppTO);
- boolean isEnabled();
-
- boolean isSsoEnabled();
-
- Map<String, List<String>> getRequiredAttributes();
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RegisteredClientAppBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RegisteredClientAppBinderImpl.java
new file mode 100644
index 0000000..151670b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RegisteredClientAppBinderImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.RegisteredClientAppTO;
+import org.apache.syncope.common.lib.to.client.ClientAppTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AttrReleasePolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.Policy;
+import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
+import org.apache.syncope.core.provisioning.api.data.RegisteredClientAppBinder;
+import org.apache.syncope.core.spring.ImplementationManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RegisteredClientAppBinderImpl implements RegisteredClientAppBinder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RegisteredClientAppBinder.class);
+
+ @Autowired
+ private PolicyDAO policyDAO;
+
+ @Autowired
+ private PolicyDataBinder policyDataBinder;
+
+ @Override
+ public RegisteredClientAppTO getRegisteredClientAppTO(final ClientAppTO clientAppTO) {
+ RegisteredClientAppTO registeredClientAppTO = new RegisteredClientAppTO();
+ registeredClientAppTO.setClientAppTO(clientAppTO);
+
+ if (clientAppTO.getAuthPolicy() == null) {
+ clientAppTO.setAuthPolicy(null);
+ } else {
+ Policy policy = policyDAO.find(clientAppTO.getAuthPolicy());
+ if (policy instanceof AuthPolicy) {
+ registeredClientAppTO.setAuthPolicyTO(policyDataBinder.getPolicyTO(policy));
+ } else {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+ sce.getElements().add("Expected " + AuthPolicy.class.getSimpleName()
+ + ", found " + policy.getClass().getSimpleName());
+ throw sce;
+ }
+ }
+
+ if (clientAppTO.getAccessPolicy() == null) {
+ clientAppTO.setAccessPolicy(null);
+ } else {
+ Policy policy = policyDAO.find(clientAppTO.getAccessPolicy());
+ if (policy instanceof AccessPolicy) {
+ try {
+ registeredClientAppTO.setAccessPolicyConf(ImplementationManager.build(((AccessPolicy) policy).
+ getConfigurations().get(0)));
+ } catch (Exception e) {
+ LOG.error("While building {}", ((AccessPolicy) policy).getConfigurations().get(0), e);
+ }
+ } else {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+ sce.getElements().add("Expected " + AccessPolicy.class.getSimpleName()
+ + ", found " + policy.getClass().getSimpleName());
+ throw sce;
+ }
+ }
+
+ if (clientAppTO.getAttrReleasePolicy() == null) {
+ clientAppTO.setAttrReleasePolicy(null);
+ } else {
+ Policy policy = policyDAO.find(clientAppTO.getAttrReleasePolicy());
+ if (policy instanceof AttrReleasePolicy) {
+ try {
+ registeredClientAppTO.setAttrReleasePolicyConf(ImplementationManager.build(
+ ((AttrReleasePolicy) policy).getConfigurations().get(0)));
+ } catch (Exception e) {
+ LOG.error("While building {}", ((AttrReleasePolicy) policy).getConfigurations().get(0), e);
+ }
+
+ } else {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+ sce.getElements().add("Expected " + AttrReleasePolicy.class.getSimpleName()
+ + ", found " + policy.getClass().getSimpleName());
+ throw sce;
+ }
+ }
+
+ return registeredClientAppTO;
+ }
+
+}
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
index 8aa015b..4b65c75 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
@@ -143,7 +143,7 @@ public class PolicyITCase extends AbstractITCase {
DefaultAccessPolicyConf conf = new DefaultAccessPolicyConf();
conf.setEnabled(true);
conf.setName("TestAccessPolicyConf");
- conf.getRequiredAttributes().put("cn", List.of("admin", "Admin", "TheAdmin"));
+ conf.getRequiredAttributes().put("cn", Set.of("admin", "Admin", "TheAdmin"));
implementationTO.setBody(POJOHelper.serialize(conf));
Response response = implementationService.create(implementationTO);
@@ -373,8 +373,8 @@ public class PolicyITCase extends AbstractITCase {
DefaultAccessPolicyConf accessPolicyConf =
POJOHelper.deserialize(accessPolicyImplementationTO.getBody(), DefaultAccessPolicyConf.class);
assertNotNull(accessPolicyConf);
- accessPolicyConf.getRequiredAttributes().put("ou", List.of("test"));
- accessPolicyConf.getRequiredAttributes().put("cn", List.of("admin", "Admin"));
+ accessPolicyConf.getRequiredAttributes().put("ou", Set.of("test"));
+ accessPolicyConf.getRequiredAttributes().put("cn", Set.of("admin", "Admin"));
accessPolicyImplementationTO.setBody(POJOHelper.serialize(accessPolicyConf));
// update new authentication policy
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
index 7c1e252..8a0d9b2 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
@@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
import java.util.UUID;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
@@ -265,7 +266,7 @@ public class RealmITCase extends AbstractITCase {
DefaultAccessPolicyConf ruleConf = new DefaultAccessPolicyConf();
ruleConf.setEnabled(true);
ruleConf.setName("TestAccessPolicyConf" + getUUIDString());
- ruleConf.getRequiredAttributes().put("cn", List.of("admin", "Admin", "TheAdmin"));
+ ruleConf.getRequiredAttributes().put("cn", Set.of("admin", "Admin", "TheAdmin"));
ImplementationTO rule = new ImplementationTO();
rule.setKey("TestAccessPolicy" + getUUIDString());
diff --git a/wa/starter/pom.xml b/wa/starter/pom.xml
index 2e2c7dc..144ddf9 100644
--- a/wa/starter/pom.xml
+++ b/wa/starter/pom.xml
@@ -201,6 +201,16 @@ under the License.
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp-config</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apereo.cas</groupId>
+ <artifactId>cas-server-support-oidc-services</artifactId>
+ <version>6.2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apereo.cas</groupId>
+ <artifactId>cas-server-core-authentication-attributes</artifactId>
+ <version>6.2.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/mapper/RegisteredServiceMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/mapper/RegisteredServiceMapper.java
new file mode 100644
index 0000000..855629f
--- /dev/null
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/mapper/RegisteredServiceMapper.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.wa.mapper;
+
+import java.util.HashSet;
+import org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf;
+import org.apache.syncope.common.lib.to.RegisteredClientAppTO;
+import org.apache.syncope.common.lib.to.client.ClientAppTO;
+import org.apache.syncope.common.lib.to.client.OIDCRPTO;
+import org.apache.syncope.common.lib.to.client.SAML2SPTO;
+import org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy;
+import org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy;
+import org.apereo.cas.services.DenyAllAttributeReleasePolicy;
+import org.apereo.cas.services.OidcRegisteredService;
+import org.apereo.cas.services.RegisteredService;
+import org.apereo.cas.services.RegisteredServiceAccessStrategy;
+import org.apereo.cas.services.RegisteredServiceAttributeReleasePolicy;
+import org.apereo.cas.services.RegisteredServiceAuthenticationPolicy;
+import org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy;
+import org.apereo.cas.support.saml.services.SamlRegisteredService;
+
+public class RegisteredServiceMapper {
+
+ public RegisteredService toRegisteredService(final RegisteredClientAppTO clientApp) {
+
+ RegisteredServiceAuthenticationPolicy authenticationPolicy = new DefaultRegisteredServiceAuthenticationPolicy();
+
+ RegisteredServiceAccessStrategy accessStrategy = new DefaultRegisteredServiceAccessStrategy(
+ clientApp.getAccessPolicyConf().isEnabled(), clientApp.getAccessPolicyConf().isSsoEnabled());
+ accessStrategy.getRequiredAttributes().putAll(clientApp.getAccessPolicyConf().getRequiredAttributes());
+
+ RegisteredServiceAttributeReleasePolicy attributeReleasePolicy;
+ if (clientApp.getAttrReleasePolicyConf() != null
+ && clientApp.getAttrReleasePolicyConf() instanceof AllowedAttrReleasePolicyConf) {
+ attributeReleasePolicy = new ReturnAllowedAttributeReleasePolicy();
+ ((AllowedAttrReleasePolicyConf) clientApp.getAttrReleasePolicyConf()).getAllowedAttributes();
+ ((ReturnAllowedAttributeReleasePolicy) attributeReleasePolicy).getAllowedAttributes().addAll(
+ ((AllowedAttrReleasePolicyConf) clientApp.getAttrReleasePolicyConf()).getAllowedAttributes());
+ } else {
+ attributeReleasePolicy = new DenyAllAttributeReleasePolicy();
+ }
+
+ if (clientApp.getClientAppTO() instanceof OIDCRPTO) {
+ OIDCRPTO rp = (OIDCRPTO) clientApp.getClientAppTO();
+ OidcRegisteredService registeredService = new OidcRegisteredService();
+ registeredService.setServiceId(rp.getKey());
+ registeredService.setName(rp.getName());
+ registeredService.setDescription(rp.getDescription());
+ registeredService.setAccessStrategy(accessStrategy);
+ registeredService.setAuthenticationPolicy(authenticationPolicy);
+ registeredService.setAttributeReleasePolicy(attributeReleasePolicy);
+
+ registeredService.setClientId(rp.getClientId());
+ registeredService.setClientSecret(rp.getClientSecret());
+ registeredService.setSignIdToken(rp.isSignIdToken());
+ registeredService.setJwks(rp.getJwks());
+ registeredService.setSubjectType(rp.getSubjectType().name());
+ registeredService.setSupportedGrantTypes((HashSet<String>) rp.getSupportedGrantTypes());
+ registeredService.setSupportedResponseTypes((HashSet<String>) rp.getSupportedResponseTypes());
+
+ return registeredService;
+ } else if (clientApp.getClientAppTO() instanceof SAML2SPTO) {
+ SAML2SPTO sp = (SAML2SPTO) clientApp.getClientAppTO();
+ SamlRegisteredService registeredService = new SamlRegisteredService();
+ registeredService.setServiceId(sp.getKey());
+ registeredService.setName(sp.getName());
+ registeredService.setDescription(sp.getDescription());
+ registeredService.setAccessStrategy(accessStrategy);
+ registeredService.setAuthenticationPolicy(authenticationPolicy);
+ registeredService.setAttributeReleasePolicy(attributeReleasePolicy);
+
+ registeredService.setIssuerEntityId(sp.getEntityId());
+ registeredService.setMetadataLocation(sp.getMetadataLocation());
+ registeredService.setMetadataSignatureLocation(sp.getMetadataSignatureLocation());
+ registeredService.setSignAssertions(sp.isSignAssertions());
+ registeredService.setSignResponses(sp.isSignResponses());
+ registeredService.setEncryptionOptional(sp.isEncryptionOptional());
+ registeredService.setEncryptAssertions(sp.isEncryptAssertions());
+ registeredService.setRequiredAuthenticationContextClass(sp.getRequiredAuthenticationContextClass());
+ registeredService.setRequiredNameIdFormat(sp.getRequiredNameIdFormat().getNameId());
+ registeredService.setSkewAllowance(sp.getSkewAllowance());
+ registeredService.setNameIdQualifier(sp.getNameIdQualifier());
+ registeredService.setAssertionAudiences(sp.getAssertionAudiences());
+ registeredService.setServiceProviderNameIdQualifier(sp.getServiceProviderNameIdQualifier());
+ return registeredService;
+ }
+ return null;
+ }
+
+ public ClientAppTO fromRegisteredService(final RegisteredService registeredService) {
+ return null;
+ }
+}
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/rest/SyncopeServiceRegistry.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/rest/SyncopeServiceRegistry.java
index 64773eb..2a64794 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/rest/SyncopeServiceRegistry.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/rest/SyncopeServiceRegistry.java
@@ -19,8 +19,10 @@
package org.apache.syncope.wa.starter.rest;
import java.util.Collection;
-import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.common.rest.api.service.RegisteredClientAppService;
import org.apache.syncope.wa.WARestClient;
+import org.apache.syncope.wa.mapper.RegisteredServiceMapper;
import org.apereo.cas.services.AbstractServiceRegistry;
import org.apereo.cas.services.RegisteredService;
import org.apereo.cas.services.ServiceRegistryListener;
@@ -34,11 +36,14 @@ public class SyncopeServiceRegistry extends AbstractServiceRegistry {
private final WARestClient restClient;
+ private final RegisteredServiceMapper mapper;
+
public SyncopeServiceRegistry(final WARestClient restClient,
final ConfigurableApplicationContext applicationContext,
final Collection<ServiceRegistryListener> serviceRegistryListeners) {
super(applicationContext, serviceRegistryListeners);
this.restClient = restClient;
+ this.mapper = new RegisteredServiceMapper();
}
@Override
@@ -54,7 +59,9 @@ public class SyncopeServiceRegistry extends AbstractServiceRegistry {
@Override
public Collection<RegisteredService> load() {
LOG.info("Loading application definitions");
- return List.of();
+
+ return restClient.getSyncopeClient().getService(RegisteredClientAppService.class).list().stream().
+ map(clientApp -> mapper.toRegisteredService(clientApp)).collect(Collectors.toList());
}
@Override