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/06/09 09:42:44 UTC
[1/2] syncope git commit: [SYNCOPE-1067] Check that any USER / GROUP
/ ANYOBJECT UPDATE under DynRealm authorization cannot alter the set of
DynRealms
Repository: syncope
Updated Branches:
refs/heads/2_0_X d6d52e1ac -> 1ad305580
refs/heads/master 8683655c6 -> f74ce5dee
[SYNCOPE-1067] Check that any USER / GROUP / ANYOBJECT UPDATE under DynRealm authorization cannot alter the set of DynRealms
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/1ad30558
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/1ad30558
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/1ad30558
Branch: refs/heads/2_0_X
Commit: 1ad3055802d6195dbaaeee186e512d38defdcaad
Parents: d6d52e1
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jun 9 11:42:25 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jun 9 11:42:25 2017 +0200
----------------------------------------------------------------------
.../syncope/core/logic/AbstractAnyLogic.java | 70 +++++++++--
.../syncope/core/logic/AnyObjectLogic.java | 15 ++-
.../apache/syncope/core/logic/GroupLogic.java | 42 ++++---
.../apache/syncope/core/logic/UserLogic.java | 24 +++-
.../api/search/SearchCondConverterTest.java | 126 +++++++++----------
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 3 +-
.../core/persistence/jpa/dao/JPAGroupDAO.java | 3 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 3 +-
.../rest/cxf/RestServiceExceptionMapper.java | 4 +-
.../DelegatedAdministrationException.java | 8 +-
.../apache/syncope/fit/core/DynRealmITCase.java | 13 ++
11 files changed, 207 insertions(+), 104 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 066b3d2..7c96979 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
@@ -167,7 +167,7 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
return ImmutablePair.of(any, actions);
}
- protected ProvisioningResult<TO> after(
+ protected ProvisioningResult<TO> afterCreate(
final TO input, final List<PropagationStatus> statuses, final List<LogicActions> actions) {
TO any = input;
@@ -183,6 +183,53 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
return result;
}
+ protected ProvisioningResult<TO> afterUpdate(
+ final TO input,
+ final List<PropagationStatus> statuses,
+ final List<LogicActions> actions,
+ final boolean authDynRealms,
+ final Set<String> dynRealmsBefore) {
+
+ Set<String> dynRealmsAfter = new HashSet<>(input.getDynRealms());
+ if (authDynRealms && !dynRealmsBefore.equals(dynRealmsAfter)) {
+ throw new DelegatedAdministrationException(
+ this instanceof UserLogic
+ ? AnyTypeKind.USER
+ : this instanceof GroupLogic
+ ? AnyTypeKind.GROUP
+ : AnyTypeKind.ANY_OBJECT,
+ input.getKey());
+ }
+
+ TO any = input;
+
+ for (LogicActions action : actions) {
+ any = action.afterUpdate(any);
+ }
+
+ ProvisioningResult<TO> result = new ProvisioningResult<>();
+ result.setEntity(any);
+ result.getPropagationStatuses().addAll(statuses);
+
+ return result;
+ }
+
+ protected ProvisioningResult<TO> afterDelete(
+ final TO input, final List<PropagationStatus> statuses, final List<LogicActions> actions) {
+
+ TO any = input;
+
+ for (LogicActions action : actions) {
+ any = action.afterDelete(any);
+ }
+
+ ProvisioningResult<TO> result = new ProvisioningResult<>();
+ result.setEntity(any);
+ result.getPropagationStatuses().addAll(statuses);
+
+ return result;
+ }
+
private static class StartsWithPredicate implements Predicate<String> {
private final Collection<String> targets;
@@ -204,6 +251,14 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
}
+ 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<>();
@@ -214,18 +269,12 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
// includes dynamic realms
- CollectionUtils.select(allowedRealms, new Predicate<String>() {
-
- @Override
- public boolean evaluate(final String realm) {
- return !realm.startsWith("/");
- }
- }, effective);
+ CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
return effective;
}
- protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+ protected boolean securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
@Override
@@ -243,6 +292,7 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
}
if (!authorized) {
throw new DelegatedAdministrationException(
+ realm,
this instanceof UserLogic
? AnyTypeKind.USER
: this instanceof GroupLogic
@@ -250,6 +300,8 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
: AnyTypeKind.ANY_OBJECT,
key);
}
+
+ return IterableUtils.matchesAny(effectiveRealms, new DynRealmsPredicate());
}
public abstract Date findLastChange(String key);
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 c585dd0..8805221 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
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
@@ -158,7 +159,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
Pair<String, List<PropagationStatus>> created = provisioningManager.create(before.getLeft(), nullPriorityAsync);
- return after(binder.getAnyObjectTO(created.getKey()), created.getRight(), before.getRight());
+ return afterCreate(binder.getAnyObjectTO(created.getKey()), created.getRight(), before.getRight());
}
@Override
@@ -166,6 +167,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
final AnyObjectPatch anyObjectPatch, final boolean nullPriorityAsync) {
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(anyObjectPatch.getKey());
+ Set<String> dynRealmsBefore = new HashSet<>(anyObjectTO.getDynRealms());
Pair<AnyObjectPatch, List<LogicActions>> before = beforeUpdate(anyObjectPatch, anyObjectTO.getRealm());
String realm =
@@ -175,11 +177,16 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
Set<String> effectiveRealms = getEffectiveRealms(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
realm);
- securityChecks(effectiveRealms, realm, before.getLeft().getKey());
+ boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
Pair<String, List<PropagationStatus>> updated = provisioningManager.update(anyObjectPatch, nullPriorityAsync);
- return after(binder.getAnyObjectTO(updated.getKey()), updated.getRight(), before.getRight());
+ return afterUpdate(
+ binder.getAnyObjectTO(updated.getKey()),
+ updated.getRight(),
+ before.getRight(),
+ authDynRealms,
+ dynRealmsBefore);
}
@Override
@@ -197,7 +204,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
AnyObjectTO anyObjectTO = new AnyObjectTO();
anyObjectTO.setKey(before.getLeft().getKey());
- return after(anyObjectTO, statuses, before.getRight());
+ return afterDelete(anyObjectTO, statuses, before.getRight());
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 1ddc108..ca3e080 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
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -109,17 +110,22 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
protected EntityFactory entityFactory;
@Override
- protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
- if (!IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+ protected boolean 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) || ownedRealm.equals(RealmUtils.getGroupOwnerRealm(realm, key));
}
- })) {
-
- throw new DelegatedAdministrationException(AnyTypeKind.GROUP, key);
+ });
+ if (!authorized) {
+ authorized = !CollectionUtils.intersection(groupDAO.findDynRealms(key), effectiveRealms).isEmpty();
+ }
+ if (!authorized) {
+ throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP, key);
}
+
+ return IterableUtils.matchesAny(effectiveRealms, new AbstractAnyLogic.DynRealmsPredicate());
}
@Transactional(readOnly = true)
@@ -239,25 +245,33 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
Pair<String, List<PropagationStatus>> created =
provisioningManager.create(before.getLeft(), nullPriorityAsync);
- return after(binder.getGroupTO(created.getKey()), created.getRight(), before.getRight());
+ return afterCreate(binder.getGroupTO(created.getKey()), created.getRight(), before.getRight());
}
@PreAuthorize("hasRole('" + StandardEntitlement.GROUP_UPDATE + "')")
@Override
public ProvisioningResult<GroupTO> update(final GroupPatch groupPatch, final boolean nullPriorityAsync) {
GroupTO groupTO = binder.getGroupTO(groupPatch.getKey());
+ Set<String> dynRealmsBefore = new HashSet<>(groupTO.getDynRealms());
Pair<GroupPatch, List<LogicActions>> before = beforeUpdate(groupPatch, groupTO.getRealm());
- if (before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
- Set<String> effectiveRealms = getEffectiveRealms(
- AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
- before.getLeft().getRealm().getValue());
- securityChecks(effectiveRealms, before.getLeft().getRealm().getValue(), before.getLeft().getKey());
- }
+ String realm =
+ before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
+ ? before.getLeft().getRealm().getValue()
+ : groupTO.getRealm();
+ Set<String> effectiveRealms = getEffectiveRealms(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
+ realm);
+ boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
Pair<String, List<PropagationStatus>> updated = provisioningManager.update(groupPatch, nullPriorityAsync);
- return after(binder.getGroupTO(updated.getKey()), updated.getRight(), before.getRight());
+ return afterUpdate(
+ binder.getGroupTO(updated.getKey()),
+ updated.getRight(),
+ before.getRight(),
+ authDynRealms,
+ dynRealmsBefore);
}
@PreAuthorize("hasRole('" + StandardEntitlement.GROUP_DELETE + "')")
@@ -290,7 +304,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
GroupTO groupTO = new GroupTO();
groupTO.setKey(before.getLeft().getKey());
- return after(groupTO, statuses, before.getRight());
+ return afterDelete(groupTO, statuses, before.getRight());
}
@PreAuthorize("hasRole('" + StandardEntitlement.GROUP_UPDATE + "')")
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 02d88cb..54a43f3 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
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
@@ -203,7 +204,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
Pair<String, List<PropagationStatus>> created =
provisioningManager.create(before.getLeft(), storePassword, nullPriorityAsync);
- return after(binder.returnUserTO(binder.getUserTO(created.getKey())), created.getRight(), before.getRight());
+ return afterCreate(
+ binder.returnUserTO(binder.getUserTO(created.getKey())), created.getRight(), before.getRight());
}
@PreAuthorize("isAuthenticated() and not(hasRole('" + StandardEntitlement.ANONYMOUS + "'))")
@@ -223,8 +225,10 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
final UserPatch userPatch, final boolean self, final boolean nullPriorityAsync) {
UserTO userTO = binder.getUserTO(userPatch.getKey());
+ Set<String> dynRealmsBefore = new HashSet<>(userTO.getDynRealms());
Pair<UserPatch, List<LogicActions>> before = beforeUpdate(userPatch, userTO.getRealm());
+ boolean authDynRealms = false;
if (!self
&& before.getLeft().getRealm() != null
&& StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
@@ -232,12 +236,18 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
Set<String> effectiveRealms = getEffectiveRealms(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
before.getLeft().getRealm().getValue());
- securityChecks(effectiveRealms, before.getLeft().getRealm().getValue(), before.getLeft().getKey());
+ authDynRealms =
+ securityChecks(effectiveRealms, before.getLeft().getRealm().getValue(), before.getLeft().getKey());
}
Pair<String, List<PropagationStatus>> updated = provisioningManager.update(before.getLeft(), nullPriorityAsync);
- return after(binder.returnUserTO(binder.getUserTO(updated.getKey())), updated.getRight(), before.getRight());
+ return afterUpdate(
+ binder.returnUserTO(binder.getUserTO(updated.getKey())),
+ updated.getRight(),
+ before.getRight(),
+ authDynRealms,
+ dynRealmsBefore);
}
protected Pair<String, List<PropagationStatus>> setStatusOnWfAdapter(
@@ -278,10 +288,12 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
statusPatch.setKey(toUpdate.getKey());
Pair<String, List<PropagationStatus>> updated = setStatusOnWfAdapter(statusPatch, nullPriorityAsync);
- return after(
+ return afterUpdate(
binder.returnUserTO(binder.getUserTO(updated.getKey())),
updated.getRight(),
- Collections.<LogicActions>emptyList());
+ Collections.<LogicActions>emptyList(),
+ false,
+ Collections.<String>emptySet());
}
@PreAuthorize("hasRole('" + StandardEntitlement.MUST_CHANGE_PASSWORD + "')")
@@ -371,7 +383,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
deletedTO = binder.getUserTO(before.getLeft().getKey());
}
- return after(binder.returnUserTO(deletedTO), statuses, before.getRight());
+ return afterDelete(binder.returnUserTO(deletedTO), statuses, before.getRight());
}
@PreAuthorize("hasRole('" + StandardEntitlement.USER_UPDATE + "')")
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
index 08b2f12..01fb922 100644
--- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
@@ -43,231 +43,227 @@ public class SearchCondConverterTest {
@Test
public void eq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
- assertEquals("username==rossini", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
+ assertEquals("username==rossini", fiql);
AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
attrCond.setSchema("username");
attrCond.setExpression("rossini");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void ieq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("username").equalToIgnoreCase("rossini").query();
- assertEquals("username=~rossini", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalToIgnoreCase("rossini").query();
+ assertEquals("username=~rossini", fiql);
AnyCond attrCond = new AnyCond(AttributeCond.Type.IEQ);
attrCond.setSchema("username");
attrCond.setExpression("rossini");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void nieq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("username").notEqualTolIgnoreCase("rossini").query();
- assertEquals("username!~rossini", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("rossini").query();
+ assertEquals("username!~rossini", fiql);
AnyCond attrCond = new AnyCond(AttributeCond.Type.IEQ);
attrCond.setSchema("username");
attrCond.setExpression("rossini");
SearchCond simpleCond = SearchCond.getNotLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void like() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
- assertEquals("username==ros*", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
+ assertEquals("username==ros*", fiql);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void ilike() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").
- equalToIgnoreCase("ros*").query();
- assertEquals("username=~ros*", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalToIgnoreCase("ros*").query();
+ assertEquals("username=~ros*", fiql);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void nilike() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").
- query();
- assertEquals("username!~ros*", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").query();
+ assertEquals("username!~ros*", fiql);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond simpleCond = SearchCond.getNotLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void isNull() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
- assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
+ assertEquals("loginDate==" + SpecialAttr.NULL, fiql);
AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNULL);
attrCond.setSchema("loginDate");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void isNotNull() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
- assertEquals("loginDate!=" + SpecialAttr.NULL, fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
+ assertEquals("loginDate!=" + SpecialAttr.NULL, fiql);
AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
attrCond.setSchema("loginDate");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void relationships() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
inRelationships("ca20ffca-1305-442f-be9a-3723a0cd88ca").query();
- assertEquals(SpecialAttr.RELATIONSHIPS + "==ca20ffca-1305-442f-be9a-3723a0cd88ca", fiqlExpression);
+ assertEquals(SpecialAttr.RELATIONSHIPS + "==ca20ffca-1305-442f-be9a-3723a0cd88ca", fiql);
RelationshipCond relationshipCond = new RelationshipCond();
relationshipCond.setAnyObject("ca20ffca-1305-442f-be9a-3723a0cd88ca");
SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void relationshipTypes() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
- assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
+ assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiql);
RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
relationshipCond.setRelationshipTypeKey("type1");
SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
- fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
+ fiql = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
assertEquals(
SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
- fiqlExpression);
+ fiql);
}
@Test
public void groups() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
inGroups("e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed").query();
- assertEquals(SpecialAttr.GROUPS + "==e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed", fiqlExpression);
+ assertEquals(SpecialAttr.GROUPS + "==e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed", fiql);
MembershipCond groupCond = new MembershipCond();
groupCond.setGroup("e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed");
SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void roles() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
- assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
+ assertEquals(SpecialAttr.ROLES + "==User reviewer", fiql);
RoleCond roleCond = new RoleCond();
roleCond.setRole("User reviewer");
SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void dynRealms() {
String dynRealm = UUID.randomUUID().toString();
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inDynRealms(dynRealm).query();
- assertEquals(SpecialAttr.DYNREALMS + "==" + dynRealm, fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().inDynRealms(dynRealm).query();
+ assertEquals(SpecialAttr.DYNREALMS + "==" + dynRealm, fiql);
DynRealmCond dynRealmCond = new DynRealmCond();
dynRealmCond.setDynRealm(dynRealm);
SearchCond simpleCond = SearchCond.getLeafCond(dynRealmCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void resources() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
- assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
+ assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiql);
ResourceCond resCond = new ResourceCond();
resCond.setResourceKey("resource-ldap");
SearchCond simpleCond = SearchCond.getLeafCond(resCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void assignable() {
- String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable().query();
- assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiqlExpression);
+ String fiql = new GroupFiqlSearchConditionBuilder().isAssignable().query();
+ assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiql);
AssignableCond assignableCond = new AssignableCond();
assignableCond.setRealmFullPath("/even/two");
SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression, "/even/two"));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql, "/even/two"));
}
@Test
public void type() {
- String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
- assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
+ String fiql = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
+ assertEquals(SpecialAttr.TYPE + "==PRINTER", fiql);
AnyTypeCond acond = new AnyTypeCond();
acond.setAnyTypeKey("PRINTER");
SearchCond simpleCond = SearchCond.getLeafCond(acond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void member() {
- String fiqlExpression = new GroupFiqlSearchConditionBuilder().withMembers("rossini").query();
- assertEquals(SpecialAttr.MEMBER + "==rossini", fiqlExpression);
+ String fiql = new GroupFiqlSearchConditionBuilder().withMembers("rossini").query();
+ assertEquals(SpecialAttr.MEMBER + "==rossini", fiql);
MemberCond mcond = new MemberCond();
mcond.setMember("rossini");
SearchCond simpleCond = SearchCond.getLeafCond(mcond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void and() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();
- assertEquals("fullname==*o*;fullname==*i*", fiqlExpression);
+ assertEquals("fullname==*o*;fullname==*i*", fiql);
AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
fullnameLeafCond1.setSchema("fullname");
@@ -279,17 +275,17 @@ public class SearchCondConverterTest {
SearchCond.getLeafCond(fullnameLeafCond1),
SearchCond.getLeafCond(fullnameLeafCond2));
- assertEquals(andCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(andCond, SearchCondConverter.convert(fiql));
}
@Test
public void or() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*", "*i*", "*ini").query();
- assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
- fiqlExpression = new UserFiqlSearchConditionBuilder().
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiql);
+ fiql = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
- assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiql);
AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
fullnameLeafCond1.setSchema("fullname");
@@ -306,7 +302,7 @@ public class SearchCondConverterTest {
SearchCond.getLeafCond(fullnameLeafCond2),
SearchCond.getLeafCond(fullnameLeafCond3)));
- assertEquals(orCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(orCond, SearchCondConverter.convert(fiql));
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 e0545d2..3cf4376 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
@@ -147,7 +147,8 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
authorized = !CollectionUtils.intersection(findDynRealms(anyObject.getKey()), authRealms).isEmpty();
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
- throw new DelegatedAdministrationException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+ throw new DelegatedAdministrationException(
+ anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT, anyObject.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 6cec27a..4c79d1b 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
@@ -171,7 +171,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
- throw new DelegatedAdministrationException(AnyTypeKind.GROUP, group.getKey());
+ throw new DelegatedAdministrationException(
+ group.getRealm().getFullPath(), AnyTypeKind.GROUP, group.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 afa83f4..f3ada03 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
@@ -190,7 +190,8 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
authorized = !CollectionUtils.intersection(findDynRealms(user.getKey()), authRealms).isEmpty();
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
- throw new DelegatedAdministrationException(AnyTypeKind.USER, user.getKey());
+ throw new DelegatedAdministrationException(
+ user.getRealm().getFullPath(), AnyTypeKind.USER, user.getKey());
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index 1ff733b..718216e 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -99,7 +99,9 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
builder = sce.isComposite()
? getSyncopeClientCompositeExceptionResponse(sce.asComposite())
: getSyncopeClientExceptionResponse(sce);
- } else if (ex instanceof DelegatedAdministrationException) {
+ } else if (ex instanceof DelegatedAdministrationException
+ || ExceptionUtils.getRootCause(ex) instanceof DelegatedAdministrationException) {
+
builder = builder(ClientExceptionType.DelegatedAdministration, ExceptionUtils.getRootCauseMessage(ex));
} else if (ex instanceof EntityExistsException || ex instanceof DuplicateException
|| ex instanceof PersistenceException && ex.getCause() instanceof EntityExistsException) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/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 be378a5..0ee414a 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,10 +24,14 @@ public class DelegatedAdministrationException extends RuntimeException {
private static final long serialVersionUID = 7540587364235915081L;
- public DelegatedAdministrationException(final AnyTypeKind type, final String key) {
- super("Missing entitlement or realm administration for "
+ public DelegatedAdministrationException(final String realm, final AnyTypeKind type, final String key) {
+ super("Missing entitlement or realm administration under " + realm + " for "
+ (key == null
? "new " + type
: type + " " + key));
}
+
+ public DelegatedAdministrationException(final AnyTypeKind type, final String key) {
+ super("The requested UPDATE would alter the set of dynamic realms for " + type + " " + key);
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1ad30558/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
index 1ad59ea..caf1623 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
@@ -41,6 +41,7 @@ import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.RoleTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
import org.apache.syncope.common.rest.api.service.DynRealmService;
@@ -182,6 +183,18 @@ public class DynRealmITCase extends AbstractITCase {
// USER_UPDATE
UserPatch userPatch = new UserPatch();
userPatch.setKey(userKey);
+ userPatch.getResources().add(new StringPatchItem.Builder().
+ value(RESOURCE_NAME_LDAP).operation(PatchOperation.DELETE).build());
+ // this will fail because unassigning resource-ldap would result in removing the user
+ // from the dynamic realm
+ try {
+ delegatedUserService.update(userPatch);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+ }
+ // this will succeed instead
+ userPatch.getResources().clear();
userPatch.getResources().add(new StringPatchItem.Builder().value(RESOURCE_NAME_NOPROPAGATION).build());
user = delegatedUserService.update(userPatch).
readEntity(new GenericType<ProvisioningResult<UserTO>>() {
[2/2] syncope git commit: [SYNCOPE-1067] Check that any USER / GROUP
/ ANYOBJECT UPDATE under DynRealm authorization cannot alter the set of
DynRealms
Posted by il...@apache.org.
[SYNCOPE-1067] Check that any USER / GROUP / ANYOBJECT UPDATE under DynRealm authorization cannot alter the set of DynRealms
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f74ce5de
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f74ce5de
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f74ce5de
Branch: refs/heads/master
Commit: f74ce5dee37f7e5157a3c84f00119d2ffa422e6f
Parents: 8683655
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jun 9 11:42:25 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jun 9 11:42:36 2017 +0200
----------------------------------------------------------------------
.../syncope/core/logic/AbstractAnyLogic.java | 70 +++++++++--
.../syncope/core/logic/AnyObjectLogic.java | 15 ++-
.../apache/syncope/core/logic/GroupLogic.java | 42 ++++---
.../apache/syncope/core/logic/UserLogic.java | 24 +++-
.../api/search/SearchCondConverterTest.java | 126 +++++++++----------
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 3 +-
.../core/persistence/jpa/dao/JPAGroupDAO.java | 3 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 3 +-
.../rest/cxf/RestServiceExceptionMapper.java | 4 +-
.../DelegatedAdministrationException.java | 8 +-
.../apache/syncope/fit/core/DynRealmITCase.java | 13 ++
11 files changed, 207 insertions(+), 104 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 066b3d2..7c96979 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
@@ -167,7 +167,7 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
return ImmutablePair.of(any, actions);
}
- protected ProvisioningResult<TO> after(
+ protected ProvisioningResult<TO> afterCreate(
final TO input, final List<PropagationStatus> statuses, final List<LogicActions> actions) {
TO any = input;
@@ -183,6 +183,53 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
return result;
}
+ protected ProvisioningResult<TO> afterUpdate(
+ final TO input,
+ final List<PropagationStatus> statuses,
+ final List<LogicActions> actions,
+ final boolean authDynRealms,
+ final Set<String> dynRealmsBefore) {
+
+ Set<String> dynRealmsAfter = new HashSet<>(input.getDynRealms());
+ if (authDynRealms && !dynRealmsBefore.equals(dynRealmsAfter)) {
+ throw new DelegatedAdministrationException(
+ this instanceof UserLogic
+ ? AnyTypeKind.USER
+ : this instanceof GroupLogic
+ ? AnyTypeKind.GROUP
+ : AnyTypeKind.ANY_OBJECT,
+ input.getKey());
+ }
+
+ TO any = input;
+
+ for (LogicActions action : actions) {
+ any = action.afterUpdate(any);
+ }
+
+ ProvisioningResult<TO> result = new ProvisioningResult<>();
+ result.setEntity(any);
+ result.getPropagationStatuses().addAll(statuses);
+
+ return result;
+ }
+
+ protected ProvisioningResult<TO> afterDelete(
+ final TO input, final List<PropagationStatus> statuses, final List<LogicActions> actions) {
+
+ TO any = input;
+
+ for (LogicActions action : actions) {
+ any = action.afterDelete(any);
+ }
+
+ ProvisioningResult<TO> result = new ProvisioningResult<>();
+ result.setEntity(any);
+ result.getPropagationStatuses().addAll(statuses);
+
+ return result;
+ }
+
private static class StartsWithPredicate implements Predicate<String> {
private final Collection<String> targets;
@@ -204,6 +251,14 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
}
+ 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<>();
@@ -214,18 +269,12 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
// includes dynamic realms
- CollectionUtils.select(allowedRealms, new Predicate<String>() {
-
- @Override
- public boolean evaluate(final String realm) {
- return !realm.startsWith("/");
- }
- }, effective);
+ CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
return effective;
}
- protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+ protected boolean securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
@Override
@@ -243,6 +292,7 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
}
if (!authorized) {
throw new DelegatedAdministrationException(
+ realm,
this instanceof UserLogic
? AnyTypeKind.USER
: this instanceof GroupLogic
@@ -250,6 +300,8 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
: AnyTypeKind.ANY_OBJECT,
key);
}
+
+ return IterableUtils.matchesAny(effectiveRealms, new DynRealmsPredicate());
}
public abstract Date findLastChange(String key);
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 c585dd0..8805221 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
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
@@ -158,7 +159,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
Pair<String, List<PropagationStatus>> created = provisioningManager.create(before.getLeft(), nullPriorityAsync);
- return after(binder.getAnyObjectTO(created.getKey()), created.getRight(), before.getRight());
+ return afterCreate(binder.getAnyObjectTO(created.getKey()), created.getRight(), before.getRight());
}
@Override
@@ -166,6 +167,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
final AnyObjectPatch anyObjectPatch, final boolean nullPriorityAsync) {
AnyObjectTO anyObjectTO = binder.getAnyObjectTO(anyObjectPatch.getKey());
+ Set<String> dynRealmsBefore = new HashSet<>(anyObjectTO.getDynRealms());
Pair<AnyObjectPatch, List<LogicActions>> before = beforeUpdate(anyObjectPatch, anyObjectTO.getRealm());
String realm =
@@ -175,11 +177,16 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
Set<String> effectiveRealms = getEffectiveRealms(
AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
realm);
- securityChecks(effectiveRealms, realm, before.getLeft().getKey());
+ boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
Pair<String, List<PropagationStatus>> updated = provisioningManager.update(anyObjectPatch, nullPriorityAsync);
- return after(binder.getAnyObjectTO(updated.getKey()), updated.getRight(), before.getRight());
+ return afterUpdate(
+ binder.getAnyObjectTO(updated.getKey()),
+ updated.getRight(),
+ before.getRight(),
+ authDynRealms,
+ dynRealmsBefore);
}
@Override
@@ -197,7 +204,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
AnyObjectTO anyObjectTO = new AnyObjectTO();
anyObjectTO.setKey(before.getLeft().getKey());
- return after(anyObjectTO, statuses, before.getRight());
+ return afterDelete(anyObjectTO, statuses, before.getRight());
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 1ddc108..ca3e080 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
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -109,17 +110,22 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
protected EntityFactory entityFactory;
@Override
- protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
- if (!IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+ protected boolean 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) || ownedRealm.equals(RealmUtils.getGroupOwnerRealm(realm, key));
}
- })) {
-
- throw new DelegatedAdministrationException(AnyTypeKind.GROUP, key);
+ });
+ if (!authorized) {
+ authorized = !CollectionUtils.intersection(groupDAO.findDynRealms(key), effectiveRealms).isEmpty();
+ }
+ if (!authorized) {
+ throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP, key);
}
+
+ return IterableUtils.matchesAny(effectiveRealms, new AbstractAnyLogic.DynRealmsPredicate());
}
@Transactional(readOnly = true)
@@ -239,25 +245,33 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
Pair<String, List<PropagationStatus>> created =
provisioningManager.create(before.getLeft(), nullPriorityAsync);
- return after(binder.getGroupTO(created.getKey()), created.getRight(), before.getRight());
+ return afterCreate(binder.getGroupTO(created.getKey()), created.getRight(), before.getRight());
}
@PreAuthorize("hasRole('" + StandardEntitlement.GROUP_UPDATE + "')")
@Override
public ProvisioningResult<GroupTO> update(final GroupPatch groupPatch, final boolean nullPriorityAsync) {
GroupTO groupTO = binder.getGroupTO(groupPatch.getKey());
+ Set<String> dynRealmsBefore = new HashSet<>(groupTO.getDynRealms());
Pair<GroupPatch, List<LogicActions>> before = beforeUpdate(groupPatch, groupTO.getRealm());
- if (before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
- Set<String> effectiveRealms = getEffectiveRealms(
- AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
- before.getLeft().getRealm().getValue());
- securityChecks(effectiveRealms, before.getLeft().getRealm().getValue(), before.getLeft().getKey());
- }
+ String realm =
+ before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
+ ? before.getLeft().getRealm().getValue()
+ : groupTO.getRealm();
+ Set<String> effectiveRealms = getEffectiveRealms(
+ AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
+ realm);
+ boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
Pair<String, List<PropagationStatus>> updated = provisioningManager.update(groupPatch, nullPriorityAsync);
- return after(binder.getGroupTO(updated.getKey()), updated.getRight(), before.getRight());
+ return afterUpdate(
+ binder.getGroupTO(updated.getKey()),
+ updated.getRight(),
+ before.getRight(),
+ authDynRealms,
+ dynRealmsBefore);
}
@PreAuthorize("hasRole('" + StandardEntitlement.GROUP_DELETE + "')")
@@ -290,7 +304,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
GroupTO groupTO = new GroupTO();
groupTO.setKey(before.getLeft().getKey());
- return after(groupTO, statuses, before.getRight());
+ return afterDelete(groupTO, statuses, before.getRight());
}
@PreAuthorize("hasRole('" + StandardEntitlement.GROUP_UPDATE + "')")
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 02d88cb..54a43f3 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
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
@@ -203,7 +204,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
Pair<String, List<PropagationStatus>> created =
provisioningManager.create(before.getLeft(), storePassword, nullPriorityAsync);
- return after(binder.returnUserTO(binder.getUserTO(created.getKey())), created.getRight(), before.getRight());
+ return afterCreate(
+ binder.returnUserTO(binder.getUserTO(created.getKey())), created.getRight(), before.getRight());
}
@PreAuthorize("isAuthenticated() and not(hasRole('" + StandardEntitlement.ANONYMOUS + "'))")
@@ -223,8 +225,10 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
final UserPatch userPatch, final boolean self, final boolean nullPriorityAsync) {
UserTO userTO = binder.getUserTO(userPatch.getKey());
+ Set<String> dynRealmsBefore = new HashSet<>(userTO.getDynRealms());
Pair<UserPatch, List<LogicActions>> before = beforeUpdate(userPatch, userTO.getRealm());
+ boolean authDynRealms = false;
if (!self
&& before.getLeft().getRealm() != null
&& StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
@@ -232,12 +236,18 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
Set<String> effectiveRealms = getEffectiveRealms(
AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
before.getLeft().getRealm().getValue());
- securityChecks(effectiveRealms, before.getLeft().getRealm().getValue(), before.getLeft().getKey());
+ authDynRealms =
+ securityChecks(effectiveRealms, before.getLeft().getRealm().getValue(), before.getLeft().getKey());
}
Pair<String, List<PropagationStatus>> updated = provisioningManager.update(before.getLeft(), nullPriorityAsync);
- return after(binder.returnUserTO(binder.getUserTO(updated.getKey())), updated.getRight(), before.getRight());
+ return afterUpdate(
+ binder.returnUserTO(binder.getUserTO(updated.getKey())),
+ updated.getRight(),
+ before.getRight(),
+ authDynRealms,
+ dynRealmsBefore);
}
protected Pair<String, List<PropagationStatus>> setStatusOnWfAdapter(
@@ -278,10 +288,12 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
statusPatch.setKey(toUpdate.getKey());
Pair<String, List<PropagationStatus>> updated = setStatusOnWfAdapter(statusPatch, nullPriorityAsync);
- return after(
+ return afterUpdate(
binder.returnUserTO(binder.getUserTO(updated.getKey())),
updated.getRight(),
- Collections.<LogicActions>emptyList());
+ Collections.<LogicActions>emptyList(),
+ false,
+ Collections.<String>emptySet());
}
@PreAuthorize("hasRole('" + StandardEntitlement.MUST_CHANGE_PASSWORD + "')")
@@ -371,7 +383,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
deletedTO = binder.getUserTO(before.getLeft().getKey());
}
- return after(binder.returnUserTO(deletedTO), statuses, before.getRight());
+ return afterDelete(binder.returnUserTO(deletedTO), statuses, before.getRight());
}
@PreAuthorize("hasRole('" + StandardEntitlement.USER_UPDATE + "')")
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
index 08b2f12..01fb922 100644
--- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
@@ -43,231 +43,227 @@ public class SearchCondConverterTest {
@Test
public void eq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
- assertEquals("username==rossini", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
+ assertEquals("username==rossini", fiql);
AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
attrCond.setSchema("username");
attrCond.setExpression("rossini");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void ieq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("username").equalToIgnoreCase("rossini").query();
- assertEquals("username=~rossini", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalToIgnoreCase("rossini").query();
+ assertEquals("username=~rossini", fiql);
AnyCond attrCond = new AnyCond(AttributeCond.Type.IEQ);
attrCond.setSchema("username");
attrCond.setExpression("rossini");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void nieq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("username").notEqualTolIgnoreCase("rossini").query();
- assertEquals("username!~rossini", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("rossini").query();
+ assertEquals("username!~rossini", fiql);
AnyCond attrCond = new AnyCond(AttributeCond.Type.IEQ);
attrCond.setSchema("username");
attrCond.setExpression("rossini");
SearchCond simpleCond = SearchCond.getNotLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void like() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
- assertEquals("username==ros*", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
+ assertEquals("username==ros*", fiql);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void ilike() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").
- equalToIgnoreCase("ros*").query();
- assertEquals("username=~ros*", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").equalToIgnoreCase("ros*").query();
+ assertEquals("username=~ros*", fiql);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void nilike() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").
- query();
- assertEquals("username!~ros*", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").query();
+ assertEquals("username!~ros*", fiql);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond simpleCond = SearchCond.getNotLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void isNull() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
- assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
+ assertEquals("loginDate==" + SpecialAttr.NULL, fiql);
AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNULL);
attrCond.setSchema("loginDate");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void isNotNull() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
- assertEquals("loginDate!=" + SpecialAttr.NULL, fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
+ assertEquals("loginDate!=" + SpecialAttr.NULL, fiql);
AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
attrCond.setSchema("loginDate");
SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void relationships() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
inRelationships("ca20ffca-1305-442f-be9a-3723a0cd88ca").query();
- assertEquals(SpecialAttr.RELATIONSHIPS + "==ca20ffca-1305-442f-be9a-3723a0cd88ca", fiqlExpression);
+ assertEquals(SpecialAttr.RELATIONSHIPS + "==ca20ffca-1305-442f-be9a-3723a0cd88ca", fiql);
RelationshipCond relationshipCond = new RelationshipCond();
relationshipCond.setAnyObject("ca20ffca-1305-442f-be9a-3723a0cd88ca");
SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void relationshipTypes() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
- assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
+ assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiql);
RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
relationshipCond.setRelationshipTypeKey("type1");
SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
- fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
+ fiql = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
assertEquals(
SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
- fiqlExpression);
+ fiql);
}
@Test
public void groups() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
inGroups("e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed").query();
- assertEquals(SpecialAttr.GROUPS + "==e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed", fiqlExpression);
+ assertEquals(SpecialAttr.GROUPS + "==e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed", fiql);
MembershipCond groupCond = new MembershipCond();
groupCond.setGroup("e7ff94e8-19c9-4f0a-b8b7-28327edbf6ed");
SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void roles() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
- assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
+ assertEquals(SpecialAttr.ROLES + "==User reviewer", fiql);
RoleCond roleCond = new RoleCond();
roleCond.setRole("User reviewer");
SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void dynRealms() {
String dynRealm = UUID.randomUUID().toString();
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inDynRealms(dynRealm).query();
- assertEquals(SpecialAttr.DYNREALMS + "==" + dynRealm, fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().inDynRealms(dynRealm).query();
+ assertEquals(SpecialAttr.DYNREALMS + "==" + dynRealm, fiql);
DynRealmCond dynRealmCond = new DynRealmCond();
dynRealmCond.setDynRealm(dynRealm);
SearchCond simpleCond = SearchCond.getLeafCond(dynRealmCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void resources() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
- assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
+ String fiql = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
+ assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiql);
ResourceCond resCond = new ResourceCond();
resCond.setResourceKey("resource-ldap");
SearchCond simpleCond = SearchCond.getLeafCond(resCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void assignable() {
- String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable().query();
- assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiqlExpression);
+ String fiql = new GroupFiqlSearchConditionBuilder().isAssignable().query();
+ assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiql);
AssignableCond assignableCond = new AssignableCond();
assignableCond.setRealmFullPath("/even/two");
SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression, "/even/two"));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql, "/even/two"));
}
@Test
public void type() {
- String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
- assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
+ String fiql = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
+ assertEquals(SpecialAttr.TYPE + "==PRINTER", fiql);
AnyTypeCond acond = new AnyTypeCond();
acond.setAnyTypeKey("PRINTER");
SearchCond simpleCond = SearchCond.getLeafCond(acond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void member() {
- String fiqlExpression = new GroupFiqlSearchConditionBuilder().withMembers("rossini").query();
- assertEquals(SpecialAttr.MEMBER + "==rossini", fiqlExpression);
+ String fiql = new GroupFiqlSearchConditionBuilder().withMembers("rossini").query();
+ assertEquals(SpecialAttr.MEMBER + "==rossini", fiql);
MemberCond mcond = new MemberCond();
mcond.setMember("rossini");
SearchCond simpleCond = SearchCond.getLeafCond(mcond);
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(simpleCond, SearchCondConverter.convert(fiql));
}
@Test
public void and() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();
- assertEquals("fullname==*o*;fullname==*i*", fiqlExpression);
+ assertEquals("fullname==*o*;fullname==*i*", fiql);
AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
fullnameLeafCond1.setSchema("fullname");
@@ -279,17 +275,17 @@ public class SearchCondConverterTest {
SearchCond.getLeafCond(fullnameLeafCond1),
SearchCond.getLeafCond(fullnameLeafCond2));
- assertEquals(andCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(andCond, SearchCondConverter.convert(fiql));
}
@Test
public void or() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ String fiql = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*", "*i*", "*ini").query();
- assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
- fiqlExpression = new UserFiqlSearchConditionBuilder().
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiql);
+ fiql = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
- assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiql);
AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
fullnameLeafCond1.setSchema("fullname");
@@ -306,7 +302,7 @@ public class SearchCondConverterTest {
SearchCond.getLeafCond(fullnameLeafCond2),
SearchCond.getLeafCond(fullnameLeafCond3)));
- assertEquals(orCond, SearchCondConverter.convert(fiqlExpression));
+ assertEquals(orCond, SearchCondConverter.convert(fiql));
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 e0545d2..3cf4376 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
@@ -147,7 +147,8 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
authorized = !CollectionUtils.intersection(findDynRealms(anyObject.getKey()), authRealms).isEmpty();
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
- throw new DelegatedAdministrationException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+ throw new DelegatedAdministrationException(
+ anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT, anyObject.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 6cec27a..4c79d1b 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
@@ -171,7 +171,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
- throw new DelegatedAdministrationException(AnyTypeKind.GROUP, group.getKey());
+ throw new DelegatedAdministrationException(
+ group.getRealm().getFullPath(), AnyTypeKind.GROUP, group.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 afa83f4..f3ada03 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
@@ -190,7 +190,8 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
authorized = !CollectionUtils.intersection(findDynRealms(user.getKey()), authRealms).isEmpty();
}
if (authRealms == null || authRealms.isEmpty() || !authorized) {
- throw new DelegatedAdministrationException(AnyTypeKind.USER, user.getKey());
+ throw new DelegatedAdministrationException(
+ user.getRealm().getFullPath(), AnyTypeKind.USER, user.getKey());
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index 1ff733b..718216e 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -99,7 +99,9 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
builder = sce.isComposite()
? getSyncopeClientCompositeExceptionResponse(sce.asComposite())
: getSyncopeClientExceptionResponse(sce);
- } else if (ex instanceof DelegatedAdministrationException) {
+ } else if (ex instanceof DelegatedAdministrationException
+ || ExceptionUtils.getRootCause(ex) instanceof DelegatedAdministrationException) {
+
builder = builder(ClientExceptionType.DelegatedAdministration, ExceptionUtils.getRootCauseMessage(ex));
} else if (ex instanceof EntityExistsException || ex instanceof DuplicateException
|| ex instanceof PersistenceException && ex.getCause() instanceof EntityExistsException) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/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 be378a5..0ee414a 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,10 +24,14 @@ public class DelegatedAdministrationException extends RuntimeException {
private static final long serialVersionUID = 7540587364235915081L;
- public DelegatedAdministrationException(final AnyTypeKind type, final String key) {
- super("Missing entitlement or realm administration for "
+ public DelegatedAdministrationException(final String realm, final AnyTypeKind type, final String key) {
+ super("Missing entitlement or realm administration under " + realm + " for "
+ (key == null
? "new " + type
: type + " " + key));
}
+
+ public DelegatedAdministrationException(final AnyTypeKind type, final String key) {
+ super("The requested UPDATE would alter the set of dynamic realms for " + type + " " + key);
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f74ce5de/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
index 1ad59ea..caf1623 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DynRealmITCase.java
@@ -41,6 +41,7 @@ import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.RoleTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
import org.apache.syncope.common.rest.api.service.DynRealmService;
@@ -182,6 +183,18 @@ public class DynRealmITCase extends AbstractITCase {
// USER_UPDATE
UserPatch userPatch = new UserPatch();
userPatch.setKey(userKey);
+ userPatch.getResources().add(new StringPatchItem.Builder().
+ value(RESOURCE_NAME_LDAP).operation(PatchOperation.DELETE).build());
+ // this will fail because unassigning resource-ldap would result in removing the user
+ // from the dynamic realm
+ try {
+ delegatedUserService.update(userPatch);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+ }
+ // this will succeed instead
+ userPatch.getResources().clear();
userPatch.getResources().add(new StringPatchItem.Builder().value(RESOURCE_NAME_NOPROPAGATION).build());
user = delegatedUserService.update(userPatch).
readEntity(new GenericType<ProvisioningResult<UserTO>>() {