You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/07/10 16:35:58 UTC
[1/4] syncope git commit: [SYNCOPE-1143] Now connector instances
require an admin realm,
which is used to enforce access control on it for administrative purposes
Repository: syncope
Updated Branches:
refs/heads/2_0_X 699b3c62c -> b5d6dc4aa
refs/heads/master f1eaaa263 -> 9779e13e0
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index f3ada03..5b7ec8e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -191,7 +191,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(
- user.getRealm().getFullPath(), AnyTypeKind.USER, user.getKey());
+ user.getRealm().getFullPath(), AnyTypeKind.USER.name(), user.getKey());
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
index 449b0f3..bd5a108 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -38,7 +38,7 @@ public abstract class AbstractAny<P extends PlainAttr<?>> extends AbstractAnnota
private static final long serialVersionUID = -2666540708092702810L;
- @ManyToOne(fetch = FetchType.EAGER)
+ @ManyToOne(fetch = FetchType.EAGER, optional = false)
private JPARealm realm;
private String workflowId;
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index c7da0ae..7678fc2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -32,6 +32,7 @@ import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@@ -41,6 +42,7 @@ import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@@ -57,6 +59,9 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
private static final int DEFAULT_TIMEOUT = 10;
+ @ManyToOne(fetch = FetchType.EAGER, optional = false)
+ private JPARealm adminRealm;
+
/**
* URI identifying the local / remote ConnId location where the related connector bundle is found.
*/
@@ -125,6 +130,17 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
private JPAConnPoolConf poolConf;
@Override
+ public Realm getAdminRealm() {
+ return adminRealm;
+ }
+
+ @Override
+ public void setAdminRealm(final Realm adminRealm) {
+ checkType(adminRealm, JPARealm.class);
+ this.adminRealm = (JPARealm) adminRealm;
+ }
+
+ @Override
public String getLocation() {
return location;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
index b8eb01a..5020adb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
@@ -23,18 +23,30 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.ConnConfPropSchema;
import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
@Transactional("Master")
@@ -45,21 +57,44 @@ public class ConnInstanceTest extends AbstractTest {
@Test
public void findAll() {
- List<ConnInstance> connectors = connInstanceDAO.findAll();
- assertNotNull(connectors);
- assertFalse(connectors.isEmpty());
+ List<GrantedAuthority> authorities = CollectionUtils.collect(StandardEntitlement.values(),
+ new Transformer<String, GrantedAuthority>() {
+
+ @Override
+ public GrantedAuthority transform(final String entitlement) {
+ return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+ }
+ }, new ArrayList<GrantedAuthority>());
+
+ UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+ new org.springframework.security.core.userdetails.User(
+ "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+ auth.setDetails(new SyncopeAuthenticationDetails("Master"));
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ try {
+ List<ConnInstance> connectors = connInstanceDAO.findAll();
+ assertNotNull(connectors);
+ assertFalse(connectors.isEmpty());
+ } finally {
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
}
@Test
public void findById() {
- ConnInstance connectorInstance = connInstanceDAO.find("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
-
- assertNotNull("findById did not work", connectorInstance);
-
+ ConnInstance connInstance = connInstanceDAO.find("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
+ assertNotNull(connInstance);
assertEquals("invalid connector name",
- "net.tirasa.connid.bundles.soap.WebServiceConnector", connectorInstance.getConnectorName());
-
- assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connectorInstance.getBundleName());
+ "net.tirasa.connid.bundles.soap.WebServiceConnector", connInstance.getConnectorName());
+ assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connInstance.getBundleName());
+
+ try {
+ connInstanceDAO.authFind("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
+ fail();
+ } catch (DelegatedAdministrationException e) {
+ assertNotNull(e);
+ }
}
@Test
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
index 3fcf4ae..03b516d 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
@@ -39,6 +39,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -74,6 +75,13 @@ public class ResourceTest extends AbstractTest {
return "7f55b09c-b573-41dc-a9eb-ccd80bd3ea7a".equals(item.getKey());
}
}));
+
+ try {
+ resourceDAO.authFind("ws-target-resource-1");
+ fail();
+ } catch (DelegatedAdministrationException e) {
+ assertNotNull(e);
+ }
}
@Test
@@ -91,13 +99,6 @@ public class ResourceTest extends AbstractTest {
}
@Test
- public void findAllByPriority() {
- List<ExternalResource> resources = resourceDAO.findAllByPriority();
- assertNotNull(resources);
- assertFalse(resources.isEmpty());
- }
-
- @Test
public void getConnObjectKey() {
ExternalResource resource = resourceDAO.find("ws-target-resource-2");
assertNotNull(resource);
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 83bacf0..717535f 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -274,6 +274,18 @@ under the License.
<SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="Search for realm evenTwo"/>
<SyncopeRole_Realm role_id="Search for realm evenTwo" realm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"/>
+ <SyncopeRole id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_READ" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_UPDATE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_DELETE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_LIST" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_READ" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_UPDATE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_DELETE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_LIST" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_Realm role_id="Connector and Resource for realm evenTwo"
+ realm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"/>
+
<SyncopeUser id="1417acbe-cbf6-4277-9372-e75e04f97000" workflowId="4" status="active"
password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
realm_id="c5b75db1-fce7-470f-b780-3b9934d82a9d"
@@ -303,6 +315,7 @@ under the License.
username="puccini" creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
<SyncopeUser_SyncopeRole user_id="823074dc-d280-436d-a7dd-07399fae48ec" role_id="Search for realm evenTwo"/>
+ <SyncopeUser_SyncopeRole user_id="823074dc-d280-436d-a7dd-07399fae48ec" role_id="Connector and Resource for realm evenTwo"/>
<SyncopeGroup id="37d15e4c-cdc1-460b-a591-8505c8133806" name="root"
realm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -614,6 +627,7 @@ under the License.
<GPlainAttrValue attribute_id="22690472-ed3f-4972-8979-4c9251fab044" id="e16765e6-f806-469e-ae34-1ddf56f2102a" stringValue="r13"/>
<ConnInstance id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" displayName="ConnInstance100"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.soap"
connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
@@ -625,6 +639,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="SEARCH"/>
<ConnInstance id="5aa5b8be-7521-481a-9651-c557aea078c1" displayName="H2"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
bundleName="net.tirasa.connid.bundles.db.table"
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
@@ -638,6 +653,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="SYNC"/>
<ConnInstance id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" displayName="ConnInstance102"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.soap"
connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
@@ -650,6 +666,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="SEARCH"/>
<ConnInstance id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" displayName="ConnInstance103"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.soap"
connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
@@ -657,6 +674,7 @@ under the License.
jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
<ConnInstance id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" displayName="CSVDir"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.csvdir"
connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
@@ -668,7 +686,9 @@ under the License.
<ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SEARCH"/>
<ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SYNC"/>
- <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
+ <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef"
+ bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
version="${connid.ldap.version}"
@@ -679,6 +699,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="SEARCH"/>
<ConnInstance id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" displayName="H2-test2"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
bundleName="net.tirasa.connid.bundles.db.table"
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
@@ -690,6 +711,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="SYNC"/>
<ConnInstance id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" bundleName="net.tirasa.connid.bundles.db.table"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
displayName="H2-testpull" version="${connid.database.version}"
@@ -700,6 +722,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="SEARCH"/>
<ConnInstance id="a6d017fd-a705-4507-bb7c-6ab6a6745997" bundleName="net.tirasa.connid.bundles.db.scriptedsql"
+ adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
displayName="Scripted SQL" version="${connid.database.version}"
@@ -711,6 +734,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SYNC"/>
<ConnInstance id="44c02549-19c3-483c-8025-4919c3283c37" bundlename="net.tirasa.connid.bundles.rest"
+ adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
connectorname="net.tirasa.connid.bundles.rest.RESTConnector"
displayname="REST" version="${connid.rest.version}"
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
index d4949d8..4fd3db7 100644
--- a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -185,6 +185,7 @@ we are happy to inform you that the password request was successfully executed f
<Notification_events notification_id="71769807-7f74-4dc3-ba61-e4a7a00eb8ad" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
<ConnInstance id="b7ea96c3-c633-488b-98a0-b52ac35850f7" bundleName="net.tirasa.connid.bundles.ldap" displayName="LDAP"
+ adminRealm_id="ea696a4f-e77a-4ef1-be67-8f8093bc8686"
location="${connid.location}"
connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
version="${connid.ldap.version}"
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
index 49810c7..a21e1de 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
@@ -21,6 +21,9 @@ package org.apache.syncope.core.provisioning.api.utils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
public final class RealmUtils {
@@ -57,6 +60,50 @@ public final class RealmUtils {
return normalized;
}
+ private static class StartsWithPredicate implements Predicate<String> {
+
+ private final Collection<String> targets;
+
+ StartsWithPredicate(final Collection<String> targets) {
+ this.targets = targets;
+ }
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return IterableUtils.matchesAny(targets, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String target) {
+ return realm.startsWith(target);
+ }
+ });
+ }
+
+ }
+
+ public static class DynRealmsPredicate implements Predicate<String> {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return !realm.startsWith("/");
+ }
+ }
+
+ public static Set<String> getEffective(final Set<String> allowedRealms, final String requestedRealm) {
+ Set<String> allowed = RealmUtils.normalize(allowedRealms);
+ Set<String> requested = new HashSet<>();
+ requested.add(requestedRealm);
+
+ Set<String> effective = new HashSet<>();
+ CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
+ CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
+
+ // includes dynamic realms
+ CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
+
+ return effective;
+ }
+
private RealmUtils() {
// empty constructor for static utility class
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index e63eb2c..901acc2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -90,6 +90,7 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory, Sy
}
ConnInstance override = entityFactory.newEntity(ConnInstance.class);
+ override.setAdminRealm(connInstance.getAdminRealm());
override.setConnectorName(connInstance.getConnectorName());
override.setDisplayName(connInstance.getDisplayName());
override.setBundleName(connInstance.getBundleName());
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
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 ba4d62d..06a8021 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,8 +24,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
@@ -37,9 +35,11 @@ import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceHistoryConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.ConnInstanceHistoryConf;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
import org.identityconnectors.framework.api.ConfigurationProperties;
@@ -54,7 +54,7 @@ import org.springframework.stereotype.Component;
@Component
public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
- private static final String[] IGNORE_PROPERTIES = { "poolConf", "location" };
+ private static final String[] IGNORE_PROPERTIES = { "poolConf", "location", "adminRealm" };
@Autowired
private ConnIdBundleManager connIdBundleManager;
@@ -66,6 +66,9 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
private ConnInstanceHistoryConfDAO connInstanceHistoryConfDAO;
@Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
private ConfDAO confDAO;
@Autowired
@@ -98,6 +101,12 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
ConnInstance connInstance = entityFactory.newEntity(ConnInstance.class);
BeanUtils.copyProperties(connInstanceTO, connInstance, IGNORE_PROPERTIES);
+ if (connInstanceTO.getAdminRealm() != null) {
+ connInstance.setAdminRealm(realmDAO.findByFullPath(connInstanceTO.getAdminRealm()));
+ }
+ if (connInstance.getAdminRealm() == null) {
+ sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+ }
if (connInstanceTO.getLocation() != null) {
connInstance.setLocation(connInstanceTO.getLocation());
}
@@ -116,7 +125,7 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
@Override
public ConnInstance update(final ConnInstanceTO connInstanceTO) {
- ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+ ConnInstance connInstance = connInstanceDAO.authFind(connInstanceTO.getKey());
if (connInstance == null) {
throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
}
@@ -143,6 +152,16 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
connInstance.getCapabilities().clear();
connInstance.getCapabilities().addAll(connInstanceTO.getCapabilities());
+ if (connInstanceTO.getAdminRealm() != null) {
+ Realm realm = realmDAO.findByFullPath(connInstanceTO.getAdminRealm());
+ if (realm == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+ throw sce;
+ }
+ connInstance.setAdminRealm(realm);
+ }
+
if (connInstanceTO.getLocation() != null) {
connInstance.setLocation(connInstanceTO.getLocation());
}
@@ -181,9 +200,9 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
try {
connInstance = connInstanceDAO.save(connInstance);
} catch (Exception e) {
- SyncopeClientException ex = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
- ex.getElements().add(e.getMessage());
- throw ex;
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
+ sce.getElements().add(e.getMessage());
+ throw sce;
}
return connInstance;
@@ -220,25 +239,18 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
Pair<URI, ConnectorInfo> info = connIdBundleManager.getConnectorInfo(connInstance);
BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
+ connInstanceTO.setAdminRealm(connInstance.getAdminRealm().getFullPath());
connInstanceTO.setLocation(info.getLeft().toASCIIString());
// refresh stored properties in the given connInstance with direct information from underlying connector
ConfigurationProperties properties = connIdBundleManager.getConfigurationProperties(info.getRight());
for (final String propName : properties.getPropertyNames()) {
ConnConfPropSchema schema = build(properties.getProperty(propName));
- ConnConfProperty property = IterableUtils.find(connInstanceTO.getConf(),
- new Predicate<ConnConfProperty>() {
-
- @Override
- public boolean evaluate(final ConnConfProperty candidate) {
- return propName.equals(candidate.getSchema().getName());
- }
- });
+ ConnConfProperty property = connInstanceTO.getConf(propName);
if (property == null) {
property = new ConnConfProperty();
connInstanceTO.getConf().add(property);
}
-
property.setSchema(schema);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
index 0ee414a..392ce41 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
@@ -24,7 +24,7 @@ public class DelegatedAdministrationException extends RuntimeException {
private static final long serialVersionUID = 7540587364235915081L;
- public DelegatedAdministrationException(final String realm, final AnyTypeKind type, final String key) {
+ public DelegatedAdministrationException(final String realm, final String type, final String key) {
super("Missing entitlement or realm administration under " + realm + " for "
+ (key == null
? "new " + type
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
index c5190b3..5bed533 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -38,12 +38,15 @@ import java.util.Set;
import java.util.UUID;
import javax.ws.rs.core.Response;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.ConnBundleTO;
import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
@@ -54,6 +57,7 @@ import org.apache.syncope.common.lib.to.MappingTO;
import org.apache.syncope.common.lib.to.ProvisionTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ConnConfPropSchema;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
@@ -117,6 +121,7 @@ public class ConnectorITCase extends AbstractITCase {
@Test
public void create() {
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connectorTO.setLocation(connectorService.read(
"88a7a819-dab5-46b4-9b90-0b9769eabdb8", Locale.ENGLISH.getLanguage()).getLocation());
connectorTO.setVersion(connIdSoapVersion);
@@ -217,6 +222,7 @@ public class ConnectorITCase extends AbstractITCase {
@Test
public void update() {
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
// set connector instance key
connectorTO.setKey("fcf9f2b0-f7d6-42c9-84a6-61b28255a42b");
@@ -358,6 +364,7 @@ public class ConnectorITCase extends AbstractITCase {
@Test
public void validate() {
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connectorTO.setLocation(connectorServerLocation);
connectorTO.setVersion(connIdDbVersion);
connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
@@ -519,6 +526,52 @@ public class ConnectorITCase extends AbstractITCase {
}
@Test
+ public void authorizations() {
+ SyncopeClient puccini = clientFactory.create("puccini", ADMIN_PWD);
+ ConnectorService pcs = puccini.getService(ConnectorService.class);
+
+ // 1. list connectors: get only the ones allowed
+ List<ConnInstanceTO> connInstances = pcs.list(null);
+ assertEquals(2, connInstances.size());
+
+ assertTrue(IterableUtils.matchesAll(connInstances, new Predicate<ConnInstanceTO>() {
+
+ @Override
+ public boolean evaluate(final ConnInstanceTO object) {
+ return "a6d017fd-a705-4507-bb7c-6ab6a6745997".equals(object.getKey())
+ || "44c02549-19c3-483c-8025-4919c3283c37".equals(object.getKey());
+ }
+ }));
+
+ // 2. attempt to read a connector with a different admin realm: fail
+ try {
+ pcs.read("88a7a819-dab5-46b4-9b90-0b9769eabdb8", null);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+ }
+
+ // 3. read and upate a connector in the realm for which entitlements are owned: succeed
+ try {
+ ConnInstanceTO scriptedsql = pcs.read("a6d017fd-a705-4507-bb7c-6ab6a6745997", null);
+ ConnConfProperty reloadScriptOnExecution = scriptedsql.getConf("reloadScriptOnExecution");
+ assertEquals("true", reloadScriptOnExecution.getValues().get(0).toString());
+
+ reloadScriptOnExecution.getValues().set(0, "false");
+ pcs.update(scriptedsql);
+
+ scriptedsql = pcs.read(scriptedsql.getKey(), null);
+ reloadScriptOnExecution = scriptedsql.getConf("reloadScriptOnExecution");
+ assertEquals("false", reloadScriptOnExecution.getValues().get(0).toString());
+ } finally {
+ ConnInstanceTO scriptedsql = connectorService.read("a6d017fd-a705-4507-bb7c-6ab6a6745997", null);
+ ConnConfProperty reloadScriptOnExecution = scriptedsql.getConf("reloadScriptOnExecution");
+ reloadScriptOnExecution.getValues().set(0, "true");
+ connectorService.update(scriptedsql);
+ }
+ }
+
+ @Test
public void issueSYNCOPE10() {
// ----------------------------------
// Copy resource and connector in order to create new objects.
@@ -616,6 +669,7 @@ public class ConnectorITCase extends AbstractITCase {
// Create a new connector
// ----------------------------------------
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connectorTO.setLocation(connectorService.read(
"88a7a819-dab5-46b4-9b90-0b9769eabdb8", Locale.ENGLISH.getLanguage()).getLocation());
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
index 9017a9b..36286e0 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
@@ -31,6 +31,7 @@ import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.io.IOUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AbstractTaskTO;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.lib.to.AttrTO;
@@ -166,6 +167,7 @@ public class MigrationITCase extends AbstractTaskITCase {
private String setupConnector() {
ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+ connInstanceTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connInstanceTO.setLocation(connectorServerLocation);
connInstanceTO.setConnectorName("net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector");
connInstanceTO.setBundleName("net.tirasa.connid.bundles.db.scriptedsql");
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index 751ce0e..8f881de 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -39,6 +39,7 @@ import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.syncope.client.console.commons.ConnIdSpecialName;
import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
+import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -610,6 +611,36 @@ public class ResourceITCase extends AbstractITCase {
}
@Test
+ public void authorizations() {
+ SyncopeClient puccini = clientFactory.create("puccini", ADMIN_PWD);
+ ResourceService prs = puccini.getService(ResourceService.class);
+
+ // 1. attempt to read a resource for a connector with a different admin realm: fail
+ try {
+ prs.read(RESOURCE_NAME_WS1);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+ }
+
+ // 2. read and upate a resource for a connector in the realm for which entitlements are owned: succeed
+ try {
+ ResourceTO scriptedsql = prs.read(RESOURCE_NAME_DBSCRIPTED);
+ assertEquals(TraceLevel.ALL, scriptedsql.getCreateTraceLevel());
+
+ scriptedsql.setCreateTraceLevel(TraceLevel.FAILURES);
+ prs.update(scriptedsql);
+
+ scriptedsql = prs.read(RESOURCE_NAME_DBSCRIPTED);
+ assertEquals(TraceLevel.FAILURES, scriptedsql.getCreateTraceLevel());
+ } finally {
+ ResourceTO scriptedsql = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+ scriptedsql.setCreateTraceLevel(TraceLevel.ALL);
+ resourceService.update(scriptedsql);
+ }
+ }
+
+ @Test
public void issueSYNCOPE323() {
ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
assertNotNull(actual);
[3/4] syncope git commit: [SYNCOPE-1143] Now connector instances
require an admin realm,
which is used to enforce access control on it for administrative purposes
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index f3ada03..5b7ec8e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -191,7 +191,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(
- user.getRealm().getFullPath(), AnyTypeKind.USER, user.getKey());
+ user.getRealm().getFullPath(), AnyTypeKind.USER.name(), user.getKey());
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
index 449b0f3..bd5a108 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -38,7 +38,7 @@ public abstract class AbstractAny<P extends PlainAttr<?>> extends AbstractAnnota
private static final long serialVersionUID = -2666540708092702810L;
- @ManyToOne(fetch = FetchType.EAGER)
+ @ManyToOne(fetch = FetchType.EAGER, optional = false)
private JPARealm realm;
private String workflowId;
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index c7da0ae..7678fc2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -32,6 +32,7 @@ import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@@ -41,6 +42,7 @@ import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@@ -57,6 +59,9 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
private static final int DEFAULT_TIMEOUT = 10;
+ @ManyToOne(fetch = FetchType.EAGER, optional = false)
+ private JPARealm adminRealm;
+
/**
* URI identifying the local / remote ConnId location where the related connector bundle is found.
*/
@@ -125,6 +130,17 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
private JPAConnPoolConf poolConf;
@Override
+ public Realm getAdminRealm() {
+ return adminRealm;
+ }
+
+ @Override
+ public void setAdminRealm(final Realm adminRealm) {
+ checkType(adminRealm, JPARealm.class);
+ this.adminRealm = (JPARealm) adminRealm;
+ }
+
+ @Override
public String getLocation() {
return location;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
index b8eb01a..5020adb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
@@ -23,18 +23,30 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.ConnConfPropSchema;
import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
@Transactional("Master")
@@ -45,21 +57,44 @@ public class ConnInstanceTest extends AbstractTest {
@Test
public void findAll() {
- List<ConnInstance> connectors = connInstanceDAO.findAll();
- assertNotNull(connectors);
- assertFalse(connectors.isEmpty());
+ List<GrantedAuthority> authorities = CollectionUtils.collect(StandardEntitlement.values(),
+ new Transformer<String, GrantedAuthority>() {
+
+ @Override
+ public GrantedAuthority transform(final String entitlement) {
+ return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+ }
+ }, new ArrayList<GrantedAuthority>());
+
+ UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+ new org.springframework.security.core.userdetails.User(
+ "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+ auth.setDetails(new SyncopeAuthenticationDetails("Master"));
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ try {
+ List<ConnInstance> connectors = connInstanceDAO.findAll();
+ assertNotNull(connectors);
+ assertFalse(connectors.isEmpty());
+ } finally {
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
}
@Test
public void findById() {
- ConnInstance connectorInstance = connInstanceDAO.find("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
-
- assertNotNull("findById did not work", connectorInstance);
-
+ ConnInstance connInstance = connInstanceDAO.find("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
+ assertNotNull(connInstance);
assertEquals("invalid connector name",
- "net.tirasa.connid.bundles.soap.WebServiceConnector", connectorInstance.getConnectorName());
-
- assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connectorInstance.getBundleName());
+ "net.tirasa.connid.bundles.soap.WebServiceConnector", connInstance.getConnectorName());
+ assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connInstance.getBundleName());
+
+ try {
+ connInstanceDAO.authFind("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
+ fail();
+ } catch (DelegatedAdministrationException e) {
+ assertNotNull(e);
+ }
}
@Test
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
index 3fcf4ae..03b516d 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
@@ -39,6 +39,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -74,6 +75,13 @@ public class ResourceTest extends AbstractTest {
return "7f55b09c-b573-41dc-a9eb-ccd80bd3ea7a".equals(item.getKey());
}
}));
+
+ try {
+ resourceDAO.authFind("ws-target-resource-1");
+ fail();
+ } catch (DelegatedAdministrationException e) {
+ assertNotNull(e);
+ }
}
@Test
@@ -91,13 +99,6 @@ public class ResourceTest extends AbstractTest {
}
@Test
- public void findAllByPriority() {
- List<ExternalResource> resources = resourceDAO.findAllByPriority();
- assertNotNull(resources);
- assertFalse(resources.isEmpty());
- }
-
- @Test
public void getConnObjectKey() {
ExternalResource resource = resourceDAO.find("ws-target-resource-2");
assertNotNull(resource);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 83bacf0..717535f 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -274,6 +274,18 @@ under the License.
<SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="Search for realm evenTwo"/>
<SyncopeRole_Realm role_id="Search for realm evenTwo" realm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"/>
+ <SyncopeRole id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_READ" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_UPDATE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_DELETE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="CONNECTOR_LIST" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_READ" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_UPDATE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_DELETE" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_entitlements entitlement="RESOURCE_LIST" role_id="Connector and Resource for realm evenTwo"/>
+ <SyncopeRole_Realm role_id="Connector and Resource for realm evenTwo"
+ realm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"/>
+
<SyncopeUser id="1417acbe-cbf6-4277-9372-e75e04f97000" workflowId="4" status="active"
password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
realm_id="c5b75db1-fce7-470f-b780-3b9934d82a9d"
@@ -303,6 +315,7 @@ under the License.
username="puccini" creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
<SyncopeUser_SyncopeRole user_id="823074dc-d280-436d-a7dd-07399fae48ec" role_id="Search for realm evenTwo"/>
+ <SyncopeUser_SyncopeRole user_id="823074dc-d280-436d-a7dd-07399fae48ec" role_id="Connector and Resource for realm evenTwo"/>
<SyncopeGroup id="37d15e4c-cdc1-460b-a591-8505c8133806" name="root"
realm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -614,6 +627,7 @@ under the License.
<GPlainAttrValue attribute_id="22690472-ed3f-4972-8979-4c9251fab044" id="e16765e6-f806-469e-ae34-1ddf56f2102a" stringValue="r13"/>
<ConnInstance id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" displayName="ConnInstance100"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.soap"
connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
@@ -625,6 +639,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="SEARCH"/>
<ConnInstance id="5aa5b8be-7521-481a-9651-c557aea078c1" displayName="H2"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
bundleName="net.tirasa.connid.bundles.db.table"
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
@@ -638,6 +653,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="SYNC"/>
<ConnInstance id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" displayName="ConnInstance102"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.soap"
connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
@@ -650,6 +666,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="SEARCH"/>
<ConnInstance id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" displayName="ConnInstance103"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.soap"
connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
@@ -657,6 +674,7 @@ under the License.
jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
<ConnInstance id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" displayName="CSVDir"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
bundleName="net.tirasa.connid.bundles.csvdir"
connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
@@ -668,7 +686,9 @@ under the License.
<ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SEARCH"/>
<ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SYNC"/>
- <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
+ <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef"
+ bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="${connid.location}"
connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
version="${connid.ldap.version}"
@@ -679,6 +699,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="SEARCH"/>
<ConnInstance id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" displayName="H2-test2"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
bundleName="net.tirasa.connid.bundles.db.table"
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
@@ -690,6 +711,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="SYNC"/>
<ConnInstance id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" bundleName="net.tirasa.connid.bundles.db.table"
+ adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
displayName="H2-testpull" version="${connid.database.version}"
@@ -700,6 +722,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="SEARCH"/>
<ConnInstance id="a6d017fd-a705-4507-bb7c-6ab6a6745997" bundleName="net.tirasa.connid.bundles.db.scriptedsql"
+ adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
displayName="Scripted SQL" version="${connid.database.version}"
@@ -711,6 +734,7 @@ under the License.
<ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SYNC"/>
<ConnInstance id="44c02549-19c3-483c-8025-4919c3283c37" bundlename="net.tirasa.connid.bundles.rest"
+ adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
connectorname="net.tirasa.connid.bundles.rest.RESTConnector"
displayname="REST" version="${connid.rest.version}"
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
index d4949d8..4fd3db7 100644
--- a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -185,6 +185,7 @@ we are happy to inform you that the password request was successfully executed f
<Notification_events notification_id="71769807-7f74-4dc3-ba61-e4a7a00eb8ad" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
<ConnInstance id="b7ea96c3-c633-488b-98a0-b52ac35850f7" bundleName="net.tirasa.connid.bundles.ldap" displayName="LDAP"
+ adminRealm_id="ea696a4f-e77a-4ef1-be67-8f8093bc8686"
location="${connid.location}"
connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
version="${connid.ldap.version}"
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
index 49810c7..a21e1de 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
@@ -21,6 +21,9 @@ package org.apache.syncope.core.provisioning.api.utils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
public final class RealmUtils {
@@ -57,6 +60,50 @@ public final class RealmUtils {
return normalized;
}
+ private static class StartsWithPredicate implements Predicate<String> {
+
+ private final Collection<String> targets;
+
+ StartsWithPredicate(final Collection<String> targets) {
+ this.targets = targets;
+ }
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return IterableUtils.matchesAny(targets, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String target) {
+ return realm.startsWith(target);
+ }
+ });
+ }
+
+ }
+
+ public static class DynRealmsPredicate implements Predicate<String> {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return !realm.startsWith("/");
+ }
+ }
+
+ public static Set<String> getEffective(final Set<String> allowedRealms, final String requestedRealm) {
+ Set<String> allowed = RealmUtils.normalize(allowedRealms);
+ Set<String> requested = new HashSet<>();
+ requested.add(requestedRealm);
+
+ Set<String> effective = new HashSet<>();
+ CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
+ CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
+
+ // includes dynamic realms
+ CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
+
+ return effective;
+ }
+
private RealmUtils() {
// empty constructor for static utility class
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index e63eb2c..901acc2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -90,6 +90,7 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory, Sy
}
ConnInstance override = entityFactory.newEntity(ConnInstance.class);
+ override.setAdminRealm(connInstance.getAdminRealm());
override.setConnectorName(connInstance.getConnectorName());
override.setDisplayName(connInstance.getDisplayName());
override.setBundleName(connInstance.getBundleName());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
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 ba4d62d..06a8021 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,8 +24,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
@@ -37,9 +35,11 @@ import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceHistoryConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.ConnInstanceHistoryConf;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
import org.identityconnectors.framework.api.ConfigurationProperties;
@@ -54,7 +54,7 @@ import org.springframework.stereotype.Component;
@Component
public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
- private static final String[] IGNORE_PROPERTIES = { "poolConf", "location" };
+ private static final String[] IGNORE_PROPERTIES = { "poolConf", "location", "adminRealm" };
@Autowired
private ConnIdBundleManager connIdBundleManager;
@@ -66,6 +66,9 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
private ConnInstanceHistoryConfDAO connInstanceHistoryConfDAO;
@Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
private ConfDAO confDAO;
@Autowired
@@ -98,6 +101,12 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
ConnInstance connInstance = entityFactory.newEntity(ConnInstance.class);
BeanUtils.copyProperties(connInstanceTO, connInstance, IGNORE_PROPERTIES);
+ if (connInstanceTO.getAdminRealm() != null) {
+ connInstance.setAdminRealm(realmDAO.findByFullPath(connInstanceTO.getAdminRealm()));
+ }
+ if (connInstance.getAdminRealm() == null) {
+ sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+ }
if (connInstanceTO.getLocation() != null) {
connInstance.setLocation(connInstanceTO.getLocation());
}
@@ -116,7 +125,7 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
@Override
public ConnInstance update(final ConnInstanceTO connInstanceTO) {
- ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+ ConnInstance connInstance = connInstanceDAO.authFind(connInstanceTO.getKey());
if (connInstance == null) {
throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
}
@@ -143,6 +152,16 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
connInstance.getCapabilities().clear();
connInstance.getCapabilities().addAll(connInstanceTO.getCapabilities());
+ if (connInstanceTO.getAdminRealm() != null) {
+ Realm realm = realmDAO.findByFullPath(connInstanceTO.getAdminRealm());
+ if (realm == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+ throw sce;
+ }
+ connInstance.setAdminRealm(realm);
+ }
+
if (connInstanceTO.getLocation() != null) {
connInstance.setLocation(connInstanceTO.getLocation());
}
@@ -181,9 +200,9 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
try {
connInstance = connInstanceDAO.save(connInstance);
} catch (Exception e) {
- SyncopeClientException ex = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
- ex.getElements().add(e.getMessage());
- throw ex;
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
+ sce.getElements().add(e.getMessage());
+ throw sce;
}
return connInstance;
@@ -220,25 +239,18 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
Pair<URI, ConnectorInfo> info = connIdBundleManager.getConnectorInfo(connInstance);
BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
+ connInstanceTO.setAdminRealm(connInstance.getAdminRealm().getFullPath());
connInstanceTO.setLocation(info.getLeft().toASCIIString());
// refresh stored properties in the given connInstance with direct information from underlying connector
ConfigurationProperties properties = connIdBundleManager.getConfigurationProperties(info.getRight());
for (final String propName : properties.getPropertyNames()) {
ConnConfPropSchema schema = build(properties.getProperty(propName));
- ConnConfProperty property = IterableUtils.find(connInstanceTO.getConf(),
- new Predicate<ConnConfProperty>() {
-
- @Override
- public boolean evaluate(final ConnConfProperty candidate) {
- return propName.equals(candidate.getSchema().getName());
- }
- });
+ ConnConfProperty property = connInstanceTO.getConf(propName);
if (property == null) {
property = new ConnConfProperty();
connInstanceTO.getConf().add(property);
}
-
property.setSchema(schema);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
index 0ee414a..392ce41 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
@@ -24,7 +24,7 @@ public class DelegatedAdministrationException extends RuntimeException {
private static final long serialVersionUID = 7540587364235915081L;
- public DelegatedAdministrationException(final String realm, final AnyTypeKind type, final String key) {
+ public DelegatedAdministrationException(final String realm, final String type, final String key) {
super("Missing entitlement or realm administration under " + realm + " for "
+ (key == null
? "new " + type
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
index c5190b3..5bed533 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -38,12 +38,15 @@ import java.util.Set;
import java.util.UUID;
import javax.ws.rs.core.Response;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.ConnBundleTO;
import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
@@ -54,6 +57,7 @@ import org.apache.syncope.common.lib.to.MappingTO;
import org.apache.syncope.common.lib.to.ProvisionTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ConnConfPropSchema;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
@@ -117,6 +121,7 @@ public class ConnectorITCase extends AbstractITCase {
@Test
public void create() {
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connectorTO.setLocation(connectorService.read(
"88a7a819-dab5-46b4-9b90-0b9769eabdb8", Locale.ENGLISH.getLanguage()).getLocation());
connectorTO.setVersion(connIdSoapVersion);
@@ -217,6 +222,7 @@ public class ConnectorITCase extends AbstractITCase {
@Test
public void update() {
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
// set connector instance key
connectorTO.setKey("fcf9f2b0-f7d6-42c9-84a6-61b28255a42b");
@@ -358,6 +364,7 @@ public class ConnectorITCase extends AbstractITCase {
@Test
public void validate() {
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connectorTO.setLocation(connectorServerLocation);
connectorTO.setVersion(connIdDbVersion);
connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
@@ -519,6 +526,52 @@ public class ConnectorITCase extends AbstractITCase {
}
@Test
+ public void authorizations() {
+ SyncopeClient puccini = clientFactory.create("puccini", ADMIN_PWD);
+ ConnectorService pcs = puccini.getService(ConnectorService.class);
+
+ // 1. list connectors: get only the ones allowed
+ List<ConnInstanceTO> connInstances = pcs.list(null);
+ assertEquals(2, connInstances.size());
+
+ assertTrue(IterableUtils.matchesAll(connInstances, new Predicate<ConnInstanceTO>() {
+
+ @Override
+ public boolean evaluate(final ConnInstanceTO object) {
+ return "a6d017fd-a705-4507-bb7c-6ab6a6745997".equals(object.getKey())
+ || "44c02549-19c3-483c-8025-4919c3283c37".equals(object.getKey());
+ }
+ }));
+
+ // 2. attempt to read a connector with a different admin realm: fail
+ try {
+ pcs.read("88a7a819-dab5-46b4-9b90-0b9769eabdb8", null);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+ }
+
+ // 3. read and upate a connector in the realm for which entitlements are owned: succeed
+ try {
+ ConnInstanceTO scriptedsql = pcs.read("a6d017fd-a705-4507-bb7c-6ab6a6745997", null);
+ ConnConfProperty reloadScriptOnExecution = scriptedsql.getConf("reloadScriptOnExecution");
+ assertEquals("true", reloadScriptOnExecution.getValues().get(0).toString());
+
+ reloadScriptOnExecution.getValues().set(0, "false");
+ pcs.update(scriptedsql);
+
+ scriptedsql = pcs.read(scriptedsql.getKey(), null);
+ reloadScriptOnExecution = scriptedsql.getConf("reloadScriptOnExecution");
+ assertEquals("false", reloadScriptOnExecution.getValues().get(0).toString());
+ } finally {
+ ConnInstanceTO scriptedsql = connectorService.read("a6d017fd-a705-4507-bb7c-6ab6a6745997", null);
+ ConnConfProperty reloadScriptOnExecution = scriptedsql.getConf("reloadScriptOnExecution");
+ reloadScriptOnExecution.getValues().set(0, "true");
+ connectorService.update(scriptedsql);
+ }
+ }
+
+ @Test
public void issueSYNCOPE10() {
// ----------------------------------
// Copy resource and connector in order to create new objects.
@@ -616,6 +669,7 @@ public class ConnectorITCase extends AbstractITCase {
// Create a new connector
// ----------------------------------------
ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connectorTO.setLocation(connectorService.read(
"88a7a819-dab5-46b4-9b90-0b9769eabdb8", Locale.ENGLISH.getLanguage()).getLocation());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
index 9017a9b..36286e0 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
@@ -31,6 +31,7 @@ import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.io.IOUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AbstractTaskTO;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.lib.to.AttrTO;
@@ -166,6 +167,7 @@ public class MigrationITCase extends AbstractTaskITCase {
private String setupConnector() {
ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+ connInstanceTO.setAdminRealm(SyncopeConstants.ROOT_REALM);
connInstanceTO.setLocation(connectorServerLocation);
connInstanceTO.setConnectorName("net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector");
connInstanceTO.setBundleName("net.tirasa.connid.bundles.db.scriptedsql");
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index 751ce0e..8f881de 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -39,6 +39,7 @@ import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.syncope.client.console.commons.ConnIdSpecialName;
import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
+import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -610,6 +611,36 @@ public class ResourceITCase extends AbstractITCase {
}
@Test
+ public void authorizations() {
+ SyncopeClient puccini = clientFactory.create("puccini", ADMIN_PWD);
+ ResourceService prs = puccini.getService(ResourceService.class);
+
+ // 1. attempt to read a resource for a connector with a different admin realm: fail
+ try {
+ prs.read(RESOURCE_NAME_WS1);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+ }
+
+ // 2. read and upate a resource for a connector in the realm for which entitlements are owned: succeed
+ try {
+ ResourceTO scriptedsql = prs.read(RESOURCE_NAME_DBSCRIPTED);
+ assertEquals(TraceLevel.ALL, scriptedsql.getCreateTraceLevel());
+
+ scriptedsql.setCreateTraceLevel(TraceLevel.FAILURES);
+ prs.update(scriptedsql);
+
+ scriptedsql = prs.read(RESOURCE_NAME_DBSCRIPTED);
+ assertEquals(TraceLevel.FAILURES, scriptedsql.getCreateTraceLevel());
+ } finally {
+ ResourceTO scriptedsql = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+ scriptedsql.setCreateTraceLevel(TraceLevel.ALL);
+ resourceService.update(scriptedsql);
+ }
+ }
+
+ @Test
public void issueSYNCOPE323() {
ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
assertNotNull(actual);
[2/4] syncope git commit: [SYNCOPE-1143] Now connector instances
require an admin realm,
which is used to enforce access control on it for administrative purposes
Posted by il...@apache.org.
[SYNCOPE-1143] Now connector instances require an admin realm, which is used to enforce access control on it for administrative purposes
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/b5d6dc4a
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/b5d6dc4a
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/b5d6dc4a
Branch: refs/heads/2_0_X
Commit: b5d6dc4aab3026374ff263a90d76b802a823173e
Parents: 699b3c6
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jul 10 18:35:33 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jul 10 18:35:33 2017 +0200
----------------------------------------------------------------------
.../client/console/SyncopeConsoleSession.java | 28 ++++-----
.../client/console/panels/RealmChoicePanel.java | 11 ++--
.../client/console/topology/Topology.java | 49 +++++++++------
.../console/wizards/any/AnyWizardBuilder.java | 7 +--
.../client/console/wizards/any/Details.java | 3 +-
.../console/wizards/any/UserWizardBuilder.java | 1 -
.../resources/ConnectorDetailsPanel.java | 49 +++++++++++++++
.../resources/ConnectorDetailsPanel.html | 4 ++
.../resources/ConnectorDetailsPanel.properties | 1 +
.../ConnectorDetailsPanel_it.properties | 1 +
.../ConnectorDetailsPanel_pt_BR.properties | 1 +
.../ConnectorDetailsPanel_ru.properties | 1 +
.../syncope/common/lib/to/ConnInstanceTO.java | 10 +++
.../syncope/core/logic/AbstractAnyLogic.java | 53 ++--------------
.../syncope/core/logic/AnyObjectLogic.java | 23 +++----
.../syncope/core/logic/ConnectorLogic.java | 53 +++++++++++++++-
.../apache/syncope/core/logic/GroupLogic.java | 30 ++++-----
.../syncope/core/logic/ResourceLogic.java | 66 +++++++++++++++++---
.../apache/syncope/core/logic/UserLogic.java | 38 +++++------
.../persistence/api/dao/ConnInstanceDAO.java | 2 +
.../api/dao/ExternalResourceDAO.java | 6 +-
.../persistence/api/entity/ConnInstance.java | 4 ++
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 2 +-
.../persistence/jpa/dao/JPAConnInstanceDAO.java | 54 +++++++++++++++-
.../jpa/dao/JPAExternalResourceDAO.java | 49 ++++++++++-----
.../core/persistence/jpa/dao/JPAGroupDAO.java | 2 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 2 +-
.../persistence/jpa/entity/AbstractAny.java | 2 +-
.../persistence/jpa/entity/JPAConnInstance.java | 16 +++++
.../persistence/jpa/inner/ConnInstanceTest.java | 55 +++++++++++++---
.../persistence/jpa/inner/ResourceTest.java | 15 ++---
.../test/resources/domains/MasterContent.xml | 26 +++++++-
.../src/test/resources/domains/TwoContent.xml | 1 +
.../core/provisioning/api/utils/RealmUtils.java | 47 ++++++++++++++
.../provisioning/java/ConnectorManager.java | 1 +
.../java/data/ConnInstanceDataBinderImpl.java | 44 ++++++++-----
.../DelegatedAdministrationException.java | 2 +-
.../syncope/fit/core/ConnectorITCase.java | 54 ++++++++++++++++
.../syncope/fit/core/MigrationITCase.java | 2 +
.../apache/syncope/fit/core/ResourceITCase.java | 31 +++++++++
40 files changed, 632 insertions(+), 214 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index af8295a..ab84d10 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -19,9 +19,10 @@
package org.apache.syncope.client.console;
import java.text.DateFormat;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -29,9 +30,9 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
-import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.list.SetUniqueList;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.lang3.tuple.Pair;
@@ -217,25 +218,18 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
return selfTO;
}
- public Set<String> getAvailableRealms(final String... entitlements) {
- final Set<String> availableRealms = new HashSet<>();
- if (entitlements != null && entitlements.length > 0) {
- for (String entitlement : entitlements) {
- final Set<String> realms = auth.get(entitlement);
- if (CollectionUtils.isNotEmpty(realms)) {
- availableRealms.addAll(realms);
- }
- }
- } else {
- for (Map.Entry<String, Set<String>> entitlement : auth.entrySet()) {
- availableRealms.addAll(entitlement.getValue());
- }
+ public List<String> getAuthRealms() {
+ List<String> sortable = new ArrayList<>();
+ List<String> available = SetUniqueList.setUniqueList(sortable);
+ for (Map.Entry<String, Set<String>> entitlement : auth.entrySet()) {
+ available.addAll(entitlement.getValue());
}
- return availableRealms;
+ Collections.sort(sortable);
+ return sortable;
}
public boolean owns(final String entitlements) {
- return owns(entitlements, "/");
+ return owns(entitlements, SyncopeConstants.ROOT_REALM);
}
public boolean owns(final String entitlements, final String realm) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
index 4a0ee0a..a141a72 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -27,12 +27,12 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.image.GlyphIconType;
import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.StringUtils;
@@ -72,7 +72,7 @@ public class RealmChoicePanel extends Panel {
private final Model<RealmTO> model;
- private final Set<String> availableRealms;
+ private final Collection<String> availableRealms;
private final Map<String, Pair<RealmTO, List<RealmTO>>> tree;
@@ -146,13 +146,13 @@ public class RealmChoicePanel extends Panel {
container.setOutputMarkupId(true);
add(container);
- availableRealms = SyncopeConsoleSession.get().getAvailableRealms();
+ availableRealms = SyncopeConsoleSession.get().getAuthRealms();
reloadRealmTree();
}
public final void reloadRealmTree() {
- final Label realmLabel = new Label("realmLabel", new Model<String>());
+ final Label realmLabel = new Label("realmLabel", new Model<>());
realmLabel.setOutputMarkupId(true);
container.addOrReplace(realmLabel);
@@ -186,7 +186,6 @@ public class RealmChoicePanel extends Panel {
@Override
public void onClick(final AjaxRequestTarget target) {
-
}
@Override
@@ -288,7 +287,7 @@ public class RealmChoicePanel extends Panel {
@Override
public boolean evaluate(final String availableRealm) {
- return "/".equals(availableRealm)
+ return SyncopeConstants.ROOT_REALM.equals(availableRealm)
|| realmTO.getKey().equals(availableRealm);
}
});
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index d2ba682..606a32d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -22,10 +22,13 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.jaxrs.client.WebClient;
@@ -39,6 +42,7 @@ import org.apache.syncope.client.console.rest.ResourceRestClient;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -92,8 +96,8 @@ public class Topology extends BasePage {
}
};
- private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel
- = new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
+ private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel =
+ new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
private static final long serialVersionUID = 5275935387613157432L;
@@ -116,8 +120,8 @@ public class Topology extends BasePage {
}
};
- private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel
- = new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
+ private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel =
+ new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
private static final long serialVersionUID = 5275935387613157433L;
@@ -177,7 +181,7 @@ public class Topology extends BasePage {
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
target.appendJavaScript("zoomIn($('#drawing')[0]);");
}
- }, ActionLink.ActionType.ZOOM_IN, StandardEntitlement.RESOURCE_LIST).disableIndicator().hideLabel();
+ }, ActionLink.ActionType.ZOOM_IN, StandardEntitlement.CONNECTOR_LIST).disableIndicator().hideLabel();
zoomActionPanel.add(new ActionLink<Serializable>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -186,7 +190,7 @@ public class Topology extends BasePage {
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
target.appendJavaScript("zoomOut($('#drawing')[0]);");
}
- }, ActionLink.ActionType.ZOOM_OUT, StandardEntitlement.RESOURCE_LIST).disableIndicator().hideLabel();
+ }, ActionLink.ActionType.ZOOM_OUT, StandardEntitlement.CONNECTOR_LIST).disableIndicator().hideLabel();
body.add(zoomActionPanel);
// -----------------------------------------
@@ -366,24 +370,31 @@ public class Topology extends BasePage {
// -----------------------------------------
// Add Resources
// -----------------------------------------
+ final Collection<String> administrableConns = new HashSet<>();
+ for (List<ConnInstanceTO> connInstances : connModel.getObject().values()) {
+ administrableConns.addAll(CollectionUtils.collect(connInstances, EntityTOUtils.keyTransformer()));
+ }
+
final List<String> connToBeProcessed = new ArrayList<>();
- for (ResourceTO resourceTO : resModel.getObject()) {
- final TopologyNode topologynode = new TopologyNode(
- resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
+ for (final ResourceTO resourceTO : resModel.getObject()) {
+ if (administrableConns.contains(resourceTO.getConnector())) {
+ final TopologyNode topologynode = new TopologyNode(
+ resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
- final Map<Serializable, TopologyNode> remoteConnections;
+ final Map<Serializable, TopologyNode> remoteConnections;
- if (connections.containsKey(resourceTO.getConnector())) {
- remoteConnections = connections.get(resourceTO.getConnector());
- } else {
- remoteConnections = new HashMap<>();
- connections.put(resourceTO.getConnector(), remoteConnections);
- }
+ if (connections.containsKey(resourceTO.getConnector())) {
+ remoteConnections = connections.get(resourceTO.getConnector());
+ } else {
+ remoteConnections = new HashMap<>();
+ connections.put(resourceTO.getConnector(), remoteConnections);
+ }
- remoteConnections.put(topologynode.getKey(), topologynode);
+ remoteConnections.put(topologynode.getKey(), topologynode);
- if (!connToBeProcessed.contains(resourceTO.getConnector())) {
- connToBeProcessed.add(resourceTO.getConnector());
+ if (!connToBeProcessed.contains(resourceTO.getConnector())) {
+ connToBeProcessed.add(resourceTO.getConnector());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 9b3bce6..37377ef 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -152,15 +152,14 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde
}
protected Details<A> addOptionalDetailsPanel(final AnyWrapper<A> modelObject) {
-
- if (modelObject.getInnerObject().getKey() != null) {
+ if (modelObject.getInnerObject().getKey() == null) {
+ return null;
+ } else {
return new Details<>(
modelObject,
mode == AjaxWizard.Mode.TEMPLATE,
true,
pageRef);
- } else {
- return null;
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
index e5a92d2..a7dd79a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
@@ -73,8 +73,7 @@ public class Details<T extends AnyTO> extends WizardStep {
"destinationRealm", "destinationRealm", new PropertyModel<String>(inner, "realm"), false);
((AjaxDropDownChoicePanel<String>) realm).setChoices(CollectionUtils.collect(
- realms,
- new Transformer<RealmTO, String>() {
+ realms, new Transformer<RealmTO, String>() {
@Override
public String transform(final RealmTO input) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index f56e24d..6cf6023 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -104,7 +104,6 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
@Override
protected Details<UserTO> addOptionalDetailsPanel(final AnyWrapper<UserTO> modelObject) {
-
return new UserDetails(
UserWrapper.class.cast(modelObject),
mode == AjaxWizard.Mode.TEMPLATE,
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
index 89c692f..43d4d85 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
@@ -19,12 +19,16 @@
package org.apache.syncope.client.console.wizards.resources;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.RealmRestClient;
import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
@@ -32,19 +36,64 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPa
import org.apache.syncope.common.lib.to.ConnBundleTO;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
public class ConnectorDetailsPanel extends WizardStep {
private static final long serialVersionUID = -2435937897614232137L;
+ private final LoadableDetachableModel<List<String>> realms;
+
public ConnectorDetailsPanel(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
super();
setOutputMarkupId(true);
+ final List<String> authRealms = SyncopeConsoleSession.get().getAuthRealms();
+ realms = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ List<RealmTO> allRealms = new RealmRestClient().list();
+ CollectionUtils.filter(allRealms, new Predicate<RealmTO>() {
+
+ @Override
+ public boolean evaluate(final RealmTO realm) {
+ return IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String fullpath) {
+ return realm.getFullPath().startsWith(fullpath);
+ }
+ });
+ }
+ });
+
+ List<String> result = CollectionUtils.collect(allRealms, new Transformer<RealmTO, String>() {
+
+ @Override
+ public String transform(final RealmTO realm) {
+ return realm.getFullPath();
+ }
+ }, new ArrayList<String>());
+ Collections.sort(result);
+ return result;
+ }
+ };
+
+ AjaxDropDownChoicePanel<String> realm = new AjaxDropDownChoicePanel<>(
+ "adminRealm", "adminRealm", new PropertyModel<String>(connInstanceTO, "adminRealm"), false);
+ realm.setChoices(realms);
+ realm.setOutputMarkupId(true);
+ realm.addRequiredLabel();
+ add(realm);
+
AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
"displayName", "displayName", new PropertyModel<String>(connInstanceTO, "displayName"), false);
displayName.setOutputMarkupId(true);
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
index 87fc624..01ac512 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
@@ -23,6 +23,10 @@ under the License.
<body>
<wicket:panel>
<div class="form-group">
+ <span wicket:id="adminRealm">[adminRealm]</span>
+ </div>
+
+ <div class="form-group">
<span wicket:id="displayName">[displayName]</span>
</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
index 6c11adc..23711a9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
@@ -24,3 +24,4 @@ poolMinIdle=Min idle objects
poolMaxIdle=Max idle objects
poolMaxWait=Max waiting time (msec)
poolMinEvictableIdleTime=Min eviction time (msec)
+adminRealm=Administration Realm
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
index ed69987..0fd9aa7 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
@@ -24,3 +24,4 @@ poolMinIdle=Max oggetti attivi
poolMaxIdle=Max oggetti inattivi
poolMaxWait=Tempo max attesa
poolMinEvictableIdleTime=Tempo min espulsione
+adminRealm=Realm di amministrazione
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
index a2915b1..db06733 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
@@ -24,3 +24,4 @@ poolMinIdle=Min idle objects
poolMaxIdle=Max idle objects
poolMaxWait=Max waiting time (msec)
poolMinEvictableIdleTime=Min eviction time (msec)
+adminRealm=Administration Realm
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
index 0194990..c5d4b3f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
@@ -25,3 +25,4 @@ poolMinIdle=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0431\u044a\u0435\
poolMaxIdle=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438
poolMaxWait=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f (\u043c\u0441)
poolMinEvictableIdleTime=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f (\u043c\u0441)
+adminRealm=Administration Realm
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
index d7c8be7..9440972 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
@@ -42,6 +42,8 @@ public class ConnInstanceTO extends AbstractBaseBean implements EntityTO {
private String key;
+ private String adminRealm;
+
private String location;
private String connectorName;
@@ -71,6 +73,14 @@ public class ConnInstanceTO extends AbstractBaseBean implements EntityTO {
this.key = key;
}
+ public String getAdminRealm() {
+ return adminRealm;
+ }
+
+ public void setAdminRealm(final String adminRealm) {
+ this.adminRealm = adminRealm;
+ }
+
public String getLocation() {
return location;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 7c96979..bf83632 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -19,7 +19,6 @@
package org.apache.syncope.core.logic;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -40,7 +39,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.spring.ApplicationContextProvider;
@@ -53,6 +51,7 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.LogicActions;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -230,50 +229,6 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
return result;
}
- private static class StartsWithPredicate implements Predicate<String> {
-
- private final Collection<String> targets;
-
- StartsWithPredicate(final Collection<String> targets) {
- this.targets = targets;
- }
-
- @Override
- public boolean evaluate(final String realm) {
- return IterableUtils.matchesAny(targets, new Predicate<String>() {
-
- @Override
- public boolean evaluate(final String target) {
- return realm.startsWith(target);
- }
- });
- }
-
- }
-
- protected static class DynRealmsPredicate implements Predicate<String> {
-
- @Override
- public boolean evaluate(final String realm) {
- return !realm.startsWith("/");
- }
- }
-
- protected Set<String> getEffectiveRealms(final Set<String> allowedRealms, final String requestedRealm) {
- Set<String> allowed = RealmUtils.normalize(allowedRealms);
- Set<String> requested = new HashSet<>();
- requested.add(requestedRealm);
-
- Set<String> effective = new HashSet<>();
- CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
- CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
-
- // includes dynamic realms
- CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
-
- return effective;
- }
-
protected boolean securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
@@ -293,15 +248,15 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
if (!authorized) {
throw new DelegatedAdministrationException(
realm,
- this instanceof UserLogic
+ (this instanceof UserLogic
? AnyTypeKind.USER
: this instanceof GroupLogic
? AnyTypeKind.GROUP
- : AnyTypeKind.ANY_OBJECT,
+ : AnyTypeKind.ANY_OBJECT).name(),
key);
}
- return IterableUtils.matchesAny(effectiveRealms, new DynRealmsPredicate());
+ return IterableUtils.matchesAny(effectiveRealms, new RealmUtils.DynRealmsPredicate());
}
public abstract Date findLastChange(String key);
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 8805221..49d18db 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -109,7 +110,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
throw new UnsupportedOperationException("Need to specify " + AnyType.class.getSimpleName());
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.SEARCH.getFor(searchCond.hasAnyTypeCond())),
realm);
@@ -125,7 +126,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
throw new UnsupportedOperationException("Need to specify " + AnyType.class.getSimpleName());
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.SEARCH.getFor(searchCond.hasAnyTypeCond())),
realm);
@@ -152,7 +153,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
throw SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.CREATE.getFor(before.getLeft().getType())),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -174,7 +175,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
? before.getLeft().getRealm().getValue()
: anyObjectTO.getRealm();
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
realm);
boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
@@ -194,7 +195,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
AnyObjectTO anyObject = binder.getAnyObjectTO(key);
Pair<AnyObjectTO, List<LogicActions>> before = beforeDelete(anyObject);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.DELETE.getFor(before.getLeft().getType())),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -211,7 +212,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
public AnyObjectTO unlink(final String key, final Collection<String> resources) {
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -233,7 +234,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
public AnyObjectTO link(final String key, final Collection<String> resources) {
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -257,7 +258,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -285,7 +286,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -309,7 +310,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -332,7 +333,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index e84dfe5..6532936 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -26,6 +26,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.PredicateUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.ArrayUtils;
@@ -44,6 +46,9 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
import org.apache.syncope.core.provisioning.api.ConnectorFactory;
import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.common.l10n.CurrentLocale;
import org.identityconnectors.framework.api.ConfigurationProperties;
import org.identityconnectors.framework.api.ConnectorInfo;
@@ -75,23 +80,61 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
@Autowired
private ConnectorFactory connFactory;
+ protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+ boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String ownedRealm) {
+ return realm.startsWith(ownedRealm);
+ }
+ });
+ if (!authorized) {
+ throw new DelegatedAdministrationException(realm, ConnInstance.class.getSimpleName(), key);
+ }
+ }
+
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_CREATE + "')")
public ConnInstanceTO create(final ConnInstanceTO connInstanceTO) {
+ if (connInstanceTO.getAdminRealm() == null) {
+ throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ }
+
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_CREATE),
+ connInstanceTO.getAdminRealm());
+ securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), null);
+
return binder.getConnInstanceTO(connInstanceDAO.save(binder.getConnInstance(connInstanceTO)));
}
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_UPDATE + "')")
public ConnInstanceTO update(final ConnInstanceTO connInstanceTO) {
+ if (connInstanceTO.getAdminRealm() == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
+ sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+ throw sce;
+ }
+
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_UPDATE),
+ connInstanceTO.getAdminRealm());
+ securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), connInstanceTO.getKey());
+
return binder.getConnInstanceTO(binder.update(connInstanceTO));
}
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_DELETE + "')")
public ConnInstanceTO delete(final String key) {
- ConnInstance connInstance = connInstanceDAO.find(key);
+ ConnInstance connInstance = connInstanceDAO.authFind(key);
if (connInstance == null) {
throw new NotFoundException("Connector '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_DELETE),
+ connInstance.getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, connInstance.getAdminRealm().getFullPath(), connInstance.getKey());
+
if (!connInstance.getResources().isEmpty()) {
SyncopeClientException associatedResources = SyncopeClientException.build(
ClientExceptionType.AssociatedResources);
@@ -136,7 +179,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
public ConnInstanceTO read(final String key, final String lang) {
CurrentLocale.set(StringUtils.isBlank(lang) ? Locale.ENGLISH : new Locale(lang));
- ConnInstance connInstance = connInstanceDAO.find(key);
+ ConnInstance connInstance = connInstanceDAO.authFind(key);
if (connInstance == null) {
throw new NotFoundException("Connector '" + key + "'");
}
@@ -183,7 +226,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
public List<ConnIdObjectClassTO> buildObjectClassInfo(
final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
- ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+ ConnInstance connInstance = connInstanceDAO.authFind(connInstanceTO.getKey());
if (connInstance == null) {
throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
}
@@ -214,6 +257,10 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_READ + "')")
@Transactional(readOnly = true)
public void check(final ConnInstanceTO connInstanceTO) {
+ if (connInstanceTO.getAdminRealm() == null) {
+ throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ }
+
connFactory.createConnector(binder.getConnInstance(connInstanceTO)).test();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index ca3e080..7e9b88b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -122,10 +122,10 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
authorized = !CollectionUtils.intersection(groupDAO.findDynRealms(key), effectiveRealms).isEmpty();
}
if (!authorized) {
- throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP, key);
+ throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP.name(), key);
}
- return IterableUtils.matchesAny(effectiveRealms, new AbstractAnyLogic.DynRealmsPredicate());
+ return IterableUtils.matchesAny(effectiveRealms, new RealmUtils.DynRealmsPredicate());
}
@Transactional(readOnly = true)
@@ -177,7 +177,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
@Transactional(readOnly = true)
@Override
public int count(final String realm) {
- return groupDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm));
+ return groupDAO.count(RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm));
}
@PreAuthorize("isAuthenticated()")
@@ -188,7 +188,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
final String realm, final boolean details) {
return CollectionUtils.collect(groupDAO.findAll(
- getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+ RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
page, size, orderBy),
new Transformer<Group, GroupTO>() {
@@ -205,7 +205,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
@Override
public int searchCount(final SearchCond searchCondition, final String realm) {
return searchDAO.count(
- getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+ RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
searchCondition, AnyTypeKind.GROUP);
}
@@ -216,7 +216,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
final List<OrderByClause> orderBy, final String realm, final boolean details) {
List<Group> matchingGroups = searchDAO.search(
- getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+ RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
searchCondition, page, size, orderBy, AnyTypeKind.GROUP);
return CollectionUtils.collect(matchingGroups, new Transformer<Group, GroupTO>() {
@@ -237,7 +237,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_CREATE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -259,7 +259,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
? before.getLeft().getRealm().getValue()
: groupTO.getRealm();
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
realm);
boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
@@ -280,7 +280,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
GroupTO group = binder.getGroupTO(key);
Pair<GroupTO, List<LogicActions>> before = beforeDelete(group);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_DELETE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -312,7 +312,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
public GroupTO unlink(final String key, final Collection<String> resources) {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -335,7 +335,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
public GroupTO link(final String key, final Collection<String> resources) {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -360,7 +360,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -389,7 +389,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -414,7 +414,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -438,7 +438,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 5269c1e..1cde745 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -25,7 +25,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -62,7 +64,10 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -113,6 +118,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@Autowired
private ConnectorFactory connFactory;
+ protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+ boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String ownedRealm) {
+ return realm.startsWith(ownedRealm);
+ }
+ });
+ if (!authorized) {
+ throw new DelegatedAdministrationException(realm, ExternalResource.class.getSimpleName(), key);
+ }
+ }
+
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_CREATE + "')")
public ResourceTO create(final ResourceTO resourceTO) {
if (StringUtils.isBlank(resourceTO.getKey())) {
@@ -121,7 +139,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
throw sce;
}
- if (resourceDAO.find(resourceTO.getKey()) != null) {
+ ConnInstance connInstance = connInstanceDAO.authFind(resourceTO.getConnector());
+ if (connInstance == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidExternalResource);
+ sce.getElements().add("Connector " + resourceTO.getConnector());
+ throw sce;
+ }
+
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_CREATE),
+ connInstance.getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, connInstance.getAdminRealm().getFullPath(), null);
+
+ if (resourceDAO.authFind(resourceTO.getKey()) != null) {
throw new DuplicateException(resourceTO.getKey());
}
@@ -130,17 +160,22 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
public ResourceTO update(final ResourceTO resourceTO) {
- ExternalResource resource = resourceDAO.find(resourceTO.getKey());
+ ExternalResource resource = resourceDAO.authFind(resourceTO.getKey());
if (resource == null) {
throw new NotFoundException("Resource '" + resourceTO.getKey() + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
return binder.getResourceTO(resourceDAO.save(binder.update(resource, resourceTO)));
}
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
public void setLatestSyncToken(final String key, final String anyTypeKey) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
@@ -153,6 +188,11 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
Connector connector;
try {
connector = connFactory.getConnector(resource);
@@ -168,7 +208,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
public void removeSyncToken(final String key, final String anyTypeKey) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
@@ -181,17 +221,27 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
provision.setSyncToken(null);
resourceDAO.save(resource);
}
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_DELETE + "')")
public ResourceTO delete(final String key) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_DELETE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
ResourceTO resourceToDelete = binder.getResourceTO(resource);
resourceDAO.delete(key);
@@ -202,7 +252,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_READ + "')")
@Transactional(readOnly = true)
public ResourceTO read(final String key) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
@@ -225,7 +275,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
private Triple<ExternalResource, AnyType, Provision> connObjectInit(
final String resourceKey, final String anyTypeKey) {
- ExternalResource resource = resourceDAO.find(resourceKey);
+ ExternalResource resource = resourceDAO.authFind(resourceKey);
if (resource == null) {
throw new NotFoundException("Resource '" + resourceKey + "'");
}
@@ -305,7 +355,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
ObjectClass objectClass;
OperationOptions options;
if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
- resource = resourceDAO.find(key);
+ resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 54a43f3..ee68a4e 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -55,6 +55,7 @@ import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -95,8 +96,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
@Transactional(readOnly = true)
@Override
public int count(final String realm) {
- return userDAO.count(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm));
+ return userDAO.count(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm));
}
@PreAuthorize("hasRole('" + StandardEntitlement.USER_SEARCH + "')")
@@ -106,9 +107,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
final int page, final int size, final List<OrderByClause> orderBy,
final String realm, final boolean details) {
- return CollectionUtils.collect(userDAO.findAll(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
- page, size, orderBy),
+ return CollectionUtils.collect(userDAO.findAll(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm), page, size, orderBy),
new Transformer<User, UserTO>() {
@Transactional(readOnly = true)
@@ -138,8 +138,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
@Transactional(readOnly = true)
@Override
public int searchCount(final SearchCond searchCondition, final String realm) {
- return searchDAO.count(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
+ return searchDAO.count(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
searchCondition, AnyTypeKind.USER);
}
@@ -149,8 +149,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public List<UserTO> search(final SearchCond searchCondition, final int page, final int size,
final List<OrderByClause> orderBy, final String realm, final boolean details) {
- List<User> matchingUsers = searchDAO.search(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
+ List<User> matchingUsers = searchDAO.search(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
searchCondition, page, size, orderBy, AnyTypeKind.USER);
return CollectionUtils.collect(matchingUsers, new Transformer<User, UserTO>() {
@@ -195,7 +195,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
}
if (!self) {
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_CREATE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -233,7 +233,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
&& before.getLeft().getRealm() != null
&& StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
before.getLeft().getRealm().getValue());
authDynRealms =
@@ -278,7 +278,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public ProvisioningResult<UserTO> status(final StatusPatch statusPatch, final boolean nullPriorityAsync) {
// security checks
UserTO toUpdate = binder.getUserTO(statusPatch.getKey());
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
toUpdate.getRealm());
securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
@@ -354,7 +354,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
Pair<UserTO, List<LogicActions>> before = beforeDelete(userTO);
if (!self) {
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_DELETE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -391,7 +391,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public UserTO unlink(final String key, final Collection<String> resources) {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -414,7 +414,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public UserTO link(final String key, final Collection<String> resources) {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -439,7 +439,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -468,7 +468,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -498,7 +498,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -522,7 +522,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
index a7ba370..bb27896 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
@@ -25,6 +25,8 @@ public interface ConnInstanceDAO extends DAO<ConnInstance> {
ConnInstance find(String key);
+ ConnInstance authFind(String key);
+
List<ConnInstance> findAll();
ConnInstance save(ConnInstance connector);
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
index 6afa771..b48fd79 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
@@ -30,16 +30,14 @@ public interface ExternalResourceDAO extends DAO<ExternalResource> {
ExternalResource find(String key);
+ ExternalResource authFind(String key);
+
List<Provision> findProvisionsByAuxClass(AnyTypeClass anyTypeClass);
List<ExternalResource> findByPolicy(Policy policy);
- List<ExternalResource> findWithoutPolicy(Class<? extends Policy> policyClass);
-
List<ExternalResource> findAll();
- List<ExternalResource> findAllByPriority();
-
ExternalResource save(ExternalResource resource);
void deleteMapping(String schemaName);
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
index 90650a2..908bb39 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
@@ -26,6 +26,10 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
public interface ConnInstance extends Entity {
+ Realm getAdminRealm();
+
+ void setAdminRealm(Realm adminRealm);
+
void setConnectorName(String connectorName);
String getConnectorName();
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 3cf4376..b052f30 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -148,7 +148,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(
- anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+ anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT.name(), anyObject.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index 8972b8b..7d4c0c8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -18,11 +18,17 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.persistence.TypedQuery;
import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceHistoryConfDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -31,6 +37,8 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -52,10 +60,54 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance> implements Con
}
@Override
+ public ConnInstance authFind(final String key) {
+ final ConnInstance connInstance = find(key);
+ if (connInstance == null) {
+ return null;
+ }
+
+ final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_READ);
+ if (authRealms == null || authRealms.isEmpty()
+ || !IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return connInstance.getAdminRealm().getFullPath().startsWith(realm);
+ }
+ })) {
+
+ throw new DelegatedAdministrationException(
+ connInstance.getAdminRealm().getFullPath(),
+ ConnInstance.class.getSimpleName(),
+ connInstance.getKey());
+ }
+
+ return connInstance;
+ }
+
+ @Override
public List<ConnInstance> findAll() {
+ final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_LIST);
+ if (authRealms == null || authRealms.isEmpty()) {
+ return Collections.emptyList();
+ }
+
TypedQuery<ConnInstance> query = entityManager().createQuery(
"SELECT e FROM " + JPAConnInstance.class.getSimpleName() + " e", ConnInstance.class);
- return query.getResultList();
+
+ return CollectionUtils.select(query.getResultList(), new Predicate<ConnInstance>() {
+
+ @Override
+ public boolean evaluate(final ConnInstance connInstance) {
+ return IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return connInstance.getAdminRealm().getFullPath().startsWith(realm);
+ }
+ });
+ }
+ }, new ArrayList<ConnInstance>());
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index c49bd5a..8989fc5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -23,6 +23,9 @@ import java.util.List;
import java.util.Set;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -53,6 +56,8 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@@ -165,6 +170,33 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
}
@Override
+ public ExternalResource authFind(final String key) {
+ final ExternalResource resource = find(key);
+ if (resource == null) {
+ return null;
+ }
+
+ final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_READ);
+ if (authRealms == null || authRealms.isEmpty()
+ || !IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return resource.getConnector() != null
+ && resource.getConnector().getAdminRealm().getFullPath().startsWith(realm);
+ }
+ })) {
+
+ throw new DelegatedAdministrationException(
+ resource.getConnector().getAdminRealm().getFullPath(),
+ ExternalResource.class.getSimpleName(),
+ resource.getKey());
+ }
+
+ return resource;
+ }
+
+ @Override
public List<Provision> findProvisionsByAuxClass(final AnyTypeClass anyTypeClass) {
TypedQuery<Provision> query = entityManager().createQuery(
"SELECT e FROM " + JPAProvision.class.getSimpleName()
@@ -193,19 +225,12 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
@Override
public List<ExternalResource> findByPolicy(final Policy policy) {
TypedQuery<ExternalResource> query = entityManager().createQuery(
- getByPolicyQuery(policy.getClass()).append(" = :policy").toString(), ExternalResource.class);
+ getByPolicyQuery(policy.getClass()).append("=:policy").toString(), ExternalResource.class);
query.setParameter("policy", policy);
return query.getResultList();
}
@Override
- public List<ExternalResource> findWithoutPolicy(final Class<? extends Policy> policyClass) {
- TypedQuery<ExternalResource> query = entityManager().createQuery(
- getByPolicyQuery(policyClass).append(" IS NULL").toString(), ExternalResource.class);
- return query.getResultList();
- }
-
- @Override
public List<ExternalResource> findAll() {
TypedQuery<ExternalResource> query = entityManager().createQuery(
"SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
@@ -213,14 +238,6 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
}
@Override
- public List<ExternalResource> findAllByPriority() {
- TypedQuery<ExternalResource> query = entityManager().createQuery(
- "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
- ExternalResource.class);
- return query.getResultList();
- }
-
- @Override
@Transactional(rollbackFor = { Throwable.class })
public ExternalResource save(final ExternalResource resource) {
ExternalResource merged = entityManager().merge(resource);
http://git-wip-us.apache.org/repos/asf/syncope/blob/b5d6dc4a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 4c79d1b..4fb49e1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -172,7 +172,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(
- group.getRealm().getFullPath(), AnyTypeKind.GROUP, group.getKey());
+ group.getRealm().getFullPath(), AnyTypeKind.GROUP.name(), group.getKey());
}
}
[4/4] syncope git commit: [SYNCOPE-1143] Now connector instances
require an admin realm,
which is used to enforce access control on it for administrative purposes
Posted by il...@apache.org.
[SYNCOPE-1143] Now connector instances require an admin realm, which is used to enforce access control on it for administrative purposes
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/9779e13e
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/9779e13e
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/9779e13e
Branch: refs/heads/master
Commit: 9779e13e0d55efa445c6b046c51781d55d91991d
Parents: f1eaaa2
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jul 10 18:35:33 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jul 10 18:35:46 2017 +0200
----------------------------------------------------------------------
.../client/console/SyncopeConsoleSession.java | 28 ++++-----
.../client/console/panels/RealmChoicePanel.java | 11 ++--
.../client/console/topology/Topology.java | 49 +++++++++------
.../console/wizards/any/AnyWizardBuilder.java | 7 +--
.../client/console/wizards/any/Details.java | 3 +-
.../console/wizards/any/UserWizardBuilder.java | 1 -
.../resources/ConnectorDetailsPanel.java | 49 +++++++++++++++
.../resources/ConnectorDetailsPanel.html | 4 ++
.../resources/ConnectorDetailsPanel.properties | 1 +
.../ConnectorDetailsPanel_it.properties | 1 +
.../ConnectorDetailsPanel_pt_BR.properties | 1 +
.../ConnectorDetailsPanel_ru.properties | 1 +
.../syncope/common/lib/to/ConnInstanceTO.java | 10 +++
.../syncope/core/logic/AbstractAnyLogic.java | 53 ++--------------
.../syncope/core/logic/AnyObjectLogic.java | 23 +++----
.../syncope/core/logic/ConnectorLogic.java | 53 +++++++++++++++-
.../apache/syncope/core/logic/GroupLogic.java | 30 ++++-----
.../syncope/core/logic/ResourceLogic.java | 66 +++++++++++++++++---
.../apache/syncope/core/logic/UserLogic.java | 38 +++++------
.../persistence/api/dao/ConnInstanceDAO.java | 2 +
.../api/dao/ExternalResourceDAO.java | 6 +-
.../persistence/api/entity/ConnInstance.java | 4 ++
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 2 +-
.../persistence/jpa/dao/JPAConnInstanceDAO.java | 54 +++++++++++++++-
.../jpa/dao/JPAExternalResourceDAO.java | 49 ++++++++++-----
.../core/persistence/jpa/dao/JPAGroupDAO.java | 2 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 2 +-
.../persistence/jpa/entity/AbstractAny.java | 2 +-
.../persistence/jpa/entity/JPAConnInstance.java | 16 +++++
.../persistence/jpa/inner/ConnInstanceTest.java | 55 +++++++++++++---
.../persistence/jpa/inner/ResourceTest.java | 15 ++---
.../test/resources/domains/MasterContent.xml | 26 +++++++-
.../src/test/resources/domains/TwoContent.xml | 1 +
.../core/provisioning/api/utils/RealmUtils.java | 47 ++++++++++++++
.../provisioning/java/ConnectorManager.java | 1 +
.../java/data/ConnInstanceDataBinderImpl.java | 44 ++++++++-----
.../DelegatedAdministrationException.java | 2 +-
.../syncope/fit/core/ConnectorITCase.java | 54 ++++++++++++++++
.../syncope/fit/core/MigrationITCase.java | 2 +
.../apache/syncope/fit/core/ResourceITCase.java | 31 +++++++++
40 files changed, 632 insertions(+), 214 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index af8295a..ab84d10 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -19,9 +19,10 @@
package org.apache.syncope.client.console;
import java.text.DateFormat;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -29,9 +30,9 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
-import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.list.SetUniqueList;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.lang3.tuple.Pair;
@@ -217,25 +218,18 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
return selfTO;
}
- public Set<String> getAvailableRealms(final String... entitlements) {
- final Set<String> availableRealms = new HashSet<>();
- if (entitlements != null && entitlements.length > 0) {
- for (String entitlement : entitlements) {
- final Set<String> realms = auth.get(entitlement);
- if (CollectionUtils.isNotEmpty(realms)) {
- availableRealms.addAll(realms);
- }
- }
- } else {
- for (Map.Entry<String, Set<String>> entitlement : auth.entrySet()) {
- availableRealms.addAll(entitlement.getValue());
- }
+ public List<String> getAuthRealms() {
+ List<String> sortable = new ArrayList<>();
+ List<String> available = SetUniqueList.setUniqueList(sortable);
+ for (Map.Entry<String, Set<String>> entitlement : auth.entrySet()) {
+ available.addAll(entitlement.getValue());
}
- return availableRealms;
+ Collections.sort(sortable);
+ return sortable;
}
public boolean owns(final String entitlements) {
- return owns(entitlements, "/");
+ return owns(entitlements, SyncopeConstants.ROOT_REALM);
}
public boolean owns(final String entitlements, final String realm) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
index bfbb460..d569b14 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -27,12 +27,12 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.image.GlyphIconType;
import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.StringUtils;
@@ -72,7 +72,7 @@ public class RealmChoicePanel extends Panel {
private final Model<RealmTO> model;
- private final Set<String> availableRealms;
+ private final Collection<String> availableRealms;
private final Map<String, Pair<RealmTO, List<RealmTO>>> tree;
@@ -146,13 +146,13 @@ public class RealmChoicePanel extends Panel {
container.setOutputMarkupId(true);
add(container);
- availableRealms = SyncopeConsoleSession.get().getAvailableRealms();
+ availableRealms = SyncopeConsoleSession.get().getAuthRealms();
reloadRealmTree();
}
public final void reloadRealmTree() {
- final Label realmLabel = new Label("realmLabel", new Model<String>());
+ final Label realmLabel = new Label("realmLabel", new Model<>());
realmLabel.setOutputMarkupId(true);
container.addOrReplace(realmLabel);
@@ -186,7 +186,6 @@ public class RealmChoicePanel extends Panel {
@Override
public void onClick(final AjaxRequestTarget target) {
-
}
@Override
@@ -288,7 +287,7 @@ public class RealmChoicePanel extends Panel {
@Override
public boolean evaluate(final String availableRealm) {
- return "/".equals(availableRealm)
+ return SyncopeConstants.ROOT_REALM.equals(availableRealm)
|| realmTO.getKey().equals(availableRealm);
}
});
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index d2ba682..606a32d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -22,10 +22,13 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.jaxrs.client.WebClient;
@@ -39,6 +42,7 @@ import org.apache.syncope.client.console.rest.ResourceRestClient;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -92,8 +96,8 @@ public class Topology extends BasePage {
}
};
- private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel
- = new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
+ private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel =
+ new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
private static final long serialVersionUID = 5275935387613157432L;
@@ -116,8 +120,8 @@ public class Topology extends BasePage {
}
};
- private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel
- = new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
+ private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel =
+ new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
private static final long serialVersionUID = 5275935387613157433L;
@@ -177,7 +181,7 @@ public class Topology extends BasePage {
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
target.appendJavaScript("zoomIn($('#drawing')[0]);");
}
- }, ActionLink.ActionType.ZOOM_IN, StandardEntitlement.RESOURCE_LIST).disableIndicator().hideLabel();
+ }, ActionLink.ActionType.ZOOM_IN, StandardEntitlement.CONNECTOR_LIST).disableIndicator().hideLabel();
zoomActionPanel.add(new ActionLink<Serializable>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -186,7 +190,7 @@ public class Topology extends BasePage {
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
target.appendJavaScript("zoomOut($('#drawing')[0]);");
}
- }, ActionLink.ActionType.ZOOM_OUT, StandardEntitlement.RESOURCE_LIST).disableIndicator().hideLabel();
+ }, ActionLink.ActionType.ZOOM_OUT, StandardEntitlement.CONNECTOR_LIST).disableIndicator().hideLabel();
body.add(zoomActionPanel);
// -----------------------------------------
@@ -366,24 +370,31 @@ public class Topology extends BasePage {
// -----------------------------------------
// Add Resources
// -----------------------------------------
+ final Collection<String> administrableConns = new HashSet<>();
+ for (List<ConnInstanceTO> connInstances : connModel.getObject().values()) {
+ administrableConns.addAll(CollectionUtils.collect(connInstances, EntityTOUtils.keyTransformer()));
+ }
+
final List<String> connToBeProcessed = new ArrayList<>();
- for (ResourceTO resourceTO : resModel.getObject()) {
- final TopologyNode topologynode = new TopologyNode(
- resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
+ for (final ResourceTO resourceTO : resModel.getObject()) {
+ if (administrableConns.contains(resourceTO.getConnector())) {
+ final TopologyNode topologynode = new TopologyNode(
+ resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
- final Map<Serializable, TopologyNode> remoteConnections;
+ final Map<Serializable, TopologyNode> remoteConnections;
- if (connections.containsKey(resourceTO.getConnector())) {
- remoteConnections = connections.get(resourceTO.getConnector());
- } else {
- remoteConnections = new HashMap<>();
- connections.put(resourceTO.getConnector(), remoteConnections);
- }
+ if (connections.containsKey(resourceTO.getConnector())) {
+ remoteConnections = connections.get(resourceTO.getConnector());
+ } else {
+ remoteConnections = new HashMap<>();
+ connections.put(resourceTO.getConnector(), remoteConnections);
+ }
- remoteConnections.put(topologynode.getKey(), topologynode);
+ remoteConnections.put(topologynode.getKey(), topologynode);
- if (!connToBeProcessed.contains(resourceTO.getConnector())) {
- connToBeProcessed.add(resourceTO.getConnector());
+ if (!connToBeProcessed.contains(resourceTO.getConnector())) {
+ connToBeProcessed.add(resourceTO.getConnector());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 9b3bce6..37377ef 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -152,15 +152,14 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde
}
protected Details<A> addOptionalDetailsPanel(final AnyWrapper<A> modelObject) {
-
- if (modelObject.getInnerObject().getKey() != null) {
+ if (modelObject.getInnerObject().getKey() == null) {
+ return null;
+ } else {
return new Details<>(
modelObject,
mode == AjaxWizard.Mode.TEMPLATE,
true,
pageRef);
- } else {
- return null;
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
index e5a92d2..a7dd79a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
@@ -73,8 +73,7 @@ public class Details<T extends AnyTO> extends WizardStep {
"destinationRealm", "destinationRealm", new PropertyModel<String>(inner, "realm"), false);
((AjaxDropDownChoicePanel<String>) realm).setChoices(CollectionUtils.collect(
- realms,
- new Transformer<RealmTO, String>() {
+ realms, new Transformer<RealmTO, String>() {
@Override
public String transform(final RealmTO input) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index f56e24d..6cf6023 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -104,7 +104,6 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
@Override
protected Details<UserTO> addOptionalDetailsPanel(final AnyWrapper<UserTO> modelObject) {
-
return new UserDetails(
UserWrapper.class.cast(modelObject),
mode == AjaxWizard.Mode.TEMPLATE,
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
index 89c692f..43d4d85 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
@@ -19,12 +19,16 @@
package org.apache.syncope.client.console.wizards.resources;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.RealmRestClient;
import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
@@ -32,19 +36,64 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPa
import org.apache.syncope.common.lib.to.ConnBundleTO;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
public class ConnectorDetailsPanel extends WizardStep {
private static final long serialVersionUID = -2435937897614232137L;
+ private final LoadableDetachableModel<List<String>> realms;
+
public ConnectorDetailsPanel(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
super();
setOutputMarkupId(true);
+ final List<String> authRealms = SyncopeConsoleSession.get().getAuthRealms();
+ realms = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ List<RealmTO> allRealms = new RealmRestClient().list();
+ CollectionUtils.filter(allRealms, new Predicate<RealmTO>() {
+
+ @Override
+ public boolean evaluate(final RealmTO realm) {
+ return IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String fullpath) {
+ return realm.getFullPath().startsWith(fullpath);
+ }
+ });
+ }
+ });
+
+ List<String> result = CollectionUtils.collect(allRealms, new Transformer<RealmTO, String>() {
+
+ @Override
+ public String transform(final RealmTO realm) {
+ return realm.getFullPath();
+ }
+ }, new ArrayList<String>());
+ Collections.sort(result);
+ return result;
+ }
+ };
+
+ AjaxDropDownChoicePanel<String> realm = new AjaxDropDownChoicePanel<>(
+ "adminRealm", "adminRealm", new PropertyModel<String>(connInstanceTO, "adminRealm"), false);
+ realm.setChoices(realms);
+ realm.setOutputMarkupId(true);
+ realm.addRequiredLabel();
+ add(realm);
+
AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
"displayName", "displayName", new PropertyModel<String>(connInstanceTO, "displayName"), false);
displayName.setOutputMarkupId(true);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
index 87fc624..01ac512 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
@@ -23,6 +23,10 @@ under the License.
<body>
<wicket:panel>
<div class="form-group">
+ <span wicket:id="adminRealm">[adminRealm]</span>
+ </div>
+
+ <div class="form-group">
<span wicket:id="displayName">[displayName]</span>
</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
index 6c11adc..23711a9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
@@ -24,3 +24,4 @@ poolMinIdle=Min idle objects
poolMaxIdle=Max idle objects
poolMaxWait=Max waiting time (msec)
poolMinEvictableIdleTime=Min eviction time (msec)
+adminRealm=Administration Realm
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
index ed69987..0fd9aa7 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
@@ -24,3 +24,4 @@ poolMinIdle=Max oggetti attivi
poolMaxIdle=Max oggetti inattivi
poolMaxWait=Tempo max attesa
poolMinEvictableIdleTime=Tempo min espulsione
+adminRealm=Realm di amministrazione
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
index a2915b1..db06733 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
@@ -24,3 +24,4 @@ poolMinIdle=Min idle objects
poolMaxIdle=Max idle objects
poolMaxWait=Max waiting time (msec)
poolMinEvictableIdleTime=Min eviction time (msec)
+adminRealm=Administration Realm
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
index 0194990..c5d4b3f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
@@ -25,3 +25,4 @@ poolMinIdle=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0431\u044a\u0435\
poolMaxIdle=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438
poolMaxWait=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f (\u043c\u0441)
poolMinEvictableIdleTime=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f (\u043c\u0441)
+adminRealm=Administration Realm
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
index d7c8be7..9440972 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
@@ -42,6 +42,8 @@ public class ConnInstanceTO extends AbstractBaseBean implements EntityTO {
private String key;
+ private String adminRealm;
+
private String location;
private String connectorName;
@@ -71,6 +73,14 @@ public class ConnInstanceTO extends AbstractBaseBean implements EntityTO {
this.key = key;
}
+ public String getAdminRealm() {
+ return adminRealm;
+ }
+
+ public void setAdminRealm(final String adminRealm) {
+ this.adminRealm = adminRealm;
+ }
+
public String getLocation() {
return location;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 7c96979..bf83632 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -19,7 +19,6 @@
package org.apache.syncope.core.logic;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -40,7 +39,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.spring.ApplicationContextProvider;
@@ -53,6 +51,7 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.LogicActions;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -230,50 +229,6 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
return result;
}
- private static class StartsWithPredicate implements Predicate<String> {
-
- private final Collection<String> targets;
-
- StartsWithPredicate(final Collection<String> targets) {
- this.targets = targets;
- }
-
- @Override
- public boolean evaluate(final String realm) {
- return IterableUtils.matchesAny(targets, new Predicate<String>() {
-
- @Override
- public boolean evaluate(final String target) {
- return realm.startsWith(target);
- }
- });
- }
-
- }
-
- protected static class DynRealmsPredicate implements Predicate<String> {
-
- @Override
- public boolean evaluate(final String realm) {
- return !realm.startsWith("/");
- }
- }
-
- protected Set<String> getEffectiveRealms(final Set<String> allowedRealms, final String requestedRealm) {
- Set<String> allowed = RealmUtils.normalize(allowedRealms);
- Set<String> requested = new HashSet<>();
- requested.add(requestedRealm);
-
- Set<String> effective = new HashSet<>();
- CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
- CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
-
- // includes dynamic realms
- CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
-
- return effective;
- }
-
protected boolean securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
@@ -293,15 +248,15 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
if (!authorized) {
throw new DelegatedAdministrationException(
realm,
- this instanceof UserLogic
+ (this instanceof UserLogic
? AnyTypeKind.USER
: this instanceof GroupLogic
? AnyTypeKind.GROUP
- : AnyTypeKind.ANY_OBJECT,
+ : AnyTypeKind.ANY_OBJECT).name(),
key);
}
- return IterableUtils.matchesAny(effectiveRealms, new DynRealmsPredicate());
+ return IterableUtils.matchesAny(effectiveRealms, new RealmUtils.DynRealmsPredicate());
}
public abstract Date findLastChange(String key);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 8805221..49d18db 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -109,7 +110,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
throw new UnsupportedOperationException("Need to specify " + AnyType.class.getSimpleName());
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.SEARCH.getFor(searchCond.hasAnyTypeCond())),
realm);
@@ -125,7 +126,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
throw new UnsupportedOperationException("Need to specify " + AnyType.class.getSimpleName());
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.SEARCH.getFor(searchCond.hasAnyTypeCond())),
realm);
@@ -152,7 +153,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
throw SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.CREATE.getFor(before.getLeft().getType())),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -174,7 +175,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
? before.getLeft().getRealm().getValue()
: anyObjectTO.getRealm();
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
realm);
boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
@@ -194,7 +195,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
AnyObjectTO anyObject = binder.getAnyObjectTO(key);
Pair<AnyObjectTO, List<LogicActions>> before = beforeDelete(anyObject);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.DELETE.getFor(before.getLeft().getType())),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -211,7 +212,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
public AnyObjectTO unlink(final String key, final Collection<String> resources) {
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -233,7 +234,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
public AnyObjectTO link(final String key, final Collection<String> resources) {
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -257,7 +258,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -285,7 +286,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -309,7 +310,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -332,7 +333,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
// security checks
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
anyObjectTO.getRealm());
securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index e84dfe5..6532936 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -26,6 +26,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.PredicateUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.ArrayUtils;
@@ -44,6 +46,9 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
import org.apache.syncope.core.provisioning.api.ConnectorFactory;
import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.common.l10n.CurrentLocale;
import org.identityconnectors.framework.api.ConfigurationProperties;
import org.identityconnectors.framework.api.ConnectorInfo;
@@ -75,23 +80,61 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
@Autowired
private ConnectorFactory connFactory;
+ protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+ boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String ownedRealm) {
+ return realm.startsWith(ownedRealm);
+ }
+ });
+ if (!authorized) {
+ throw new DelegatedAdministrationException(realm, ConnInstance.class.getSimpleName(), key);
+ }
+ }
+
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_CREATE + "')")
public ConnInstanceTO create(final ConnInstanceTO connInstanceTO) {
+ if (connInstanceTO.getAdminRealm() == null) {
+ throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ }
+
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_CREATE),
+ connInstanceTO.getAdminRealm());
+ securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), null);
+
return binder.getConnInstanceTO(connInstanceDAO.save(binder.getConnInstance(connInstanceTO)));
}
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_UPDATE + "')")
public ConnInstanceTO update(final ConnInstanceTO connInstanceTO) {
+ if (connInstanceTO.getAdminRealm() == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
+ sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+ throw sce;
+ }
+
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_UPDATE),
+ connInstanceTO.getAdminRealm());
+ securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), connInstanceTO.getKey());
+
return binder.getConnInstanceTO(binder.update(connInstanceTO));
}
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_DELETE + "')")
public ConnInstanceTO delete(final String key) {
- ConnInstance connInstance = connInstanceDAO.find(key);
+ ConnInstance connInstance = connInstanceDAO.authFind(key);
if (connInstance == null) {
throw new NotFoundException("Connector '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_DELETE),
+ connInstance.getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, connInstance.getAdminRealm().getFullPath(), connInstance.getKey());
+
if (!connInstance.getResources().isEmpty()) {
SyncopeClientException associatedResources = SyncopeClientException.build(
ClientExceptionType.AssociatedResources);
@@ -136,7 +179,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
public ConnInstanceTO read(final String key, final String lang) {
CurrentLocale.set(StringUtils.isBlank(lang) ? Locale.ENGLISH : new Locale(lang));
- ConnInstance connInstance = connInstanceDAO.find(key);
+ ConnInstance connInstance = connInstanceDAO.authFind(key);
if (connInstance == null) {
throw new NotFoundException("Connector '" + key + "'");
}
@@ -183,7 +226,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
public List<ConnIdObjectClassTO> buildObjectClassInfo(
final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
- ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+ ConnInstance connInstance = connInstanceDAO.authFind(connInstanceTO.getKey());
if (connInstance == null) {
throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
}
@@ -214,6 +257,10 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_READ + "')")
@Transactional(readOnly = true)
public void check(final ConnInstanceTO connInstanceTO) {
+ if (connInstanceTO.getAdminRealm() == null) {
+ throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ }
+
connFactory.createConnector(binder.getConnInstance(connInstanceTO)).test();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index ca3e080..7e9b88b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -122,10 +122,10 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
authorized = !CollectionUtils.intersection(groupDAO.findDynRealms(key), effectiveRealms).isEmpty();
}
if (!authorized) {
- throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP, key);
+ throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP.name(), key);
}
- return IterableUtils.matchesAny(effectiveRealms, new AbstractAnyLogic.DynRealmsPredicate());
+ return IterableUtils.matchesAny(effectiveRealms, new RealmUtils.DynRealmsPredicate());
}
@Transactional(readOnly = true)
@@ -177,7 +177,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
@Transactional(readOnly = true)
@Override
public int count(final String realm) {
- return groupDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm));
+ return groupDAO.count(RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm));
}
@PreAuthorize("isAuthenticated()")
@@ -188,7 +188,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
final String realm, final boolean details) {
return CollectionUtils.collect(groupDAO.findAll(
- getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+ RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
page, size, orderBy),
new Transformer<Group, GroupTO>() {
@@ -205,7 +205,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
@Override
public int searchCount(final SearchCond searchCondition, final String realm) {
return searchDAO.count(
- getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+ RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
searchCondition, AnyTypeKind.GROUP);
}
@@ -216,7 +216,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
final List<OrderByClause> orderBy, final String realm, final boolean details) {
List<Group> matchingGroups = searchDAO.search(
- getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+ RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
searchCondition, page, size, orderBy, AnyTypeKind.GROUP);
return CollectionUtils.collect(matchingGroups, new Transformer<Group, GroupTO>() {
@@ -237,7 +237,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
}
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_CREATE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -259,7 +259,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
? before.getLeft().getRealm().getValue()
: groupTO.getRealm();
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
realm);
boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
@@ -280,7 +280,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
GroupTO group = binder.getGroupTO(key);
Pair<GroupTO, List<LogicActions>> before = beforeDelete(group);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_DELETE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -312,7 +312,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
public GroupTO unlink(final String key, final Collection<String> resources) {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -335,7 +335,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
public GroupTO link(final String key, final Collection<String> resources) {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -360,7 +360,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -389,7 +389,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -414,7 +414,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -438,7 +438,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
// security checks
GroupTO group = binder.getGroupTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
group.getRealm());
securityChecks(effectiveRealms, group.getRealm(), group.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 5269c1e..1cde745 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -25,7 +25,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -62,7 +64,10 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -113,6 +118,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@Autowired
private ConnectorFactory connFactory;
+ protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+ boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String ownedRealm) {
+ return realm.startsWith(ownedRealm);
+ }
+ });
+ if (!authorized) {
+ throw new DelegatedAdministrationException(realm, ExternalResource.class.getSimpleName(), key);
+ }
+ }
+
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_CREATE + "')")
public ResourceTO create(final ResourceTO resourceTO) {
if (StringUtils.isBlank(resourceTO.getKey())) {
@@ -121,7 +139,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
throw sce;
}
- if (resourceDAO.find(resourceTO.getKey()) != null) {
+ ConnInstance connInstance = connInstanceDAO.authFind(resourceTO.getConnector());
+ if (connInstance == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidExternalResource);
+ sce.getElements().add("Connector " + resourceTO.getConnector());
+ throw sce;
+ }
+
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_CREATE),
+ connInstance.getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, connInstance.getAdminRealm().getFullPath(), null);
+
+ if (resourceDAO.authFind(resourceTO.getKey()) != null) {
throw new DuplicateException(resourceTO.getKey());
}
@@ -130,17 +160,22 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
public ResourceTO update(final ResourceTO resourceTO) {
- ExternalResource resource = resourceDAO.find(resourceTO.getKey());
+ ExternalResource resource = resourceDAO.authFind(resourceTO.getKey());
if (resource == null) {
throw new NotFoundException("Resource '" + resourceTO.getKey() + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
return binder.getResourceTO(resourceDAO.save(binder.update(resource, resourceTO)));
}
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
public void setLatestSyncToken(final String key, final String anyTypeKey) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
@@ -153,6 +188,11 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
Connector connector;
try {
connector = connFactory.getConnector(resource);
@@ -168,7 +208,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
public void removeSyncToken(final String key, final String anyTypeKey) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
@@ -181,17 +221,27 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
provision.setSyncToken(null);
resourceDAO.save(resource);
}
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_DELETE + "')")
public ResourceTO delete(final String key) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
+ Set<String> effectiveRealms = RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_DELETE),
+ resource.getConnector().getAdminRealm().getFullPath());
+ securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
ResourceTO resourceToDelete = binder.getResourceTO(resource);
resourceDAO.delete(key);
@@ -202,7 +252,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_READ + "')")
@Transactional(readOnly = true)
public ResourceTO read(final String key) {
- ExternalResource resource = resourceDAO.find(key);
+ ExternalResource resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
@@ -225,7 +275,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
private Triple<ExternalResource, AnyType, Provision> connObjectInit(
final String resourceKey, final String anyTypeKey) {
- ExternalResource resource = resourceDAO.find(resourceKey);
+ ExternalResource resource = resourceDAO.authFind(resourceKey);
if (resource == null) {
throw new NotFoundException("Resource '" + resourceKey + "'");
}
@@ -305,7 +355,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
ObjectClass objectClass;
OperationOptions options;
if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
- resource = resourceDAO.find(key);
+ resource = resourceDAO.authFind(key);
if (resource == null) {
throw new NotFoundException("Resource '" + key + "'");
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 54a43f3..ee68a4e 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -55,6 +55,7 @@ import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -95,8 +96,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
@Transactional(readOnly = true)
@Override
public int count(final String realm) {
- return userDAO.count(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm));
+ return userDAO.count(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm));
}
@PreAuthorize("hasRole('" + StandardEntitlement.USER_SEARCH + "')")
@@ -106,9 +107,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
final int page, final int size, final List<OrderByClause> orderBy,
final String realm, final boolean details) {
- return CollectionUtils.collect(userDAO.findAll(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
- page, size, orderBy),
+ return CollectionUtils.collect(userDAO.findAll(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm), page, size, orderBy),
new Transformer<User, UserTO>() {
@Transactional(readOnly = true)
@@ -138,8 +138,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
@Transactional(readOnly = true)
@Override
public int searchCount(final SearchCond searchCondition, final String realm) {
- return searchDAO.count(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
+ return searchDAO.count(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
searchCondition, AnyTypeKind.USER);
}
@@ -149,8 +149,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public List<UserTO> search(final SearchCond searchCondition, final int page, final int size,
final List<OrderByClause> orderBy, final String realm, final boolean details) {
- List<User> matchingUsers = searchDAO.search(
- getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
+ List<User> matchingUsers = searchDAO.search(RealmUtils.getEffective(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
searchCondition, page, size, orderBy, AnyTypeKind.USER);
return CollectionUtils.collect(matchingUsers, new Transformer<User, UserTO>() {
@@ -195,7 +195,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
}
if (!self) {
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_CREATE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -233,7 +233,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
&& before.getLeft().getRealm() != null
&& StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
before.getLeft().getRealm().getValue());
authDynRealms =
@@ -278,7 +278,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public ProvisioningResult<UserTO> status(final StatusPatch statusPatch, final boolean nullPriorityAsync) {
// security checks
UserTO toUpdate = binder.getUserTO(statusPatch.getKey());
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
toUpdate.getRealm());
securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
@@ -354,7 +354,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
Pair<UserTO, List<LogicActions>> before = beforeDelete(userTO);
if (!self) {
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_DELETE),
before.getLeft().getRealm());
securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -391,7 +391,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public UserTO unlink(final String key, final Collection<String> resources) {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -414,7 +414,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
public UserTO link(final String key, final Collection<String> resources) {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -439,7 +439,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -468,7 +468,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -498,7 +498,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -522,7 +522,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
// security checks
UserTO user = binder.getUserTO(key);
- Set<String> effectiveRealms = getEffectiveRealms(
+ Set<String> effectiveRealms = RealmUtils.getEffective(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
user.getRealm());
securityChecks(effectiveRealms, user.getRealm(), user.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
index a7ba370..bb27896 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
@@ -25,6 +25,8 @@ public interface ConnInstanceDAO extends DAO<ConnInstance> {
ConnInstance find(String key);
+ ConnInstance authFind(String key);
+
List<ConnInstance> findAll();
ConnInstance save(ConnInstance connector);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
index 6afa771..b48fd79 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
@@ -30,16 +30,14 @@ public interface ExternalResourceDAO extends DAO<ExternalResource> {
ExternalResource find(String key);
+ ExternalResource authFind(String key);
+
List<Provision> findProvisionsByAuxClass(AnyTypeClass anyTypeClass);
List<ExternalResource> findByPolicy(Policy policy);
- List<ExternalResource> findWithoutPolicy(Class<? extends Policy> policyClass);
-
List<ExternalResource> findAll();
- List<ExternalResource> findAllByPriority();
-
ExternalResource save(ExternalResource resource);
void deleteMapping(String schemaName);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
index 90650a2..908bb39 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
@@ -26,6 +26,10 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
public interface ConnInstance extends Entity {
+ Realm getAdminRealm();
+
+ void setAdminRealm(Realm adminRealm);
+
void setConnectorName(String connectorName);
String getConnectorName();
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 3cf4376..b052f30 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -148,7 +148,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(
- anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+ anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT.name(), anyObject.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index 8972b8b..7d4c0c8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -18,11 +18,17 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.persistence.TypedQuery;
import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceHistoryConfDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -31,6 +37,8 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -52,10 +60,54 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance> implements Con
}
@Override
+ public ConnInstance authFind(final String key) {
+ final ConnInstance connInstance = find(key);
+ if (connInstance == null) {
+ return null;
+ }
+
+ final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_READ);
+ if (authRealms == null || authRealms.isEmpty()
+ || !IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return connInstance.getAdminRealm().getFullPath().startsWith(realm);
+ }
+ })) {
+
+ throw new DelegatedAdministrationException(
+ connInstance.getAdminRealm().getFullPath(),
+ ConnInstance.class.getSimpleName(),
+ connInstance.getKey());
+ }
+
+ return connInstance;
+ }
+
+ @Override
public List<ConnInstance> findAll() {
+ final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_LIST);
+ if (authRealms == null || authRealms.isEmpty()) {
+ return Collections.emptyList();
+ }
+
TypedQuery<ConnInstance> query = entityManager().createQuery(
"SELECT e FROM " + JPAConnInstance.class.getSimpleName() + " e", ConnInstance.class);
- return query.getResultList();
+
+ return CollectionUtils.select(query.getResultList(), new Predicate<ConnInstance>() {
+
+ @Override
+ public boolean evaluate(final ConnInstance connInstance) {
+ return IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return connInstance.getAdminRealm().getFullPath().startsWith(realm);
+ }
+ });
+ }
+ }, new ArrayList<ConnInstance>());
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index c49bd5a..8989fc5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -23,6 +23,9 @@ import java.util.List;
import java.util.Set;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -53,6 +56,8 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@@ -165,6 +170,33 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
}
@Override
+ public ExternalResource authFind(final String key) {
+ final ExternalResource resource = find(key);
+ if (resource == null) {
+ return null;
+ }
+
+ final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_READ);
+ if (authRealms == null || authRealms.isEmpty()
+ || !IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return resource.getConnector() != null
+ && resource.getConnector().getAdminRealm().getFullPath().startsWith(realm);
+ }
+ })) {
+
+ throw new DelegatedAdministrationException(
+ resource.getConnector().getAdminRealm().getFullPath(),
+ ExternalResource.class.getSimpleName(),
+ resource.getKey());
+ }
+
+ return resource;
+ }
+
+ @Override
public List<Provision> findProvisionsByAuxClass(final AnyTypeClass anyTypeClass) {
TypedQuery<Provision> query = entityManager().createQuery(
"SELECT e FROM " + JPAProvision.class.getSimpleName()
@@ -193,19 +225,12 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
@Override
public List<ExternalResource> findByPolicy(final Policy policy) {
TypedQuery<ExternalResource> query = entityManager().createQuery(
- getByPolicyQuery(policy.getClass()).append(" = :policy").toString(), ExternalResource.class);
+ getByPolicyQuery(policy.getClass()).append("=:policy").toString(), ExternalResource.class);
query.setParameter("policy", policy);
return query.getResultList();
}
@Override
- public List<ExternalResource> findWithoutPolicy(final Class<? extends Policy> policyClass) {
- TypedQuery<ExternalResource> query = entityManager().createQuery(
- getByPolicyQuery(policyClass).append(" IS NULL").toString(), ExternalResource.class);
- return query.getResultList();
- }
-
- @Override
public List<ExternalResource> findAll() {
TypedQuery<ExternalResource> query = entityManager().createQuery(
"SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
@@ -213,14 +238,6 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
}
@Override
- public List<ExternalResource> findAllByPriority() {
- TypedQuery<ExternalResource> query = entityManager().createQuery(
- "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
- ExternalResource.class);
- return query.getResultList();
- }
-
- @Override
@Transactional(rollbackFor = { Throwable.class })
public ExternalResource save(final ExternalResource resource) {
ExternalResource merged = entityManager().merge(resource);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 4c79d1b..4fb49e1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -172,7 +172,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(
- group.getRealm().getFullPath(), AnyTypeKind.GROUP, group.getKey());
+ group.getRealm().getFullPath(), AnyTypeKind.GROUP.name(), group.getKey());
}
}