You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2020/04/03 16:13:52 UTC
[syncope] branch SYNCOPE-163-1 updated: [SYNCOPE-163-1] Added
AuthModule REST service
This is an automated email from the ASF dual-hosted git repository.
skylark17 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 39eb21e [SYNCOPE-163-1] Added AuthModule REST service
39eb21e is described below
commit 39eb21e8a74641473202a6549805bf8ded1cfc8c
Author: skylark17 <sk...@apache.org>
AuthorDate: Fri Apr 3 16:19:44 2020 +0200
[SYNCOPE-163-1] Added AuthModule REST service
---
.../common/lib/auth/AbstractAuthModuleConf.java | 34 +-
.../syncope/common/lib/auth/AuthModuleConf.java | 18 +-
.../common/lib/auth/JDBCAuthModuleConf.java | 99 +++++
.../common/lib/auth/LDAPAuthModuleConf.java | 17 +-
.../common/lib/auth/OIDCAuthModuleConf.java | 2 +-
.../common/lib/auth/SAML2IdPAuthModuleConf.java | 4 +-
.../common/lib/auth/StaticAuthModuleConf.java | 8 +-
...hModuleConf.java => SyncopeAuthModuleConf.java} | 47 ++-
.../apache/syncope/common/lib/to/AuthModuleTO.java | 132 +++++++
.../syncope/common/lib/to/client/ClientAppTO.java | 3 +-
.../syncope/common/lib/types/AMEntitlement.java | 20 +-
.../common/lib/types/AMImplementationType.java | 4 -
.../common/lib/types/AuthModuleConfPropSchema.java | 157 --------
.../common/lib/types/AuthModuleConfProperty.java | 100 -----
...lientAppService.java => AuthModuleService.java} | 68 ++--
.../common/rest/api/service/ClientAppService.java | 8 +-
.../apache/syncope/core/logic/AuthModuleLogic.java | 131 +++++++
.../init/ClassPathScanImplementationLookup.java | 14 -
.../rest/cxf/service/AuthModuleServiceImpl.java | 65 ++++
.../persistence/api/dao/auth/AuthModuleDAO.java | 3 -
.../persistence/api/entity/auth/AuthModule.java | 22 +-
.../auth/{AuthModule.java => AuthModuleItem.java} | 13 +-
.../src/test/resources/domains/MasterContent.xml | 23 +-
.../core/persistence/jpa/dao/JPAPolicyDAO.java | 24 +-
.../persistence/jpa/dao/auth/JPAAuthModuleDAO.java | 14 +-
.../persistence/jpa/entity/JPAEntityFactory.java | 6 +-
.../persistence/jpa/entity/auth/JPAAuthModule.java | 77 ++--
.../{JPAAuthModule.java => JPAAuthModuleItem.java} | 64 ++--
.../jpa/entity/policy/JPAAccessPolicy.java | 2 +-
.../jpa/entity/policy/JPAAttrReleasePolicy.java | 2 +-
.../jpa/entity/policy/JPAAuthPolicy.java | 2 +-
.../core/persistence/jpa/inner/AuthModuleTest.java | 331 +++++++++++++----
.../core/persistence/jpa/outer/PolicyTest.java | 7 +-
.../src/test/resources/domains/MasterContent.xml | 27 +-
.../api/data/AuthModuleDataBinder.java} | 27 +-
.../java/data/AuthModuleDataBinderImpl.java | 79 ++++
.../java/data/ConnInstanceDataBinderImpl.java | 4 -
.../java/data/ImplementationDataBinderImpl.java | 14 -
.../org/apache/syncope/fit/AbstractITCase.java | 17 +
.../apache/syncope/fit/core/AuthModuleITCase.java | 406 +++++++++++++++++++++
.../wa/starter/rest/SyncopeServiceRegistry.java | 1 +
41 files changed, 1446 insertions(+), 650 deletions(-)
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AbstractAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AbstractAuthModuleConf.java
index edec434..a4399d6 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AbstractAuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AbstractAuthModuleConf.java
@@ -18,29 +18,20 @@
*/
package org.apache.syncope.common.lib.auth;
-import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import org.apache.syncope.common.lib.to.ItemTO;
@XmlType
-@XmlSeeAlso({ JaasAuthModuleConf.class, StaticAuthModuleConf.class, LDAPAuthModuleConf.class, OIDCAuthModuleConf.class,
- GoogleMfaAuthModuleConf.class, SAML2IdPAuthModuleConf.class })
+@XmlSeeAlso({ JaasAuthModuleConf.class, StaticAuthModuleConf.class, LDAPAuthModuleConf.class,
+ OIDCAuthModuleConf.class, GoogleMfaAuthModuleConf.class, SAML2IdPAuthModuleConf.class, U2FAuthModuleConf.class,
+ JDBCAuthModuleConf.class, SyncopeAuthModuleConf.class, RadiusAuthModuleConf.class })
public abstract class AbstractAuthModuleConf implements Serializable, AuthModuleConf {
private static final long serialVersionUID = 4153200197344709778L;
private String name;
- private int order;
-
- private List<ItemTO> profileItems = new ArrayList<>();
-
public AbstractAuthModuleConf() {
setName(getClass().getName());
}
@@ -54,21 +45,4 @@ public abstract class AbstractAuthModuleConf implements Serializable, AuthModule
this.name = name;
}
- @Override
- public int getOrder() {
- return order;
- }
-
- public void setOrder(final int order) {
- this.order = order;
- }
-
- @XmlElementWrapper(name = "profileItems")
- @XmlElement(name = "profileItem")
- @JsonProperty("profileItems")
- @Override
- public List<ItemTO> getProfileItems() {
- return profileItems;
- }
-
}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java
index 8f8fa4f..28c1357 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java
@@ -20,9 +20,9 @@ package org.apache.syncope.common.lib.auth;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import java.io.Serializable;
-import java.util.List;
-import org.apache.syncope.common.lib.to.ItemTO;
+import javax.xml.bind.annotation.XmlTransient;
+@XmlTransient
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
public interface AuthModuleConf extends Serializable {
@@ -32,18 +32,4 @@ public interface AuthModuleConf extends Serializable {
* @return name of this authentication module instance
*/
String getName();
-
- /**
- * Execution order of this authentication module in the policy chain.
- *
- * @return numeric order
- */
- int getOrder();
-
- /**
- * Specify the mapping items for the attributes fetched from the source.
- *
- * @return list of mapping items
- */
- List<ItemTO> getProfileItems();
}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/JDBCAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/JDBCAuthModuleConf.java
new file mode 100644
index 0000000..0141078
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/JDBCAuthModuleConf.java
@@ -0,0 +1,99 @@
+/*
+ * 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.auth;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "jdbcAuthModuleConf")
+@XmlType
+public class JDBCAuthModuleConf extends AbstractAuthModuleConf {
+
+ private static final long serialVersionUID = 8383233437907219385L;
+
+ /**
+ * SQL query to execute. Example: {@code SELECT * FROM table WHERE name=?}.
+ */
+ private String sql;
+
+ /**
+ * Password field/column name to retrieve.
+ */
+ private String fieldPassword;
+
+ /**
+ * Boolean field that should indicate whether the account is expired.
+ */
+ private String fieldExpired;
+
+ /**
+ * Boolean field that should indicate whether the account is disabled.
+ */
+ private String fieldDisabled;
+
+ /**
+ * List of column names to fetch as user attributes.
+ */
+ private final List<String> principalAttributeList = new ArrayList<>();
+
+ public String getSql() {
+ return sql;
+ }
+
+ public void setSql(final String sql) {
+ this.sql = sql;
+ }
+
+ public String getFieldPassword() {
+ return fieldPassword;
+ }
+
+ public void setFieldPassword(final String fieldPassword) {
+ this.fieldPassword = fieldPassword;
+ }
+
+ public String getFieldExpired() {
+ return fieldExpired;
+ }
+
+ public void setFieldExpired(final String fieldExpired) {
+ this.fieldExpired = fieldExpired;
+ }
+
+ public String getFieldDisabled() {
+ return fieldDisabled;
+ }
+
+ public void setFieldDisabled(final String fieldDisabled) {
+ this.fieldDisabled = fieldDisabled;
+ }
+
+ @XmlElementWrapper(name = "principalAttributeList")
+ @XmlElement(name = "principalAttributeList")
+ @JsonProperty("principalAttributeList")
+ public List<String> getPrincipalAttributeList() {
+ return principalAttributeList;
+ }
+
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/LDAPAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/LDAPAuthModuleConf.java
index b344c6e..afd7f90 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/LDAPAuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/LDAPAuthModuleConf.java
@@ -75,14 +75,6 @@ public class LDAPAuthModuleConf extends AbstractAuthModuleConf {
this.searchFilter = searchFilter;
}
- public String getBaseDn() {
- return baseDn;
- }
-
- public void setBaseDn(final String baseDn) {
- this.baseDn = baseDn;
- }
-
public String getUserIdAttribute() {
return userIdAttribute;
}
@@ -122,4 +114,13 @@ public class LDAPAuthModuleConf extends AbstractAuthModuleConf {
public void setBindCredential(final String bindCredential) {
this.bindCredential = bindCredential;
}
+
+ public String getBaseDn() {
+ return baseDn;
+ }
+
+ public void setBaseDn(final String baseDn) {
+ this.baseDn = baseDn;
+ }
+
}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/OIDCAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/OIDCAuthModuleConf.java
index c56e160..d59b34d 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/OIDCAuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/OIDCAuthModuleConf.java
@@ -19,12 +19,12 @@
package org.apache.syncope.common.lib.auth;
import com.fasterxml.jackson.annotation.JsonProperty;
-import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java
index e3169fd..03b6aed 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java
@@ -19,12 +19,12 @@
package org.apache.syncope.common.lib.auth;
import com.fasterxml.jackson.annotation.JsonProperty;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "saml2IdPAuthModuleConf")
@XmlType
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/StaticAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/StaticAuthModuleConf.java
index 4d2112f..60d2751 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/StaticAuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/StaticAuthModuleConf.java
@@ -19,12 +19,12 @@
package org.apache.syncope.common.lib.auth;
import com.fasterxml.jackson.annotation.JsonProperty;
-import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
@@ -37,12 +37,6 @@ public class StaticAuthModuleConf extends AbstractAuthModuleConf {
@XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
private final Map<String, String> users = new HashMap<>();
- public StaticAuthModuleConf(final Map<String, String> users) {
- setName(getClass().getSimpleName());
- getUsers().clear();
- getUsers().putAll(users);
- }
-
@XmlElementWrapper(name = "users")
@XmlElement(name = "user")
@JsonProperty("users")
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SyncopeAuthModuleConf.java
similarity index 53%
copy from common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java
copy to common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SyncopeAuthModuleConf.java
index 8f8fa4f..2ac2192 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SyncopeAuthModuleConf.java
@@ -18,32 +18,39 @@
*/
package org.apache.syncope.common.lib.auth;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import java.io.Serializable;
-import java.util.List;
-import org.apache.syncope.common.lib.to.ItemTO;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public interface AuthModuleConf extends Serializable {
+@XmlRootElement(name = "syncopeAuthModuleConf")
+@XmlType
+public class SyncopeAuthModuleConf extends AbstractAuthModuleConf {
- /**
- * Given name of related authentication module instance.
- *
- * @return name of this authentication module instance
- */
- String getName();
+ private static final long serialVersionUID = -3334329948161152222L;
/**
- * Execution order of this authentication module in the policy chain.
- *
- * @return numeric order
+ * Syncope domain used for authentication, etc.
*/
- int getOrder();
+ private String domain = "Master";
/**
- * Specify the mapping items for the attributes fetched from the source.
- *
- * @return list of mapping items
+ * Syncope instance URL primary used for REST.
*/
- List<ItemTO> getProfileItems();
+ private String url;
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(final String domain) {
+ this.domain = domain;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(final String url) {
+ this.url = url;
+ }
+
}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java
new file mode 100644
index 0000000..492227f
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java
@@ -0,0 +1,132 @@
+/*
+ * 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 com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.syncope.common.lib.BaseBean;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.auth.AuthModuleConf;
+
+@XmlRootElement(name = "authModule")
+@XmlType
+public class AuthModuleTO extends BaseBean implements EntityTO {
+
+ private static final long serialVersionUID = -7490425997956703057L;
+
+ private String key;
+
+ private String name;
+
+ private String description;
+
+ private final List<ItemTO> profileItems = new ArrayList<>();
+
+ private AuthModuleConf conf;
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(final String description) {
+ this.description = description;
+ }
+
+ public AuthModuleConf getConf() {
+ return conf;
+ }
+
+ public void setConf(final AuthModuleConf conf) {
+ this.conf = conf;
+ }
+
+ @XmlElementWrapper(name = "profileItems")
+ @XmlElement(name = "profileItem")
+ @JsonProperty("profileItems")
+ public List<ItemTO> getProfileItems() {
+ return profileItems;
+ }
+
+ public boolean add(final ItemTO item) {
+ return Optional.ofNullable(item)
+ .filter(itemTO -> this.profileItems.contains(itemTO) || this.profileItems.add(itemTO)).isPresent();
+ }
+
+ public boolean remove(final ItemTO item) {
+ return this.profileItems.remove(item);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ AuthModuleTO other = (AuthModuleTO) obj;
+ return new EqualsBuilder().
+ append(key, other.key).
+ append(name, other.name).
+ append(description, other.description).
+ append(profileItems, other.profileItems).
+ append(conf, other.conf).
+ build();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(key).
+ append(name).
+ append(description).
+ append(profileItems).
+ append(conf).
+ build();
+ }
+
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/client/ClientAppTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/client/ClientAppTO.java
index 5a7b234..b1b4730 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/client/ClientAppTO.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/client/ClientAppTO.java
@@ -33,8 +33,7 @@ import javax.xml.bind.annotation.XmlType;
@XmlType
@XmlSeeAlso({ OIDCRPTO.class, SAML2SPTO.class })
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@class")
-@JsonPropertyOrder(value = { "@class", "key", "name", "description",
- "authPolicy", "accessPolicy", "attReleasePolicy" })
+@JsonPropertyOrder(value = { "@class", "key", "name", "description", "authPolicy", "accessPolicy", "attReleasePolicy" })
@Schema(subTypes = { OIDCRPTO.class, SAML2SPTO.class }, discriminatorProperty = "@class")
public abstract class ClientAppTO extends BaseBean implements EntityTO {
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 16939e6..d20258b 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
@@ -34,16 +34,6 @@ public final class AMEntitlement {
public static final String GATEWAY_ROUTE_PUSH = "GATEWAY_ROUTE_PUSH";
- public static final String AUTHMODULE_READ = "AUTHMODULE_READ";
-
- public static final String AUTHMODULE_LIST = "AUTHMODULE_LIST";
-
- public static final String AUTHMODULE_CREATE = "AUTHMODULE_CREATE";
-
- public static final String AUTHMODULE_UPDATE = "AUTHMODULE_CREATE";
-
- public static final String AUTHMODULE_DELETE = "AUTHMODULE_DELETE";
-
public static final String CLIENTAPP_READ = "CLIENTAPP_READ";
public static final String CLIENTAPP_LIST = "CLIENTAPP_LIST";
@@ -54,6 +44,16 @@ public final class AMEntitlement {
public static final String CLIENTAPP_DELETE = "CLIENTAPP_DELETE";
+ public static final String AUTH_MODULE_LIST = "AUTH_MODULE_LIST";
+
+ public static final String AUTH_MODULE_CREATE = "AUTH_MODULE_CREATE";
+
+ public static final String AUTH_MODULE_READ = "AUTH_MODULE_READ";
+
+ public static final String AUTH_MODULE_UPDATE = "AUTH_MODULE_UPDATE";
+
+ public static final String AUTH_MODULE_DELETE = "AUTH_MODULE_DELETE";
+
private static final Set<String> VALUES;
public static final String REGISTERED_CLIENT_APP_READ = "REGISTERED_CLIENT_APP_READ";
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java
index 6c6be03..1c05727 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java
@@ -23,8 +23,6 @@ import java.util.Map;
public final class AMImplementationType {
- public static final String AUTH_MODULE_CONFIGURATIONS = "AUTH_MODULE_CONFIGURATIONS";
-
public static final String AUTH_POLICY_CONFIGURATIONS = "AUTH_POLICY_CONFIGURATIONS";
public static final String ACCESS_POLICY_CONFIGURATIONS = "ACCESS_POLICY_CONFIGURATIONS";
@@ -36,8 +34,6 @@ public final class AMImplementationType {
}
private static final Map<String, String> VALUES = Map.ofEntries(
- Pair.of(AUTH_MODULE_CONFIGURATIONS,
- "org.apache.syncope.common.lib.auth.AuthModuleConf"),
Pair.of(AUTH_POLICY_CONFIGURATIONS,
"org.apache.syncope.common.lib.policy.AuthPolicyConf"),
Pair.of(ATTR_RELEASE_POLICY_CONFIGURATIONS,
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfPropSchema.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfPropSchema.java
deleted file mode 100644
index 6ff8800..0000000
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfPropSchema.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.types;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
-@XmlRootElement
-@XmlType
-public class AuthModuleConfPropSchema implements Serializable, Comparable<AuthModuleConfPropSchema> {
-
- private static final long serialVersionUID = -1615574676038299363L;
-
- private String name;
-
- private String displayName;
-
- private String helpMessage;
-
- private String type = String.class.getName();
-
- private boolean required;
-
- private int order;
-
- private boolean confidential;
-
- private final List<Object> defaultValues = new ArrayList<>();
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public boolean isRequired() {
- return required;
- }
-
- public void setRequired(final boolean required) {
- this.required = required;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(final String type) {
- this.type = type;
- }
-
- public String getDisplayName() {
- return displayName;
- }
-
- public void setDisplayName(final String displayName) {
- this.displayName = displayName;
- }
-
- public String getHelpMessage() {
- return helpMessage;
- }
-
- public void setHelpMessage(final String helpMessage) {
- this.helpMessage = helpMessage;
- }
-
- public int getOrder() {
- return order;
- }
-
- public void setOrder(final int order) {
- this.order = order;
- }
-
- public boolean isConfidential() {
- return confidential;
- }
-
- public void setConfidential(final boolean confidential) {
- this.confidential = confidential;
- }
-
- @XmlElementWrapper(name = "defaultValues")
- @XmlElement(name = "defaultValue")
- @JsonProperty("defaultValues")
- public List<Object> getDefaultValues() {
- return defaultValues;
- }
-
- @Override
- public int compareTo(final AuthModuleConfPropSchema other) {
- return this.getOrder() > other.getOrder()
- ? 1
- : this.getOrder() < other.getOrder()
- ? -1
- : 0;
- }
-
- @Override
- public int hashCode() {
- return new HashCodeBuilder().
- append(name).
- append(type).
- append(required).
- append(order).
- append(confidential).
- build();
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AuthModuleConfPropSchema other = (AuthModuleConfPropSchema) obj;
- return new EqualsBuilder().
- append(name, other.name).
- append(type, other.type).
- append(required, other.required).
- append(order, other.order).
- append(confidential, other.confidential).
- build();
- }
-}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfProperty.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfProperty.java
deleted file mode 100644
index d3a125f..0000000
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfProperty.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.types;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.commons.lang3.ObjectUtils;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
-@XmlRootElement
-@XmlType
-public class AuthModuleConfProperty implements Serializable, Comparable<AuthModuleConfProperty> {
-
- private static final long serialVersionUID = 7291446596155549328L;
-
- private AuthModuleConfPropSchema schema;
-
- private final List<Object> values = new ArrayList<>();
-
- private boolean overridable;
-
- public AuthModuleConfPropSchema getSchema() {
- return schema;
- }
-
- public void setSchema(final AuthModuleConfPropSchema schema) {
- this.schema = schema;
- }
-
- @XmlElementWrapper(name = "values")
- @XmlElement(name = "value")
- @JsonProperty("values")
- public List<Object> getValues() {
- return values;
- }
-
- public boolean isOverridable() {
- return overridable;
- }
-
- public void setOverridable(final boolean overridable) {
- this.overridable = overridable;
- }
-
- @Override
- public int compareTo(final AuthModuleConfProperty connConfProperty) {
- return ObjectUtils.compare(this.getSchema(), connConfProperty.getSchema());
- }
-
- @Override
- public int hashCode() {
- return new HashCodeBuilder().
- append(schema).
- append(values).
- append(overridable).
- build();
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AuthModuleConfProperty other = (AuthModuleConfProperty) obj;
- return new EqualsBuilder().
- append(schema, other.schema).
- append(values, other.values).
- append(overridable, other.overridable).
- build();
- }
-}
diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuthModuleService.java
similarity index 65%
copy from common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java
copy to common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuthModuleService.java
index 002c5b5..83e6015 100644
--- a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java
+++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuthModuleService.java
@@ -40,57 +40,49 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.client.ClientAppTO;
-import org.apache.syncope.common.lib.types.ClientAppType;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
/**
- * REST operations for applications.
+ * REST operations for authentication modules.
*/
-@Tag(name = "ClientApps")
+@Tag(name = "AuthModules")
@SecurityRequirements({
@SecurityRequirement(name = "BasicAuthentication"),
@SecurityRequirement(name = "Bearer") })
-@Path("clientApps")
-public interface ClientAppService extends JAXRSService {
+@Path("authModules")
+public interface AuthModuleService extends JAXRSService {
/**
- * Returns the client app matching the given key.
+ * Returns the authentication module matching the given key.
*
- * @param type client app type
- * @param key key of requested client app
- * @param <T> response type (extending ClientAppTO)
- * @return client app with matching id
+ * @param key key of requested authentication module
+ * @return authentication module with matching id
*/
@GET
- @Path("{type}/{key}")
+ @Path("{key}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- <T extends ClientAppTO> T read(
- @NotNull @PathParam("type") ClientAppType type,
+ AuthModuleTO read(
@NotNull @PathParam("key") String key);
/**
- * Returns a list of policies of the matching type.
+ * Returns a list of authentication modules of the matching type.
*
- * @param type Type selector for requested policies
- * @param <T> response type (extending ClientAppTO)
- * @return list of policies with matching type
+ * @return list of authentication modules with matching type
*/
@GET
- @Path("{type}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- <T extends ClientAppTO> List<T> list(@NotNull @PathParam("type") ClientAppType type);
+ List<AuthModuleTO> list();
/**
- * Create a new client app.
+ * Create a new authentication module.
*
- * @param type client app type
- * @param clientAppTO ClientApp to be created (needs to match type)
- * @return Response object featuring Location header of created client app
+ * @param authModuleTO AuthModule to be created (needs to match type)
+ * @return Response object featuring Location header of created authentication module
*/
@ApiResponses(
@ApiResponse(responseCode = "201",
- description = "ClientApp successfully created", headers = {
+ description = "AuthModule successfully created", headers = {
@Header(name = RESTHeaders.RESOURCE_KEY, schema =
@Schema(type = "string"),
description = "UUID generated for the entity created"),
@@ -98,37 +90,37 @@ public interface ClientAppService extends JAXRSService {
@Schema(type = "string"),
description = "URL of the entity created") }))
@POST
- @Path("{type}")
@Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- Response create(@NotNull @PathParam("type") ClientAppType type, @NotNull ClientAppTO clientAppTO);
+ Response create(
+ @NotNull AuthModuleTO authModuleTO);
/**
- * Updates client app matching the given key.
+ * Updates authentication module matching the given key.
*
- * @param type client app type
- * @param clientAppTO ClientApp to replace existing client app
+ * @param authModuleTO AuthModule to replace existing authentication module
*/
- @Parameter(name = "key", description = "ClientApp's key", in = ParameterIn.PATH, schema =
+ @Parameter(name = "key", description = "AuthModule's key", in = ParameterIn.PATH, schema =
@Schema(type = "string"))
@ApiResponses(
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@PUT
- @Path("{type}/{key}")
+ @Path("{key}")
@Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- void update(@NotNull @PathParam("type") ClientAppType type, @NotNull ClientAppTO clientAppTO);
+ void update(
+ @NotNull AuthModuleTO authModuleTO);
/**
- * Delete client app matching the given key.
+ * Delete authentication module matching the given key.
*
- * @param type client app type
- * @param key key of client app to be deleted
+ * @param key key of authentication module to be deleted
*/
@ApiResponses(
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
- @Path("{type}/{key}")
+ @Path("{key}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- void delete(@NotNull @PathParam("type") ClientAppType type, @NotNull @PathParam("key") String key);
+ void delete(
+ @NotNull @PathParam("key") String key);
}
diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java
index 002c5b5..c2e2398 100644
--- a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java
+++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ClientAppService.java
@@ -45,7 +45,7 @@ import org.apache.syncope.common.lib.types.ClientAppType;
import org.apache.syncope.common.rest.api.RESTHeaders;
/**
- * REST operations for applications.
+ * REST operations for client applications.
*/
@Tag(name = "ClientApps")
@SecurityRequirements({
@@ -70,11 +70,11 @@ public interface ClientAppService extends JAXRSService {
@NotNull @PathParam("key") String key);
/**
- * Returns a list of policies of the matching type.
+ * Returns a list of client apps of the matching type.
*
- * @param type Type selector for requested policies
+ * @param type Type selector for requested client apps
* @param <T> response type (extending ClientAppTO)
- * @return list of policies with matching type
+ * @return list of client apps with matching type
*/
@GET
@Path("{type}")
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java
new file mode 100644
index 0000000..538dc82
--- /dev/null
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java
@@ -0,0 +1,131 @@
+/*
+ * 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 static org.apache.syncope.core.logic.AbstractLogic.LOG;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
+import org.apache.syncope.common.lib.types.AMEntitlement;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthModuleDAO;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import org.apache.syncope.core.provisioning.api.data.AuthModuleDataBinder;
+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 AuthModuleLogic extends AbstractTransactionalLogic<AuthModuleTO> {
+
+ @Autowired
+ private AuthModuleDataBinder binder;
+
+ @Autowired
+ private AuthModuleDAO authModuleDAO;
+
+ @PreAuthorize("hasRole('" + AMEntitlement.AUTH_MODULE_CREATE + "')")
+ public AuthModuleTO create(final AuthModuleTO authModuleTO) {
+ return binder.getAuthModuleTO(authModuleDAO.save(binder.create(authModuleTO)));
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.AUTH_MODULE_UPDATE + "')")
+ public AuthModuleTO update(final AuthModuleTO authModuleTO) {
+ AuthModule authModule = authModuleDAO.find(authModuleTO.getKey());
+ if (authModule == null) {
+ throw new NotFoundException("AuthModule " + authModuleTO.getKey() + " not found");
+ }
+
+ return binder.getAuthModuleTO(authModuleDAO.save(binder.update(authModule, authModuleTO)));
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.AUTH_MODULE_LIST + "')")
+ @Transactional(readOnly = true)
+ public List<AuthModuleTO> list() {
+ return authModuleDAO.findAll().stream().
+ filter(Objects::nonNull).
+ map(authModule -> {
+ AuthModuleTO result = null;
+ try {
+ result = binder.getAuthModuleTO(authModule);
+ } catch (NotFoundException e) {
+ LOG.error("Authentication module '{}' not found", authModule.getName());
+ }
+
+ return result;
+ }).collect(Collectors.toList());
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.AUTH_MODULE_READ + "')")
+ @Transactional(readOnly = true)
+ public AuthModuleTO read(final String key) {
+ AuthModule authModule = authModuleDAO.find(key);
+ if (authModule == null) {
+ throw new NotFoundException("AuthModule " + key + " not found");
+ }
+
+ return binder.getAuthModuleTO(authModule);
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.AUTH_MODULE_DELETE + "')")
+ public AuthModuleTO delete(final String key) {
+ AuthModule authModule = authModuleDAO.find(key);
+ if (authModule == null) {
+ throw new NotFoundException("AuthModule " + key + " not found");
+ }
+
+ AuthModuleTO deleted = binder.getAuthModuleTO(authModule);
+ authModuleDAO.delete(authModule);
+
+ return deleted;
+ }
+
+ @Override
+ protected AuthModuleTO resolveReference(final Method method, final Object... args)
+ throws UnresolvedReferenceException {
+
+ String key = null;
+
+ if (ArrayUtils.isNotEmpty(args)) {
+ for (int i = 0; key == null && i < args.length; i++) {
+ if (args[i] instanceof String) {
+ key = (String) args[i];
+ } else if (args[i] instanceof AuthModuleTO) {
+ key = ((AuthModuleTO) args[i]).getKey();
+ }
+ }
+ }
+
+ if (key != null) {
+ try {
+ return binder.getAuthModuleTO(authModuleDAO.find(key));
+ } catch (Throwable ignore) {
+ LOG.debug("Unresolved reference", ignore);
+ throw new UnresolvedReferenceException(ignore);
+ }
+ }
+
+ throw new UnresolvedReferenceException();
+ }
+}
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index 07d2efd..e887aef 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -36,7 +36,6 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen
import org.springframework.core.Ordered;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.util.ClassUtils;
-import org.apache.syncope.common.lib.auth.AuthModuleConf;
import org.apache.syncope.common.lib.policy.AuthPolicyConf;
/**
@@ -52,8 +51,6 @@ public class ClassPathScanImplementationLookup implements SyncopeCoreLoader {
private Map<Class<? extends AuthPolicyConf>, Class<? extends AuthPolicyConf>> authPolicyClasses;
- private Map<Class<? extends AuthModuleConf>, Class<? extends AuthModuleConf>> authModuleClasses;
-
private Map<Class<? extends AccessPolicyConf>, Class<? extends AccessPolicyConf>> accessPolicyClasses;
@Override
@@ -86,7 +83,6 @@ public class ClassPathScanImplementationLookup implements SyncopeCoreLoader {
});
authPolicyClasses = new HashMap<>();
- authModuleClasses = new HashMap<>();
accessPolicyClasses = new HashMap<>();
scanner.findCandidateComponents(getBasePackage()).forEach(bd -> {
@@ -98,9 +94,6 @@ public class ClassPathScanImplementationLookup implements SyncopeCoreLoader {
if (AuthPolicyConf.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(AMImplementationType.AUTH_POLICY_CONFIGURATIONS).add(bd.getBeanClassName());
}
- if (AuthModuleConf.class.isAssignableFrom(clazz) && !isAbstractClazz) {
- classNames.get(AMImplementationType.AUTH_MODULE_CONFIGURATIONS).add(bd.getBeanClassName());
- }
if (AccessPolicyConf.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(AMImplementationType.ACCESS_POLICY_CONFIGURATIONS).add(bd.getBeanClassName());
}
@@ -113,7 +106,6 @@ public class ClassPathScanImplementationLookup implements SyncopeCoreLoader {
LOG.debug("Implementation classes found: {}", classNames);
authPolicyClasses = Collections.unmodifiableMap(authPolicyClasses);
- authModuleClasses = Collections.unmodifiableMap(authModuleClasses);
accessPolicyClasses = Collections.unmodifiableMap(accessPolicyClasses);
}
@@ -127,12 +119,6 @@ public class ClassPathScanImplementationLookup implements SyncopeCoreLoader {
return authPolicyClasses.get(authPolicyConfClass);
}
- public Class<? extends AuthModuleConf> getAuthModuleConfClass(
- final Class<? extends AuthModuleConf> authModuleConfClass) {
-
- return authModuleClasses.get(authModuleConfClass);
- }
-
public Class<? extends AccessPolicyConf> getAccessPolicyConfClass(
final Class<? extends AccessPolicyConf> accessPolicyConfClass) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.java
new file mode 100644
index 0000000..68bdd90
--- /dev/null
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.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.core.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AuthModuleService;
+import org.apache.syncope.core.logic.AuthModuleLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AuthModuleServiceImpl extends AbstractServiceImpl implements AuthModuleService {
+
+ @Autowired
+ private AuthModuleLogic logic;
+
+ @Override
+ public Response create(final AuthModuleTO authModuleTO) {
+ AuthModuleTO authModule = logic.create(authModuleTO);
+ URI location = uriInfo.getAbsolutePathBuilder().path(authModule.getKey()).build();
+ return Response.created(location).
+ header(RESTHeaders.RESOURCE_KEY, authModule.getKey()).
+ build();
+ }
+
+ @Override
+ public void delete(final String key) {
+ logic.delete(key);
+ }
+
+ @Override
+ public List<AuthModuleTO> list() {
+ return logic.list();
+ }
+
+ @Override
+ public AuthModuleTO read(final String key) {
+ return logic.read(key);
+ }
+
+ @Override
+ public void update(final AuthModuleTO authModuleTO) {
+ logic.update(authModuleTO);
+ }
+}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/auth/AuthModuleDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/auth/AuthModuleDAO.java
index fcd1f90..fc5e18c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/auth/AuthModuleDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/auth/AuthModuleDAO.java
@@ -19,7 +19,6 @@
package org.apache.syncope.core.persistence.api.dao.auth;
import org.apache.syncope.core.persistence.api.dao.DAO;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
import java.util.List;
import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
@@ -35,6 +34,4 @@ public interface AuthModuleDAO extends DAO<AuthModule> {
void delete(AuthModule authModule);
- List<AuthModule> findByConfiguration(Implementation configuration);
-
}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java
index 68c5669..5d2393e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java
@@ -18,9 +18,10 @@
*/
package org.apache.syncope.core.persistence.api.entity.auth;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
import java.util.List;
+import org.apache.syncope.common.lib.auth.AuthModuleConf;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
public interface AuthModule extends Entity {
@@ -28,7 +29,20 @@ public interface AuthModule extends Entity {
void setName(String name);
- List<? extends Implementation> getConfigurations();
+ String getDescription();
+
+ void setDescription(String description);
+
+ /**
+ * Specify the mapping items for the attributes fetched from the source.
+ *
+ * @return list of mapping items
+ */
+ List<? extends Item> getProfileItems();
+
+ boolean add(Item profileItem);
+
+ AuthModuleConf getConf();
- boolean add(Implementation configuration);
+ void setConf(AuthModuleConf description);
}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModuleItem.java
similarity index 70%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java
copy to core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModuleItem.java
index 68c5669..9f249e4 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModule.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/auth/AuthModuleItem.java
@@ -18,17 +18,8 @@
*/
package org.apache.syncope.core.persistence.api.entity.auth;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
-public interface AuthModule extends Entity {
+public interface AuthModuleItem extends Item {
- String getName();
-
- void setName(String name);
-
- List<? extends Implementation> getConfigurations();
-
- boolean add(Implementation configuration);
}
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index be9293a..8e82492 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -49,7 +49,6 @@ under the License.
body='{"@class":"org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf","authModules":["LdapAuthenticationTest"]}'/>
<AuthPolicy id="659b9906-4b6e-4bc0-aca0-6809dff346d4" name="MyDefaultAuthPolicyConf" description="an authentication policy"/>
<AuthPolicy id="b912a0d4-a890-416f-9ab8-84ab077eb028" name="DefaultAuthPolicy" description="Default authentication policy"/>
- <AuthModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultAuthModule"/>
<!-- access policies -->
<Implementation id="MyDefaultAccessPolicyConf" type="ACCESS_POLICY_CONFIGURATIONS" engine="JAVA"
@@ -65,6 +64,28 @@ under the License.
body='{"@class":"org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf","name":"DenyAttrReleasePolicyConf"}'/>
<AttrReleasePolicy id="219935c7-deb3-40b3-8a9a-683037e523a2" name="DenyAttrReleasePolicy" description="deny attribute release policy policy"/>
+ <!-- Authentication modules -->
+ <AuthModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultLDAPAuthModule"
+ description="LDAP auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","name":"MyLDAPAuthModuleConf","userIdAttribute":"uid","bindCredential":"Password","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"dc=example,dc=org","subtreeSearch":true}'/>
+ <AuthModule id="4c3ed7e8-7008-11ea-bc55-0242ac130003" name="DefaultJDBCAuthModule"
+ description="JDBC auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.JDBCAuthModuleConf","name":"MyJDBCAuthModuleConf", "sql":"SELECT * FROM table WHERE name=?"}'/>
+ <AuthModule id="4c3ed4e6-7008-11ea-bc55-0242ac130003" name="DefaultGoogleMfaAuthModule"
+ description="Google Mfa auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf","name":"MyGoogleMfaAuthModuleConf","codeDigits":6,"issuer":"SyncopeTest"}'/>
+ <AuthModule id="4c3ed8f6-7008-11ea-bc55-0242ac130003" name="DefaultOIDCAuthModule"
+ description="OIDC auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.OIDCAuthModuleConf","name":"MyOIDCAuthModuleConf", "discoveryUri":"www.testurl.com"}'/>
+ <AuthModule id="4c3ed9d2-7008-11ea-bc55-0242ac130003" name="DefaultSAML2IdPAuthModule"
+ description="SAML2 IdP auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf","name":"MySAML2IdPAuthModuleConf", "providerName":"testProviderName","serviceProviderMetadataPath":"file:/etc/metadata"}'/>
+ <AuthModule id="4c3edbbc-7008-11ea-bc55-0242ac130003" name="DefaultJaasAuthModule"
+ description="Jaas auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.JaasAuthModuleConf","name":"MyJaasAuthModuleConf","realm":"SYNCOPE","kerberosRealmSystemProperty":"sample-value"}'/>
+ <AuthModule id="4c3edc98-7008-11ea-bc55-0242ac130003" name="DefaultStaticAuthModule"
+ description="Static auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.StaticAuthModuleConf","name":"MyStaticAuthModuleConf","users":{"user1": "testUserPassword123"}}'/>
+ <AuthModule id="4c3edd60-7008-11ea-bc55-0242ac130003" name="DefaultSyncopeAuthModule"
+ description="Syncope auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf","name":"MySyncopeAuthModuleConf","domain":"Master","url":"http://mydomain.com/syncope/rest"}'/>
+ <AuthModule id="07c528f3-63b4-4dc1-a4da-87f35b8bdec8" name="DefaultRadiusAuthModule"
+ description="Radius auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.RadiusAuthModuleConf","name":"MyRadiusAuthModuleConf","protocol":"MSCHAPv2","inetAddress":"1.2.3.4", "sharedSecret":"thesecret"}'/>
+ <AuthModule id="f6e1288d-50d9-45fe-82ee-597c42242205" name="DefaultU2FAuthModule"
+ description="U2F auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.U2FAuthModuleConf","name":"MyU2FAuthModuleConf","expireDevices":40}'/>
+
<RelationshipType id="inclusion" description="Models the act that an object is included in another"/>
<RelationshipType id="neighborhood" description="Models the act that an object is near another"/>
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
index e305918..abd4dd3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
@@ -121,29 +121,27 @@ public class JPAPolicyDAO extends AbstractDAO<Policy> implements PolicyDAO {
}
@Override
- public List<AuthPolicy> findByAuthPolicy(final Implementation policy) {
+ public List<AuthPolicy> findByAuthPolicy(final Implementation conf) {
TypedQuery<AuthPolicy> query = entityManager().createQuery("SELECT e FROM " + JPAAuthPolicy.class.
- getSimpleName() + " e "
- + "WHERE :authPolicy MEMBER OF e.rules", AuthPolicy.class);
- query.setParameter("authPolicy", policy);
+ getSimpleName() + " e WHERE :authPolicy MEMBER OF e.configurations", AuthPolicy.class);
+ query.setParameter("authPolicy", conf);
return query.getResultList();
}
@Override
- public List<AccessPolicy> findByAccessPolicy(final Implementation policy) {
+ public List<AccessPolicy> findByAccessPolicy(final Implementation conf) {
TypedQuery<AccessPolicy> query = entityManager().createQuery("SELECT e FROM " + JPAAuthPolicy.class.
- getSimpleName() + " e "
- + "WHERE :accessPolicy MEMBER OF e.rules", AccessPolicy.class);
- query.setParameter("accessPolicy", policy);
+ getSimpleName() + " e WHERE :accessPolicy MEMBER OF e.configurations", AccessPolicy.class);
+ query.setParameter("accessPolicy", conf);
return query.getResultList();
}
@Override
- public List<AttrReleasePolicy> findByAttrReleasePolicy(final Implementation policy) {
- TypedQuery<AttrReleasePolicy> query = entityManager().createQuery(
- "SELECT e FROM " + JPAAttrReleasePolicy.class.getSimpleName() + " e "
- + "WHERE :attrReleasePolicy MEMBER OF e.rules", AttrReleasePolicy.class);
- query.setParameter("attrReleasePolicy", policy);
+ public List<AttrReleasePolicy> findByAttrReleasePolicy(final Implementation conf) {
+ TypedQuery<AttrReleasePolicy> query = entityManager().createQuery("SELECT e FROM "
+ + JPAAttrReleasePolicy.class.getSimpleName() + " e WHERE :attrReleasePolicy MEMBER OF e.configurations",
+ AttrReleasePolicy.class);
+ query.setParameter("attrReleasePolicy", conf);
return query.getResultList();
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/auth/JPAAuthModuleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/auth/JPAAuthModuleDAO.java
index bd21ef5..dd765ad 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/auth/JPAAuthModuleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/auth/JPAAuthModuleDAO.java
@@ -18,15 +18,14 @@
*/
package org.apache.syncope.core.persistence.jpa.dao.auth;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
import org.apache.syncope.core.persistence.jpa.dao.AbstractDAO;
-import org.apache.syncope.core.persistence.jpa.entity.auth.JPAAuthModule;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.TypedQuery;
import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
import org.apache.syncope.core.persistence.api.dao.auth.AuthModuleDAO;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import org.apache.syncope.core.persistence.jpa.entity.auth.JPAAuthModule;
@Repository
public class JPAAuthModuleDAO extends AbstractDAO<AuthModule> implements AuthModuleDAO {
@@ -47,15 +46,6 @@ public class JPAAuthModuleDAO extends AbstractDAO<AuthModule> implements AuthMod
@Transactional(readOnly = true)
@Override
- public List<AuthModule> findByConfiguration(final Implementation configuration) {
- TypedQuery<AuthModule> query = entityManager().createQuery("SELECT e FROM " + JPAAuthModule.class.
- getSimpleName() + " e "
- + "WHERE :configuration MEMBER OF e.configurations", AuthModule.class);
- query.setParameter("configuration", configuration);
- return query.getResultList();
- }
-
- @Override
public AuthModule save(final AuthModule authModule) {
return entityManager().merge(authModule);
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index e625cad..a034449 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -57,6 +57,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModuleItem;
import org.apache.syncope.core.persistence.api.entity.auth.OIDCRP;
import org.apache.syncope.core.persistence.api.entity.auth.SAML2SP;
import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
@@ -108,7 +109,6 @@ import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUni
import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue;
import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
-import org.apache.syncope.core.persistence.jpa.entity.auth.JPAAuthModule;
import org.apache.syncope.core.persistence.jpa.entity.auth.JPAOIDCRP;
import org.apache.syncope.core.persistence.jpa.entity.auth.JPASAML2SP;
import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
@@ -153,6 +153,8 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
import org.apache.syncope.core.spring.security.SecureRandomUtils;
+import org.apache.syncope.core.persistence.jpa.entity.auth.JPAAuthModule;
+import org.apache.syncope.core.persistence.jpa.entity.auth.JPAAuthModuleItem;
public class JPAEntityFactory implements EntityFactory {
@@ -307,6 +309,8 @@ public class JPAEntityFactory implements EntityFactory {
result = (E) new JPAGatewayRoute();
} else if (reference.equals(AuthModule.class)) {
result = (E) new JPAAuthModule();
+ } else if (reference.equals(AuthModuleItem.class)) {
+ result = (E) new JPAAuthModuleItem();
} else if (reference.equals(AuthPolicy.class)) {
result = (E) new JPAAuthPolicy();
} else if (reference.equals(AccessPolicy.class)) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java
index 2a91d09..e2b6586 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java
@@ -18,22 +18,21 @@
*/
package org.apache.syncope.core.persistence.jpa.entity.auth;
-import org.apache.syncope.common.lib.types.AMImplementationType;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
-import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
-
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
+import javax.persistence.Lob;
+import javax.persistence.OneToMany;
import javax.persistence.Table;
-
-import java.util.ArrayList;
-import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.auth.AuthModuleConf;
import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@Entity
@Table(name = JPAAuthModule.TABLE)
@@ -41,18 +40,29 @@ public class JPAAuthModule extends AbstractGeneratedKeyEntity implements AuthMod
public static final String TABLE = "AuthModule";
- private static final long serialVersionUID = 7422422526695279794L;
+ private static final long serialVersionUID = 5681033638234853077L;
@Column(unique = true, nullable = false)
private String name;
- @ManyToMany(fetch = FetchType.EAGER)
- @JoinTable(name = TABLE + "Conf",
- joinColumns =
- @JoinColumn(name = "authentication_module_id"),
- inverseJoinColumns =
- @JoinColumn(name = "implementation_id"))
- private List<JPAImplementation> configurations = new ArrayList<>();
+ @Column(nullable = false)
+ private String description;
+
+ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
+ private final List<JPAAuthModuleItem> profileItems = new ArrayList<>();
+
+ @Lob
+ private String jsonConf;
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public void setDescription(final String description) {
+ this.description = description;
+ }
@Override
public String getName() {
@@ -65,15 +75,30 @@ public class JPAAuthModule extends AbstractGeneratedKeyEntity implements AuthMod
}
@Override
- public List<? extends Implementation> getConfigurations() {
- return configurations;
+ public List<? extends Item> getProfileItems() {
+ return profileItems;
+ }
+
+ @Override
+ public boolean add(final Item profileItem) {
+ checkType(profileItem, JPAAuthModuleItem.class);
+ return profileItems.contains((JPAAuthModuleItem) profileItem)
+ || profileItems.add((JPAAuthModuleItem) profileItem);
+ }
+
+ @Override
+ public AuthModuleConf getConf() {
+ AuthModuleConf conf = null;
+ if (!StringUtils.isBlank(jsonConf)) {
+ conf = POJOHelper.deserialize(jsonConf, AuthModuleConf.class);
+ }
+
+ return conf;
}
@Override
- public boolean add(final Implementation configuration) {
- checkType(configuration, JPAImplementation.class);
- checkImplementationType(configuration, AMImplementationType.AUTH_MODULE_CONFIGURATIONS);
- return configurations.contains((JPAImplementation) configuration)
- || configurations.add((JPAImplementation) configuration);
+ public void setConf(final AuthModuleConf conf) {
+ jsonConf = POJOHelper.serialize(conf);
}
+
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModuleItem.java
similarity index 52%
copy from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java
copy to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModuleItem.java
index 2a91d09..bc92d49 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAAuthModuleItem.java
@@ -18,62 +18,52 @@
*/
package org.apache.syncope.core.persistence.jpa.entity.auth;
-import org.apache.syncope.common.lib.types.AMImplementationType;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
-import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
-
-import javax.persistence.Column;
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.common.lib.types.IdMImplementationType;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModuleItem;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractItem;
@Entity
-@Table(name = JPAAuthModule.TABLE)
-public class JPAAuthModule extends AbstractGeneratedKeyEntity implements AuthModule {
+@Table(name = JPAAuthModuleItem.TABLE)
+@Cacheable
+public class JPAAuthModuleItem extends AbstractItem implements AuthModuleItem {
- public static final String TABLE = "AuthModule";
+ public static final String TABLE = "AuthModuleItem";
- private static final long serialVersionUID = 7422422526695279794L;
-
- @Column(unique = true, nullable = false)
- private String name;
+ private static final long serialVersionUID = 3165440920144995781L;
@ManyToMany(fetch = FetchType.EAGER)
- @JoinTable(name = TABLE + "Conf",
+ @JoinTable(name = TABLE + "Transformer",
joinColumns =
- @JoinColumn(name = "authentication_module_id"),
+ @JoinColumn(name = "item_id"),
inverseJoinColumns =
- @JoinColumn(name = "implementation_id"))
- private List<JPAImplementation> configurations = new ArrayList<>();
-
- @Override
- public String getName() {
- return name;
- }
+ @JoinColumn(name = "implementation_id"),
+ uniqueConstraints =
+ @UniqueConstraint(columnNames = { "item_id", "implementation_id" }))
+ private final List<JPAImplementation> transformers = new ArrayList<>();
@Override
- public void setName(final String name) {
- this.name = name;
+ public boolean add(final Implementation transformer) {
+ checkType(transformer, JPAImplementation.class);
+ checkImplementationType(transformer, IdMImplementationType.ITEM_TRANSFORMER);
+ return transformers.contains((JPAImplementation) transformer)
+ || this.transformers.add((JPAImplementation) transformer);
}
@Override
- public List<? extends Implementation> getConfigurations() {
- return configurations;
+ public List<? extends Implementation> getTransformers() {
+ return transformers;
}
- @Override
- public boolean add(final Implementation configuration) {
- checkType(configuration, JPAImplementation.class);
- checkImplementationType(configuration, AMImplementationType.AUTH_MODULE_CONFIGURATIONS);
- return configurations.contains((JPAImplementation) configuration)
- || configurations.add((JPAImplementation) configuration);
- }
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
index 97add50..621bc1a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
@@ -54,7 +54,7 @@ public class JPAAccessPolicy extends AbstractPolicy implements AccessPolicy {
@JoinColumn(name = "implementation_id"),
uniqueConstraints =
@UniqueConstraint(columnNames = { "access_policy_id", "implementation_id" }))
- private List<JPAImplementation> configurations = new ArrayList<>();
+ private final List<JPAImplementation> configurations = new ArrayList<>();
@Override
public String getName() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAttrReleasePolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAttrReleasePolicy.java
index 412b968..92a125a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAttrReleasePolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAttrReleasePolicy.java
@@ -54,7 +54,7 @@ public class JPAAttrReleasePolicy extends AbstractPolicy implements AttrReleaseP
@JoinColumn(name = "implementation_id"),
uniqueConstraints =
@UniqueConstraint(columnNames = { "attr_release_policy_id", "implementation_id" }))
- private List<JPAImplementation> configurations = new ArrayList<>();
+ private final List<JPAImplementation> configurations = new ArrayList<>();
@Override
public String getName() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthPolicy.java
index 553c40c..cdf3f97 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthPolicy.java
@@ -54,7 +54,7 @@ public class JPAAuthPolicy extends AbstractPolicy implements AuthPolicy {
@JoinColumn(name = "implementation_id"),
uniqueConstraints =
@UniqueConstraint(columnNames = { "authentication_policy_id", "implementation_id" }))
- private List<JPAImplementation> configurations = new ArrayList<>();
+ private final List<JPAImplementation> configurations = new ArrayList<>();
@Override
public String getName() {
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java
index 780a9b0..0b198fa 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java
@@ -19,30 +19,32 @@
package org.apache.syncope.core.persistence.jpa.inner;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
-import java.util.Map;
import java.util.UUID;
+import org.apache.commons.lang3.ClassUtils;
import org.apache.syncope.common.lib.auth.AuthModuleConf;
import org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf;
+import org.apache.syncope.common.lib.auth.JDBCAuthModuleConf;
import org.apache.syncope.common.lib.auth.JaasAuthModuleConf;
import org.apache.syncope.common.lib.auth.LDAPAuthModuleConf;
import org.apache.syncope.common.lib.auth.OIDCAuthModuleConf;
+import org.apache.syncope.common.lib.auth.RadiusAuthModuleConf;
+import org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf;
import org.apache.syncope.common.lib.auth.StaticAuthModuleConf;
-import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.types.AMImplementationType;
-import org.apache.syncope.common.lib.types.ImplementationEngine;
-import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf;
+import org.apache.syncope.common.lib.auth.U2FAuthModuleConf;
import org.apache.syncope.core.persistence.api.dao.auth.AuthModuleDAO;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModuleItem;
@Transactional("Master")
public class AuthModuleTest extends AbstractTest {
@@ -50,37 +52,146 @@ public class AuthModuleTest extends AbstractTest {
@Autowired
private AuthModuleDAO authModuleDAO;
- @Autowired
- private ImplementationDAO implementationDAO;
-
@Test
public void find() {
- AuthModule module = authModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
- assertNotNull(module);
+ AuthModule authModule = authModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3ed8f6-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3edbbc-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3ed7e8-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3ed4e6-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3edc98-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3ed9d2-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("4c3edd60-7008-11ea-bc55-0242ac130003");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("07c528f3-63b4-4dc1-a4da-87f35b8bdec8");
+ assertNotNull(authModule);
+
+ authModule = authModuleDAO.find("f6e1288d-50d9-45fe-82ee-597c42242205");
+ assertNotNull(authModule);
- module = authModuleDAO.find(UUID.randomUUID().toString());
- assertNull(module);
+ authModule = authModuleDAO.find(UUID.randomUUID().toString());
+ assertNull(authModule);
}
@Test
public void findAll() {
List<AuthModule> modules = authModuleDAO.findAll();
assertNotNull(modules);
- assertEquals(1, modules.size());
+ assertFalse(modules.isEmpty());
+ assertTrue(modules.size() >= 10);
}
@Test
- public void saveWithPredefinedModule() {
- StaticAuthModuleConf conf = new StaticAuthModuleConf(Map.of("user", UUID.randomUUID().toString()));
-
- Implementation config = getImplementation(conf);
+ public void findByAuthModuleImpl() {
+ AuthModule ldapAuthModule = authModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
+ assertNotNull(ldapAuthModule);
+ AuthModule jdbcAuthModule = authModuleDAO.find("4c3ed7e8-7008-11ea-bc55-0242ac130003");
+ assertNotNull(jdbcAuthModule);
+ AuthModule googleMfaAuthModule = authModuleDAO.find("4c3ed4e6-7008-11ea-bc55-0242ac130003");
+ assertNotNull(googleMfaAuthModule);
+ AuthModule oidcAuthModule = authModuleDAO.find("4c3ed8f6-7008-11ea-bc55-0242ac130003");
+ assertNotNull(oidcAuthModule);
+ AuthModule saml2IdPAuthModule = authModuleDAO.find("4c3ed9d2-7008-11ea-bc55-0242ac130003");
+ assertNotNull(saml2IdPAuthModule);
+ AuthModule jaasAuthModule = authModuleDAO.find("4c3edbbc-7008-11ea-bc55-0242ac130003");
+ assertNotNull(jaasAuthModule);
+ AuthModule staticAuthModule = authModuleDAO.find("4c3edc98-7008-11ea-bc55-0242ac130003");
+ assertNotNull(staticAuthModule);
+ AuthModule syncopeAuthModule = authModuleDAO.find("4c3edd60-7008-11ea-bc55-0242ac130003");
+ assertNotNull(syncopeAuthModule);
+ AuthModule radiusAuthModule = authModuleDAO.find("07c528f3-63b4-4dc1-a4da-87f35b8bdec8");
+ assertNotNull(radiusAuthModule);
+ AuthModule u2fAuthModule = authModuleDAO.find("f6e1288d-50d9-45fe-82ee-597c42242205");
+ assertNotNull(u2fAuthModule);
+
+ assertTrue(isSpecificConf(ldapAuthModule.getConf(), LDAPAuthModuleConf.class));
+ assertFalse(isSpecificConf(ldapAuthModule.getConf(), JDBCAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(jdbcAuthModule.getConf(), JDBCAuthModuleConf.class));
+ assertFalse(isSpecificConf(jdbcAuthModule.getConf(), GoogleMfaAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(googleMfaAuthModule.getConf(), GoogleMfaAuthModuleConf.class));
+ assertFalse(isSpecificConf(googleMfaAuthModule.getConf(), OIDCAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(oidcAuthModule.getConf(), OIDCAuthModuleConf.class));
+ assertFalse(isSpecificConf(oidcAuthModule.getConf(), SAML2IdPAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(saml2IdPAuthModule.getConf(), SAML2IdPAuthModuleConf.class));
+ assertFalse(isSpecificConf(saml2IdPAuthModule.getConf(), JaasAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(jaasAuthModule.getConf(), JaasAuthModuleConf.class));
+ assertFalse(isSpecificConf(jaasAuthModule.getConf(), StaticAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(staticAuthModule.getConf(), StaticAuthModuleConf.class));
+ assertFalse(isSpecificConf(staticAuthModule.getConf(), SyncopeAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(syncopeAuthModule.getConf(), SyncopeAuthModuleConf.class));
+ assertFalse(isSpecificConf(syncopeAuthModule.getConf(), RadiusAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(radiusAuthModule.getConf(), RadiusAuthModuleConf.class));
+ assertFalse(isSpecificConf(radiusAuthModule.getConf(), U2FAuthModuleConf.class));
+
+ assertTrue(isSpecificConf(u2fAuthModule.getConf(), U2FAuthModuleConf.class));
+ assertFalse(isSpecificConf(u2fAuthModule.getConf(), LDAPAuthModuleConf.class));
+ }
- config = implementationDAO.save(config);
+ @Test
+ public void findByType() {
+ List<AuthModule> authModules = authModuleDAO.findAll();
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), LDAPAuthModuleConf.class)
+ && authModule.getName().equals("DefaultLDAPAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), JDBCAuthModuleConf.class)
+ && authModule.getName().equals("DefaultJDBCAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), GoogleMfaAuthModuleConf.class)
+ && authModule.getName().equals("DefaultGoogleMfaAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), OIDCAuthModuleConf.class)
+ && authModule.getName().equals("DefaultOIDCAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), SAML2IdPAuthModuleConf.class)
+ && authModule.getName().equals("DefaultSAML2IdPAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), JaasAuthModuleConf.class)
+ && authModule.getName().equals("DefaultJaasAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), StaticAuthModuleConf.class)
+ && authModule.getName().equals("DefaultStaticAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), SyncopeAuthModuleConf.class)
+ && authModule.getName().equals("DefaultSyncopeAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), RadiusAuthModuleConf.class)
+ && authModule.getName().equals("DefaultRadiusAuthModule")));
+ assertTrue(authModules.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), U2FAuthModuleConf.class)
+ && authModule.getName().equals("DefaultU2FAuthModule")));
+ }
- assertNotNull(config);
- assertNotNull(config.getKey());
+ @Test
+ public void saveWithStaticModule() {
+ StaticAuthModuleConf conf = new StaticAuthModuleConf();
+ conf.getUsers().put("user1", UUID.randomUUID().toString());
+ conf.getUsers().put("user2", "user2Password123");
- saveAuthModule(config, "AuthModulePredefinedTest");
+ saveAuthModule("StaticAuthModuleTest", conf);
}
@Test
@@ -91,14 +202,8 @@ public class AuthModuleTest extends AbstractTest {
conf.setLoginConfigType("JavaLoginConfig");
conf.setRealm("SYNCOPE");
conf.setLoginConfigurationFile("/opt/jaas/login.conf");
- Implementation config = getImplementation(conf);
- config = implementationDAO.save(config);
-
- assertNotNull(config);
- assertNotNull(config.getKey());
-
- saveAuthModule(config, "AuthModuleJaasTest");
+ saveAuthModule("JaasAuthModuleTest", conf);
}
@Test
@@ -109,23 +214,9 @@ public class AuthModuleTest extends AbstractTest {
conf.setSubtreeSearch(true);
conf.setLdapUrl("ldap://localhost:1389");
conf.setUserIdAttribute("uid");
- conf.setBaseDn("cn=Directory Manager,dc=example,dc=org");
conf.setBindCredential("Password");
- ItemTO keyMapping = new ItemTO();
- keyMapping.setIntAttrName("uid");
- keyMapping.setExtAttrName("username");
- ItemTO fullnameMapping = new ItemTO();
- fullnameMapping.setIntAttrName("cn");
- fullnameMapping.setExtAttrName("fullname");
- conf.getProfileItems().addAll(List.of(fullnameMapping, keyMapping));
- Implementation config = getImplementation(conf);
- config = implementationDAO.save(config);
-
- assertNotNull(config);
- assertNotNull(config.getKey());
-
- saveAuthModule(config, "AuthModuleLdapTest");
+ saveAuthModule("LDAPAuthModuleTest", conf);
}
@Test
@@ -136,14 +227,8 @@ public class AuthModuleTest extends AbstractTest {
conf.setLabel("Syncope");
conf.setTimeStepSize(30);
conf.setWindowSize(3);
- Implementation config = getImplementation(conf);
-
- config = implementationDAO.save(config);
- assertNotNull(config);
- assertNotNull(config.getKey());
-
- saveAuthModule(config, "AuthModuleGoogleTest");
+ saveAuthModule("GoogleMfaAuthModuleTest", conf);
}
@Test
@@ -154,49 +239,135 @@ public class AuthModuleTest extends AbstractTest {
conf.setUserIdAttribute("username");
conf.setResponseType("code");
conf.setScope("openid email profile");
- ItemTO keyMapping = new ItemTO();
- keyMapping.setIntAttrName("uid");
- keyMapping.setExtAttrName("username");
- conf.getProfileItems().add(keyMapping);
- Implementation config = getImplementation(conf);
- config = implementationDAO.save(config);
+ saveAuthModule("OIDCAuthModuleTest", conf);
+ }
- assertNotNull(config);
- assertNotNull(config.getKey());
+ @Test
+ public void saveWithJDBCModule() {
+ JDBCAuthModuleConf conf = new JDBCAuthModuleConf();
+ conf.setSql("SELECT * FROM table WHERE name=?");
+ conf.setFieldPassword("password");
+ conf.getPrincipalAttributeList().addAll(List.of("sn", "cn:commonName", "givenName"));
- saveAuthModule(config, "AuthModuleOIDCTest");
+ saveAuthModule("JDBCAuthModuleTest", conf);
}
- private void saveAuthModule(final Implementation config, final String name) {
- AuthModule module = entityFactory.newEntity(AuthModule.class);
- module.setName(name);
- module.add(config);
- authModuleDAO.save(module);
+ @Test
+ public void saveWithSyncopeModule() {
+ SyncopeAuthModuleConf conf = new SyncopeAuthModuleConf();
+ conf.setDomain("Master");
+ conf.setUrl("http://mydomain.com/syncope/rest");
+
+ saveAuthModule("SyncopeAuthModuleTest", conf);
+ }
+ @Test
+ public void saveWithSAML2IdPModule() {
+ SAML2IdPAuthModuleConf conf = new SAML2IdPAuthModuleConf();
+ conf.setServiceProviderEntityId("testEntityId");
+ conf.setProviderName("testProviderName");
+ conf.setServiceProviderMetadataPath("file:/etc/metadata");
+
+ saveAuthModule("SAML2IdPAuthModuleTest", conf);
+ }
+
+ @Test
+ public void saveWithRadiusModule() {
+ RadiusAuthModuleConf conf = new RadiusAuthModuleConf();
+ conf.setProtocol("MSCHAPv2");
+ conf.setInetAddress("1.2.3.4");
+ conf.setSharedSecret("xyz");
+ conf.setSocketTimeout(40);
+
+ saveAuthModule("RadiusAuthModuleTest", conf);
+ }
+
+ @Test
+ public void saveWithU2FModule() {
+ U2FAuthModuleConf conf = new U2FAuthModuleConf();
+ conf.setExpireDevices(50);
+
+ saveAuthModule("U2FAuthModuleTest", conf);
+ }
+
+ @Test
+ public void updateWithLDAPModule() {
+ AuthModule module = authModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
assertNotNull(module);
- assertNotNull(module.getKey());
+ AuthModuleConf conf = module.getConf();
+ LDAPAuthModuleConf.class.cast(conf).setBaseDn("dc=example2,dc=org");
+ LDAPAuthModuleConf.class.cast(conf).setSearchFilter("cn={user2}");
+ module.setConf(conf);
- assertNotNull(authModuleDAO.find(module.getKey()));
+ module = authModuleDAO.save(module);
+ assertNotNull(module);
+ assertNotNull(module.getKey());
+ AuthModule found = authModuleDAO.find(module.getKey());
+ assertNotNull(found);
+ assertEquals("dc=example2,dc=org", LDAPAuthModuleConf.class.cast(found.getConf()).getBaseDn());
+ assertEquals("cn={user2}", LDAPAuthModuleConf.class.cast(found.getConf()).getSearchFilter());
}
- private Implementation getImplementation(final AuthModuleConf conf) {
- Implementation config = entityFactory.newEntity(Implementation.class);
- config.setKey(UUID.randomUUID().toString());
- config.setEngine(ImplementationEngine.JAVA);
- config.setType(AMImplementationType.AUTH_MODULE_CONFIGURATIONS);
- config.setBody(POJOHelper.serialize(conf));
- return config;
+ @Test
+ public void updateWithJDBCModule() {
+ AuthModule module = authModuleDAO.find("4c3ed7e8-7008-11ea-bc55-0242ac130003");
+ assertNotNull(module);
+ AuthModuleConf conf = module.getConf();
+ JDBCAuthModuleConf.class.cast(conf).setSql("SELECT * FROM otherTable WHERE name=?");
+ module.setConf(conf);
+
+ module = authModuleDAO.save(module);
+ assertNotNull(module);
+ assertNotNull(module.getKey());
+ AuthModule found = authModuleDAO.find(module.getKey());
+ assertNotNull(found);
+ assertEquals("SELECT * FROM otherTable WHERE name=?",
+ JDBCAuthModuleConf.class.cast(found.getConf()).getSql());
}
@Test
public void delete() {
- AuthModule authModule = authModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
- assertNotNull(authModule);
+ testDelete("be456831-593d-4003-b273-4c3fb61700df");
+ testDelete("4c3ed8f6-7008-11ea-bc55-0242ac130003");
+ testDelete("4c3edbbc-7008-11ea-bc55-0242ac130003");
+ testDelete("4c3ed7e8-7008-11ea-bc55-0242ac130003");
+ testDelete("4c3ed4e6-7008-11ea-bc55-0242ac130003");
+ testDelete("4c3edc98-7008-11ea-bc55-0242ac130003");
+ testDelete("4c3ed9d2-7008-11ea-bc55-0242ac130003");
+ testDelete("4c3edd60-7008-11ea-bc55-0242ac130003");
+ testDelete("07c528f3-63b4-4dc1-a4da-87f35b8bdec8");
+ testDelete("f6e1288d-50d9-45fe-82ee-597c42242205");
+ }
- authModuleDAO.delete("be456831-593d-4003-b273-4c3fb61700df");
+ private void saveAuthModule(final String name, final AuthModuleConf conf) {
+ AuthModule module = entityFactory.newEntity(AuthModule.class);
+ module.setName(name);
+ module.setDescription("An authentication module");
+ module.setConf(conf);
+ AuthModuleItem keyMapping = entityFactory.newEntity(AuthModuleItem.class);
+ keyMapping.setIntAttrName("uid");
+ keyMapping.setExtAttrName("username");
+ AuthModuleItem fullnameMapping = entityFactory.newEntity(AuthModuleItem.class);
+ fullnameMapping.setIntAttrName("cn");
+ fullnameMapping.setExtAttrName("fullname");
+ module.add(keyMapping);
+ module.add(fullnameMapping);
+ authModuleDAO.save(module);
+ assertNotNull(module);
+ assertNotNull(module.getKey());
+ assertNotNull(authModuleDAO.find(module.getKey()));
+ }
- authModule = authModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
+ private void testDelete(final String key) {
+ AuthModule authModule = authModuleDAO.find(key);
+ assertNotNull(authModule);
+ authModuleDAO.delete(key);
+ authModule = authModuleDAO.find(key);
assertNull(authModule);
}
+
+ private boolean isSpecificConf(final AuthModuleConf conf, final Class<? extends AuthModuleConf> clazz) {
+ return ClassUtils.isAssignable(clazz, conf.getClass());
+ }
}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PolicyTest.java
index 75a5f3b..19acd47 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PolicyTest.java
@@ -28,19 +28,16 @@ import org.apache.syncope.core.persistence.jpa.inner.AbstractClientAppTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
-
import javax.persistence.PersistenceException;
-
import java.util.UUID;
+import org.apache.syncope.core.persistence.api.dao.auth.OIDCRPDAO;
+import org.apache.syncope.core.persistence.api.entity.auth.OIDCRP;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import org.apache.syncope.core.persistence.api.dao.auth.OIDCRPDAO;
-import org.apache.syncope.core.persistence.api.entity.auth.OIDCRP;
-
@Transactional("Master")
public class PolicyTest extends AbstractClientAppTest {
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 29fe303..b484956 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -44,14 +44,13 @@ under the License.
body='{"@class":"org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf","maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWit [...]
<PasswordPolicyRule policy_id="55e5de0b-c79c-4e66-adda-251b6fb8579a" implementation_id="DefaultPasswordRuleConf3"/>
- <!-- authentication policies -->
+ <!-- Authentication policies -->
<Implementation id="MyDefaultAuthPolicyConf" type="AUTH_POLICY_CONFIGURATIONS" engine="JAVA"
body='{"@class":"org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf","authModules":["LdapAuthenticationTest"]}'/>
<AuthPolicy id="659b9906-4b6e-4bc0-aca0-6809dff346d4" name="MyDefaultAuthPolicyConf" description="an authentication policy"/>
<AuthPolicy id="b912a0d4-a890-416f-9ab8-84ab077eb028" name="DefaultAuthPolicy" description="Default authentication policy"/>
- <AuthModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultAuthModule"/>
- <!-- access policies -->
+ <!-- Access policies -->
<Implementation id="MyDefaultAccessPolicyConf" type="ACCESS_POLICY_CONFIGURATIONS" engine="JAVA"
body='{"@class":"org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf","name":"MyDefaultAccessPolicyConf","enabled":true,"ssoEnabled":true}'/>
<AccessPolicy id="419935c7-deb3-40b3-8a9a-683037e523a2" name="MyDefaultAccessPolicyConf" description="an access policy"/>
@@ -64,6 +63,28 @@ under the License.
<Implementation id="DenyAttrReleasePolicyConf" type="ATTR_RELEASE_CONFIGURATIONS" engine="JAVA"
body='{"@class":"org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf","name":"DenyAttrReleasePolicyConf"}'/>
<AttrReleasePolicy id="219935c7-deb3-40b3-8a9a-683037e523a2" name="DenyAttrReleasePolicy" description="deny attribute release policy policy"/>
+
+ <!-- Authentication modules -->
+ <AuthModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultLDAPAuthModule"
+ description="LDAP auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","name":"MyLDAPAuthModuleConf","userIdAttribute":"uid","bindCredential":"Password","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"dc=example,dc=org","subtreeSearch":true}'/>
+ <AuthModule id="4c3ed7e8-7008-11ea-bc55-0242ac130003" name="DefaultJDBCAuthModule"
+ description="JDBC auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.JDBCAuthModuleConf","name":"MyJDBCAuthModuleConf", "sql":"SELECT * FROM table WHERE name=?"}'/>
+ <AuthModule id="4c3ed4e6-7008-11ea-bc55-0242ac130003" name="DefaultGoogleMfaAuthModule"
+ description="Google Mfa auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf","name":"MyGoogleMfaAuthModuleConf","codeDigits":6,"issuer":"SyncopeTest"}'/>
+ <AuthModule id="4c3ed8f6-7008-11ea-bc55-0242ac130003" name="DefaultOIDCAuthModule"
+ description="OIDC auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.OIDCAuthModuleConf","name":"MyOIDCAuthModuleConf", "discoveryUri":"www.testurl.com"}'/>
+ <AuthModule id="4c3ed9d2-7008-11ea-bc55-0242ac130003" name="DefaultSAML2IdPAuthModule"
+ description="SAML2 IdP auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf","name":"MySAML2IdPAuthModuleConf", "providerName":"testProviderName","serviceProviderMetadataPath":"file:/etc/metadata"}'/>
+ <AuthModule id="4c3edbbc-7008-11ea-bc55-0242ac130003" name="DefaultJaasAuthModule"
+ description="Jaas auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.JaasAuthModuleConf","name":"MyJaasAuthModuleConf","realm":"SYNCOPE","kerberosRealmSystemProperty":"sample-value"}'/>
+ <AuthModule id="4c3edc98-7008-11ea-bc55-0242ac130003" name="DefaultStaticAuthModule"
+ description="Static auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.StaticAuthModuleConf","name":"MyStaticAuthModuleConf","users":{"user1": "testUserPassword123"}}'/>
+ <AuthModule id="4c3edd60-7008-11ea-bc55-0242ac130003" name="DefaultSyncopeAuthModule"
+ description="Syncope auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf","name":"MySyncopeAuthModuleConf","domain":"Master","url":"http://mydomain.com/syncope/rest"}'/>
+ <AuthModule id="07c528f3-63b4-4dc1-a4da-87f35b8bdec8" name="DefaultRadiusAuthModule"
+ description="Radius auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.RadiusAuthModuleConf","name":"MyRadiusAuthModuleConf","protocol":"MSCHAPv2","inetAddress":"1.2.3.4", "sharedSecret":"thesecret"}'/>
+ <AuthModule id="f6e1288d-50d9-45fe-82ee-597c42242205" name="DefaultU2FAuthModule"
+ description="U2F auth module" jsonConf='{"@class":"org.apache.syncope.common.lib.auth.U2FAuthModuleConf","name":"MyU2FAuthModuleConf","expireDevices":40}'/>
<RelationshipType id="inclusion" description="Models the act that an object is included in another"/>
<RelationshipType id="neighborhood" description="Models the act that an object is near another"/>
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractClientAppLogic.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuthModuleDataBinder.java
similarity index 53%
rename from core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractClientAppLogic.java
rename to core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuthModuleDataBinder.java
index b73f319..1eab9f4 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractClientAppLogic.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuthModuleDataBinder.java
@@ -16,30 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.logic;
+package org.apache.syncope.core.provisioning.api.data;
-import org.apache.syncope.common.lib.to.client.ClientAppTO;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
-import java.lang.reflect.Method;
-import java.util.List;
+public interface AuthModuleDataBinder {
-public abstract class AbstractClientAppLogic<T extends ClientAppTO>
- extends AbstractTransactionalLogic<ClientAppTO> {
+ AuthModule create(AuthModuleTO authModuleTO);
- @Override
- protected ClientAppTO resolveReference(final Method method, final Object... args)
- throws UnresolvedReferenceException {
- throw new UnresolvedReferenceException();
- }
+ AuthModule update(AuthModule authModule, AuthModuleTO authModuleTO);
- public abstract T delete(String key);
-
- public abstract List<T> list();
-
- public abstract T read(String key);
-
- public abstract T create(T applicationTO);
-
- public abstract T update(T applicationTO);
+ AuthModuleTO getAuthModuleTO(AuthModule authModule);
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuthModuleDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuthModuleDataBinderImpl.java
new file mode 100644
index 0000000..0b0e38b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuthModuleDataBinderImpl.java
@@ -0,0 +1,79 @@
+/*
+ * 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.core.persistence.api.entity.EntityFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
+import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
+import org.apache.syncope.core.provisioning.api.data.AuthModuleDataBinder;
+
+@Component
+public class AuthModuleDataBinderImpl implements AuthModuleDataBinder {
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ private AuthModule getAuthModule(final AuthModule authModule, final AuthModuleTO authModuleTO) {
+ AuthModule result = authModule;
+
+ if (result == null) {
+ result = entityFactory.newEntity(AuthModule.class);
+ }
+
+ AuthModule authenticationModule = AuthModule.class.cast(result);
+ AuthModuleTO authenticationModuleTO = AuthModuleTO.class.cast(authModuleTO);
+
+ authenticationModule.setName(authenticationModuleTO.getName());
+ authenticationModule.setConf(authenticationModuleTO.getConf());
+ authenticationModule.setDescription(authenticationModuleTO.getDescription());
+ // remove all profile items not contained in the TO
+ authenticationModule.getProfileItems().
+ removeIf(item -> !authenticationModuleTO.getProfileItems().stream().
+ anyMatch(otherItem -> item.getKey().equals(otherItem.getKey())));
+
+ return result;
+ }
+
+ @Override
+ public AuthModule create(final AuthModuleTO authModuleTO) {
+ return getAuthModule(null, authModuleTO);
+ }
+
+ @Override
+ public AuthModule update(final AuthModule authModule, final AuthModuleTO authModuleTO) {
+ return getAuthModule(authModule, authModuleTO);
+ }
+
+ @Override
+ public AuthModuleTO getAuthModuleTO(final AuthModule authModule) {
+ AuthModuleTO authModuleTO = new AuthModuleTO();
+
+ authModuleTO.setName(authModule.getName());
+ authModuleTO.setKey(authModule.getKey());
+ authModuleTO.setDescription(authModule.getDescription());
+ authModuleTO.setConf(authModule.getConf());
+ authModuleTO.getProfileItems().forEach(item -> {
+ authModuleTO.add(item);
+ });
+
+ return authModuleTO;
+ }
+}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index 812b1bf..9502a5d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -24,7 +24,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ConnPoolConfTO;
@@ -60,9 +59,6 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
private RealmDAO realmDAO;
@Autowired
- private ConfParamOps confParamOps;
-
- @Autowired
private EntityFactory entityFactory;
@Override
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
index dca7d28..9df9f8c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
@@ -23,7 +23,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.policy.AccessPolicyConf;
import org.apache.syncope.common.lib.policy.AttrReleasePolicyConf;
-import org.apache.syncope.common.lib.auth.AuthModuleConf;
import org.apache.syncope.common.lib.policy.RuleConf;
import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.common.lib.to.ImplementationTO;
@@ -58,7 +57,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.apache.syncope.common.lib.policy.AuthPolicyConf;
-import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
@Component
@@ -162,10 +160,6 @@ public class ImplementationDataBinderImpl implements ImplementationDataBinder {
base = AccessPolicy.class;
break;
- case AMImplementationType.AUTH_MODULE_CONFIGURATIONS:
- base = AuthModule.class;
- break;
-
case AMImplementationType.AUTH_POLICY_CONFIGURATIONS:
base = AuthPolicy.class;
break;
@@ -198,14 +192,6 @@ public class ImplementationDataBinderImpl implements ImplementationDataBinder {
throw sce;
}
break;
- case AMImplementationType.AUTH_MODULE_CONFIGURATIONS:
- AuthModuleConf authModuleConf =
- POJOHelper.deserialize(implementation.getBody(), AuthModuleConf.class);
- if (authModuleConf == null) {
- sce.getElements().add("Could not deserialize as AuthModule");
- throw sce;
- }
- break;
case AMImplementationType.AUTH_POLICY_CONFIGURATIONS:
AuthPolicyConf authPolicyConf =
POJOHelper.deserialize(implementation.getBody(), AuthPolicyConf.class);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index bd208f7..3525861 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -74,6 +74,7 @@ import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.ReportTO;
import org.apache.syncope.common.lib.to.RoleTO;
import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.PolicyType;
@@ -86,6 +87,7 @@ import org.apache.syncope.common.rest.api.service.AnyObjectService;
import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
import org.apache.syncope.common.rest.api.service.AnyTypeService;
import org.apache.syncope.common.rest.api.service.ApplicationService;
+import org.apache.syncope.common.rest.api.service.AuthModuleService;
import org.apache.syncope.common.rest.api.service.CamelRouteService;
import org.apache.syncope.common.rest.api.service.ClientAppService;
import org.apache.syncope.common.rest.api.service.ConnectorService;
@@ -268,6 +270,8 @@ public abstract class AbstractITCase {
protected static PolicyService policyService;
+ protected static AuthModuleService authModuleService;
+
protected static SecurityQuestionService securityQuestionService;
protected static ImplementationService implementationService;
@@ -360,6 +364,7 @@ public abstract class AbstractITCase {
oidcProviderService = adminClient.getService(OIDCProviderService.class);
scimConfService = adminClient.getService(SCIMConfService.class);
clientAppService = adminClient.getService(ClientAppService.class);
+ authModuleService = adminClient.getService(AuthModuleService.class);
}
@Autowired
@@ -562,6 +567,18 @@ public abstract class AbstractITCase {
return (T) getObject(response.getLocation(), PolicyService.class, policy.getClass());
}
+ @SuppressWarnings("unchecked")
+ protected AuthModuleTO createAuthModule(final AuthModuleTO authModule) {
+ Response response = authModuleService.create(authModule);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return getObject(response.getLocation(), AuthModuleService.class, authModule.getClass());
+ }
+
protected ResourceTO createResource(final ResourceTO resourceTO) {
Response response = resourceService.create(resourceTO);
if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java
new file mode 100644
index 0000000..f88c03a
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java
@@ -0,0 +1,406 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.jupiter.api.Test;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.UUID;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.auth.AuthModuleConf;
+import org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf;
+import org.apache.syncope.common.lib.auth.JDBCAuthModuleConf;
+import org.apache.syncope.common.lib.auth.JaasAuthModuleConf;
+import org.apache.syncope.common.lib.auth.LDAPAuthModuleConf;
+import org.apache.syncope.common.lib.auth.OIDCAuthModuleConf;
+import org.apache.syncope.common.lib.auth.RadiusAuthModuleConf;
+import org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf;
+import org.apache.syncope.common.lib.auth.StaticAuthModuleConf;
+import org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf;
+import org.apache.syncope.common.lib.auth.U2FAuthModuleConf;
+import org.apache.syncope.common.lib.to.AuthModuleTO;
+
+public class AuthModuleITCase extends AbstractITCase {
+
+ private enum AuthModuleSupportedType {
+ GOOGLE_MFA,
+ SAML2_IDP,
+ STATIC,
+ SYNCOPE,
+ LDAP,
+ JAAS,
+ JDBC,
+ U2F,
+ RADIUS,
+ OIDC;
+
+ };
+
+ private static AuthModuleTO buildAuthModuleTO(final AuthModuleSupportedType type) {
+ AuthModuleTO authModuleTO = new AuthModuleTO();
+ authModuleTO.setName("Test" + type + "AuthenticationModule" + getUUIDString());
+ authModuleTO.setDescription("A test " + type + " Authentication Module");
+ AuthModuleConf conf;
+
+ switch (type) {
+ case LDAP:
+ conf = new LDAPAuthModuleConf();
+ LDAPAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ LDAPAuthModuleConf.class.cast(conf).setBaseDn("dc=example,dc=org");
+ LDAPAuthModuleConf.class.cast(conf).setSearchFilter("cn={user}");
+ LDAPAuthModuleConf.class.cast(conf).setSubtreeSearch(true);
+ LDAPAuthModuleConf.class.cast(conf).setLdapUrl("ldap://localhost:1389");
+ LDAPAuthModuleConf.class.cast(conf).setUserIdAttribute("uid");
+ LDAPAuthModuleConf.class.cast(conf).setBaseDn("cn=Directory Manager,dc=example,dc=org");
+ LDAPAuthModuleConf.class.cast(conf).setBindCredential("Password");
+ break;
+
+ case GOOGLE_MFA:
+ conf = new GoogleMfaAuthModuleConf();
+ GoogleMfaAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ GoogleMfaAuthModuleConf.class.cast(conf).setCodeDigits(6);
+ GoogleMfaAuthModuleConf.class.cast(conf).setIssuer("SyncopeTest");
+ GoogleMfaAuthModuleConf.class.cast(conf).setLabel("Syncope");
+ GoogleMfaAuthModuleConf.class.cast(conf).setTimeStepSize(30);
+ GoogleMfaAuthModuleConf.class.cast(conf).setWindowSize(3);
+ break;
+
+ case JAAS:
+ conf = new JaasAuthModuleConf();
+ JaasAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ JaasAuthModuleConf.class.cast(conf).setKerberosKdcSystemProperty("sample-value");
+ JaasAuthModuleConf.class.cast(conf).setKerberosRealmSystemProperty("sample-value");
+ JaasAuthModuleConf.class.cast(conf).setLoginConfigType("JavaLoginConfig");
+ JaasAuthModuleConf.class.cast(conf).setRealm("SYNCOPE");
+ JaasAuthModuleConf.class.cast(conf).setLoginConfigurationFile("/opt/jaas/login.conf");
+ break;
+
+ case JDBC:
+ conf = new JDBCAuthModuleConf();
+ JDBCAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ JDBCAuthModuleConf.class.cast(conf).setSql("SELECT * FROM table WHERE name=?");
+ JDBCAuthModuleConf.class.cast(conf).setFieldPassword("password");
+ JDBCAuthModuleConf.class.cast(conf).getPrincipalAttributeList().addAll(
+ List.of("sn", "cn:commonName", "givenName"));
+ break;
+
+ case OIDC:
+ conf = new OIDCAuthModuleConf();
+ OIDCAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ OIDCAuthModuleConf.class.cast(conf).setId("OIDCTestId");
+ OIDCAuthModuleConf.class.cast(conf).setDiscoveryUri("www.testurl.com");
+ OIDCAuthModuleConf.class.cast(conf).setUserIdAttribute("username");
+ OIDCAuthModuleConf.class.cast(conf).setResponseType("code");
+ OIDCAuthModuleConf.class.cast(conf).setScope("openid email profile");
+ break;
+
+ case SAML2_IDP:
+ conf = new SAML2IdPAuthModuleConf();
+ SAML2IdPAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ SAML2IdPAuthModuleConf.class.cast(conf).setServiceProviderEntityId("testEntityId");
+ SAML2IdPAuthModuleConf.class.cast(conf).setProviderName("testProviderName");
+ SAML2IdPAuthModuleConf.class.cast(conf).setServiceProviderMetadataPath(
+ "file:/etc/metadata");
+ break;
+
+ case SYNCOPE:
+ conf = new SyncopeAuthModuleConf();
+ SyncopeAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ SyncopeAuthModuleConf.class.cast(conf).setDomain("Master");
+ SyncopeAuthModuleConf.class.cast(conf).setUrl("http://mydomain.com/syncope/rest");
+ break;
+
+ case U2F:
+ conf = new U2FAuthModuleConf();
+ U2FAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ U2FAuthModuleConf.class.cast(conf).setExpireDevices(50);
+ break;
+
+ case RADIUS:
+ conf = new RadiusAuthModuleConf();
+ RadiusAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ RadiusAuthModuleConf.class.cast(conf).setProtocol("MSCHAPv2");
+ RadiusAuthModuleConf.class.cast(conf).setInetAddress("1.2.3.4");
+ RadiusAuthModuleConf.class.cast(conf).setSharedSecret("xyz");
+ RadiusAuthModuleConf.class.cast(conf).setSocketTimeout(40);
+ break;
+
+ case STATIC:
+ default:
+ conf = new StaticAuthModuleConf();
+ StaticAuthModuleConf.class.cast(conf).setName("TestConf" + getUUIDString());
+ StaticAuthModuleConf.class.cast(conf).getUsers().put("user1", UUID.randomUUID().toString());
+ StaticAuthModuleConf.class.cast(conf).getUsers().put("user2", "user2Password123");
+ break;
+ }
+ authModuleTO.setConf(conf);
+
+ return authModuleTO;
+ }
+
+ @Test
+ public void findAll() {
+ List<AuthModuleTO> authModuleTOs = authModuleService.list();
+ assertNotNull(authModuleTOs);
+ assertFalse(authModuleTOs.isEmpty());
+ assertTrue(authModuleTOs.size() >= 10);
+ }
+
+ @Test
+ public void listByType() {
+ List<AuthModuleTO> authModuleTOs = authModuleService.list();
+ assertNotNull(authModuleTOs);
+ assertFalse(authModuleTOs.isEmpty());
+
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), LDAPAuthModuleConf.class)
+ && authModule.getName().equals("DefaultLDAPAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), JDBCAuthModuleConf.class)
+ && authModule.getName().equals("DefaultJDBCAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), GoogleMfaAuthModuleConf.class)
+ && authModule.getName().equals("DefaultGoogleMfaAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), OIDCAuthModuleConf.class)
+ && authModule.getName().equals("DefaultOIDCAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), SAML2IdPAuthModuleConf.class)
+ && authModule.getName().equals("DefaultSAML2IdPAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), JaasAuthModuleConf.class)
+ && authModule.getName().equals("DefaultJaasAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), StaticAuthModuleConf.class)
+ && authModule.getName().equals("DefaultStaticAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), SyncopeAuthModuleConf.class)
+ && authModule.getName().equals("DefaultSyncopeAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), U2FAuthModuleConf.class)
+ && authModule.getName().equals("DefaultU2FAuthModule")));
+ assertTrue(authModuleTOs.stream().anyMatch(
+ authModule -> isSpecificConf(authModule.getConf(), RadiusAuthModuleConf.class)
+ && authModule.getName().equals("DefaultRadiusAuthModule")));
+ }
+
+ @Test
+ public void getLDAPAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("be456831-593d-4003-b273-4c3fb61700df");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), LDAPAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), JDBCAuthModuleConf.class));
+ }
+
+ @Test
+ public void getJDBCAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3ed7e8-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), JDBCAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), GoogleMfaAuthModuleConf.class));
+ }
+
+ @Test
+ public void getGoogleMfaAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3ed4e6-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), GoogleMfaAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), OIDCAuthModuleConf.class));
+ }
+
+ @Test
+ public void getOIDCAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3ed8f6-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), OIDCAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), SAML2IdPAuthModuleConf.class));
+ }
+
+ @Test
+ public void getSAML2IdPAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3ed9d2-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), SAML2IdPAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), JaasAuthModuleConf.class));
+ }
+
+ @Test
+ public void getJaasAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3edbbc-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), JaasAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), StaticAuthModuleConf.class));
+ }
+
+ @Test
+ public void getStaticAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3edc98-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), StaticAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), SyncopeAuthModuleConf.class));
+ }
+
+ @Test
+ public void getSyncopeAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("4c3edd60-7008-11ea-bc55-0242ac130003");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), SyncopeAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), RadiusAuthModuleConf.class));
+ }
+
+ @Test
+ public void getRadiusAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("07c528f3-63b4-4dc1-a4da-87f35b8bdec8");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), RadiusAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), U2FAuthModuleConf.class));
+ }
+
+ @Test
+ public void getU2FAuthModule() {
+ AuthModuleTO authModuleTO = authModuleService.read("f6e1288d-50d9-45fe-82ee-597c42242205");
+
+ assertNotNull(authModuleTO);
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getName()));
+ assertTrue(StringUtils.isNotBlank(authModuleTO.getDescription()));
+ assertTrue(isSpecificConf(authModuleTO.getConf(), U2FAuthModuleConf.class));
+ assertFalse(isSpecificConf(authModuleTO.getConf(), LDAPAuthModuleConf.class));
+ }
+
+ @Test
+ public void create() throws IOException {
+ EnumSet.allOf(AuthModuleSupportedType.class).forEach(type -> testCreate(type));
+ }
+
+ @Test
+ public void updateGoogleMfaAuthModule() {
+ AuthModuleTO googleMfaAuthModuleTO = authModuleService.read("4c3ed4e6-7008-11ea-bc55-0242ac130003");
+ assertNotNull(googleMfaAuthModuleTO);
+
+ final String authModuleName = "TestGoogleMfaAuthModule" + getUUIDString();
+ AuthModuleTO newGoogleMfaAuthModuleTO = buildAuthModuleTO(AuthModuleSupportedType.GOOGLE_MFA);
+ newGoogleMfaAuthModuleTO = createAuthModule(newGoogleMfaAuthModuleTO);
+ assertNotNull(newGoogleMfaAuthModuleTO);
+
+ AuthModuleConf conf = googleMfaAuthModuleTO.getConf();
+ assertNotNull(conf);
+ GoogleMfaAuthModuleConf.class.cast(conf).setLabel("newLabel");
+ newGoogleMfaAuthModuleTO.setConf(conf);
+
+ // update new auth module
+ authModuleService.update(newGoogleMfaAuthModuleTO);
+ newGoogleMfaAuthModuleTO = authModuleService.read(newGoogleMfaAuthModuleTO.getKey());
+ assertNotNull(newGoogleMfaAuthModuleTO);
+
+ conf = newGoogleMfaAuthModuleTO.getConf();
+ assertEquals("newLabel", GoogleMfaAuthModuleConf.class.cast(conf).getLabel());
+ }
+
+ @Test
+ public void updateLDAPAuthModule() {
+ AuthModuleTO ldapAuthModuleTO = authModuleService.read("be456831-593d-4003-b273-4c3fb61700df");
+ assertNotNull(ldapAuthModuleTO);
+
+ final String authModuleName = "TestGoogleMfaAuthModule" + getUUIDString();
+ AuthModuleTO newLdapAuthModuleTO = buildAuthModuleTO(AuthModuleSupportedType.LDAP);
+ newLdapAuthModuleTO = createAuthModule(newLdapAuthModuleTO);
+ assertNotNull(newLdapAuthModuleTO);
+
+ AuthModuleConf conf = ldapAuthModuleTO.getConf();
+ assertNotNull(conf);
+ LDAPAuthModuleConf.class.cast(conf).setSubtreeSearch(false);
+ newLdapAuthModuleTO.setConf(conf);
+
+ // update new auth module
+ authModuleService.update(newLdapAuthModuleTO);
+ newLdapAuthModuleTO = authModuleService.read(newLdapAuthModuleTO.getKey());
+ assertNotNull(newLdapAuthModuleTO);
+
+ conf = newLdapAuthModuleTO.getConf();
+ assertFalse(LDAPAuthModuleConf.class.cast(conf).isSubtreeSearch());
+ }
+
+ @Test
+ public void delete() throws IOException {
+ EnumSet.allOf(AuthModuleSupportedType.class).forEach(type -> testDelete(type));
+ }
+
+ private void testCreate(final AuthModuleSupportedType type) {
+ AuthModuleTO authModuleTO = createAuthModule(buildAuthModuleTO(type));
+ assertNotNull(authModuleTO);
+ assertTrue(authModuleTO.getName().contains(
+ "Test" + type + "AuthenticationModule"));
+ assertTrue(authModuleTO.getDescription().contains(
+ "A test " + type + " Authentication Module"));
+ }
+
+ private void testDelete(final AuthModuleSupportedType type) {
+ AuthModuleTO authModuleTO = buildAuthModuleTO(type);
+ AuthModuleTO read = createAuthModule(authModuleTO);
+ assertNotNull(read);
+ authModuleService.delete(read.getKey());
+ try {
+ authModuleService.read(read.getKey());
+ fail("This should not happen");
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ }
+
+ private boolean isSpecificConf(final AuthModuleConf conf, final Class<? extends AuthModuleConf> clazz) {
+ return ClassUtils.isAssignable(clazz, conf.getClass());
+ }
+}
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 2a64794..5af04e0 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
@@ -41,6 +41,7 @@ public class SyncopeServiceRegistry extends AbstractServiceRegistry {
public SyncopeServiceRegistry(final WARestClient restClient,
final ConfigurableApplicationContext applicationContext,
final Collection<ServiceRegistryListener> serviceRegistryListeners) {
+
super(applicationContext, serviceRegistryListeners);
this.restClient = restClient;
this.mapper = new RegisteredServiceMapper();