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/08 15:55:16 UTC
[4/4] syncope git commit: [SYNCOPE-1067] Core modifications
[SYNCOPE-1067] Core modifications
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a1bb6723
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a1bb6723
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a1bb6723
Branch: refs/heads/master
Commit: a1bb672317e9bbd605a19e89272456b3ca8066f6
Parents: 6816f17
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Jun 8 17:54:45 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Jun 8 17:54:58 2017 +0200
----------------------------------------------------------------------
.../console/panels/RoleDirectoryPanel.java | 2 +
.../panels/RoleDirectoryPanel.properties | 1 +
.../panels/RoleDirectoryPanel_it.properties | 1 +
.../panels/RoleDirectoryPanel_pt_BR.properties | 1 +
.../panels/RoleDirectoryPanel_ru.properties | 1 +
.../AbstractFiqlSearchConditionBuilder.java | 25 +++
.../syncope/common/lib/search/SpecialAttr.java | 4 +
.../common/lib/search/SyncopeProperty.java | 4 +
.../search/UserFiqlSearchConditionBuilder.java | 12 --
.../org/apache/syncope/common/lib/to/AnyTO.java | 9 +
.../syncope/common/lib/to/DynRealmTO.java | 55 +++++
.../apache/syncope/common/lib/to/RoleTO.java | 9 +
.../common/lib/types/ClientExceptionType.java | 1 +
.../common/lib/types/EntityViolationType.java | 1 +
.../common/lib/types/StandardEntitlement.java | 10 +
.../rest/api/service/DynRealmService.java | 90 ++++++++
.../syncope/core/logic/AbstractAnyLogic.java | 42 +++-
.../syncope/core/logic/AnyObjectLogic.java | 4 -
.../syncope/core/logic/DynRealmLogic.java | 127 +++++++++++
.../apache/syncope/core/logic/GroupLogic.java | 8 -
.../apache/syncope/core/logic/UserLogic.java | 8 -
.../core/persistence/api/dao/AnyDAO.java | 1 +
.../core/persistence/api/dao/AnyObjectDAO.java | 2 +-
.../core/persistence/api/dao/DynRealmDAO.java | 41 ++++
.../core/persistence/api/dao/RoleDAO.java | 2 +-
.../core/persistence/api/dao/UserDAO.java | 4 +-
.../api/dao/search/DynRealmCond.java | 39 ++++
.../persistence/api/dao/search/RoleCond.java | 12 +-
.../persistence/api/dao/search/SearchCond.java | 25 ++-
.../core/persistence/api/entity/DynRealm.java | 23 ++
.../core/persistence/api/entity/Role.java | 4 +
.../api/search/SearchCondVisitor.java | 9 +-
.../api/search/SearchCondConverterTest.java | 20 +-
core/persistence-jpa/pom.xml | 18 ++
.../persistence/jpa/dao/AbstractAnyDAO.java | 39 ++++
.../jpa/dao/AbstractAnySearchDAO.java | 22 ++
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 19 +-
.../persistence/jpa/dao/JPAAnySearchDAO.java | 74 +++++--
.../persistence/jpa/dao/JPADynRealmDAO.java | 162 ++++++++++++++
.../core/persistence/jpa/dao/JPAGroupDAO.java | 16 +-
.../core/persistence/jpa/dao/JPARoleDAO.java | 6 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 37 ++--
.../core/persistence/jpa/dao/SearchSupport.java | 4 +
.../persistence/jpa/entity/JPADynRealm.java | 50 +++++
.../jpa/entity/JPAEntityFactory.java | 3 +
.../core/persistence/jpa/entity/JPARole.java | 20 ++
.../jpa/validation/entity/DynRealmCheck.java | 41 ++++
.../validation/entity/DynRealmValidator.java | 47 +++++
.../entity/EntityValidationListener.java | 2 +
.../src/main/resources/indexes.xml | 3 +
.../src/main/resources/views.xml | 6 +
.../persistence/jpa/inner/AnySearchTest.java | 4 +-
.../core/persistence/jpa/inner/RoleTest.java | 1 -
.../persistence/jpa/outer/AnySearchTest.java | 2 +-
.../persistence/jpa/outer/DynRealmTest.java | 84 ++++++++
.../api/data/DynRealmDataBinder.java | 31 +++
.../java/data/AnyObjectDataBinderImpl.java | 5 +-
.../java/data/DynRealmDataBinderImpl.java | 72 +++++++
.../java/data/GroupDataBinderImpl.java | 7 +-
.../java/data/RoleDataBinderImpl.java | 18 ++
.../java/data/UserDataBinderImpl.java | 7 +-
.../rest/cxf/service/DynRealmServiceImpl.java | 66 ++++++
.../core/spring/security/AuthDataAccessor.java | 69 +++---
.../client/ElasticsearchUtils.java | 8 +-
.../jpa/dao/ElasticsearchAnySearchDAO.java | 49 ++++-
.../org/apache/syncope/fit/AbstractITCase.java | 4 +
.../apache/syncope/fit/core/DynRealmITCase.java | 211 +++++++++++++++++++
.../syncope/fit/core/ExceptionMapperITCase.java | 2 +-
68 files changed, 1652 insertions(+), 154 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
index d911887..1251b6d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
@@ -115,6 +115,8 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
new ResourceModel("entitlements", "Entitlements"), null, "entitlements"));
columns.add(new PropertyColumn<RoleTO, String>(
new ResourceModel("realms"), null, "realms"));
+ columns.add(new PropertyColumn<RoleTO, String>(
+ new ResourceModel("dynRealms"), null, "dynRealms"));
return columns;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel.properties
index 3a27730..d656ca5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel.properties
@@ -17,3 +17,4 @@
any.edit=Edit role ${roleTO.key}
any.new=New role
role.members=Role '${key}' members
+dynRealms=Dynamic Realms
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_it.properties
index 04a466e..34ba4ef 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_it.properties
@@ -17,3 +17,4 @@
any.edit=Modifica ruolo ${roleTO.key}
any.new=Nuovo ruolo
role.members=Utenti membri del rulo '${key}'
+dynRealms=Realm dinamici
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_pt_BR.properties
index 1de6e43..4e55e7e 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_pt_BR.properties
@@ -17,3 +17,4 @@
any.edit=Alterar fun\u00e7\u00e3o ${roleTO.key}
any.new=Novo fun\u00e7\u00e3o
role.members=Role '${key}' members
+dynRealms=Dynamic Realms
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_ru.properties
index b292ea7..61dd821 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RoleDirectoryPanel_ru.properties
@@ -18,3 +18,4 @@
any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u043e\u043b\u044c ${roleTO.key}
any.new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0440\u043e\u043b\u044c
role.members=\u0423\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0440\u043e\u043b\u0438 '${key}'
+dynRealms=Dynamic Realms
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
index 3338c1b..18fee59 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
@@ -65,6 +65,18 @@ public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchCondi
return newBuilderInstance().is(property).notNullValue();
}
+ public CompleteCondition inDynRealms(final String dynRealm, final String... moreDynRealms) {
+ return newBuilderInstance().
+ is(SpecialAttr.DYNREALMS.toString()).
+ inDynRealms(dynRealm, moreDynRealms);
+ }
+
+ public CompleteCondition notInDynRealms(final String dynRealm, final String... moreDynRealms) {
+ return newBuilderInstance().
+ is(SpecialAttr.DYNREALMS.toString()).
+ notInDynRealms(dynRealm, moreDynRealms);
+ }
+
public CompleteCondition hasResources(final String resource, final String... moreResources) {
return newBuilderInstance().is(SpecialAttr.RESOURCES.toString()).hasResources(resource, moreResources);
}
@@ -122,5 +134,18 @@ public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchCondi
public CompleteCondition notEqualTolIgnoreCase(final String literalOrPattern) {
return condition(SyncopeFiqlParser.NIEQ, literalOrPattern);
}
+
+ @Override
+ public CompleteCondition inDynRealms(final String dynRealm, final String... moreDynRealms) {
+ this.result = SpecialAttr.DYNREALMS.toString();
+ return condition(FiqlParser.EQ, dynRealm, (Object[]) moreDynRealms);
+ }
+
+ @Override
+ public CompleteCondition notInDynRealms(final String dynRealm, final String... moreDynRealms) {
+ this.result = SpecialAttr.DYNREALMS.toString();
+ return condition(FiqlParser.NEQ, dynRealm, (Object[]) moreDynRealms);
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
index d8b6672..c744169 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
@@ -56,6 +56,10 @@ public enum SpecialAttr {
*/
ROLES("$roles"),
/**
+ * Applies to users, groups and any objects.
+ */
+ DYNREALMS("$dynRealms"),
+ /**
* Applies to groups.
*/
MEMBER("$member"),
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
index 0d06c5b..fe2d47e 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
@@ -70,4 +70,8 @@ public interface SyncopeProperty extends Property {
*/
CompleteCondition hasNotResources(String resource, String... moreResources);
+ CompleteCondition inDynRealms(String dynRealm, String... moreDynRealms);
+
+ CompleteCondition notInDynRealms(String dynRealm, String... moreDynRealms);
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
index 89d81c7..8cd7421 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
@@ -88,18 +88,6 @@ public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionB
notInRoles(role, moreRoles);
}
- @Override
- public CompleteCondition hasResources(final String resource, final String... moreResources) {
- return newBuilderInstance().
- is(SpecialAttr.RESOURCES.toString()).
- hasResources(resource, moreResources);
- }
-
- @Override
- public CompleteCondition hasNotResources(final String resource, final String... moreResources) {
- return newBuilderInstance().is(SpecialAttr.RESOURCES.toString()).hasNotResources(resource, moreResources);
- }
-
protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
implements UserProperty, CompleteCondition {
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
index b63d4b0..47f1d9b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -46,6 +46,8 @@ public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, A
private String realm;
+ private List<String> dynRealms = new ArrayList<>();
+
private String status;
private final List<String> auxClasses = new ArrayList<>();
@@ -84,6 +86,13 @@ public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, A
this.realm = realm;
}
+ @XmlElementWrapper(name = "dynRealms")
+ @XmlElement(name = "dynRealmF")
+ @JsonProperty("dynRealms")
+ public List<String> getDynRealms() {
+ return dynRealms;
+ }
+
public String getStatus() {
return status;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/to/DynRealmTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/DynRealmTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DynRealmTO.java
new file mode 100644
index 0000000..c218ec6
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DynRealmTO.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import javax.ws.rs.PathParam;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "dynRealm")
+@XmlType
+public class DynRealmTO extends AbstractBaseBean implements EntityTO {
+
+ private static final long serialVersionUID = 4560822655754800031L;
+
+ private String key;
+
+ private String cond;
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @PathParam("key")
+ @Override
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getCond() {
+ return cond;
+ }
+
+ public void setCond(final String cond) {
+ this.cond = cond;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
index cbb8784..9313349 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
@@ -42,6 +42,8 @@ public class RoleTO extends AbstractBaseBean implements EntityTO {
private final List<String> realms = new ArrayList<>();
+ private final List<String> dynRealms = new ArrayList<>();
+
private String dynMembershipCond;
@Override
@@ -69,6 +71,13 @@ public class RoleTO extends AbstractBaseBean implements EntityTO {
return realms;
}
+ @XmlElementWrapper(name = "dynRealms")
+ @XmlElement(name = "dynRealm")
+ @JsonProperty("dynRealms")
+ public List<String> getDynRealms() {
+ return dynRealms;
+ }
+
public String getDynMembershipCond() {
return dynMembershipCond;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 9954b9b..1927737 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -58,6 +58,7 @@ public enum ClientExceptionType {
InvalidMapping(Response.Status.BAD_REQUEST),
InvalidMembership(Response.Status.BAD_REQUEST),
InvalidRealm(Response.Status.BAD_REQUEST),
+ InvalidDynRealm(Response.Status.BAD_REQUEST),
InvalidRole(Response.Status.BAD_REQUEST),
InvalidUser(Response.Status.BAD_REQUEST),
InvalidExternalResource(Response.Status.BAD_REQUEST),
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
index 3107536..6cc7e7c 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
@@ -35,6 +35,7 @@ public enum EntityViolationType {
InvalidPolicy("org.apache.syncope.core.persistence.validation.policy"),
InvalidPropagationTask("org.apache.syncope.core.persistence.validation.propagationtask"),
InvalidRealm("org.apache.syncope.core.persistence.validation.realm"),
+ InvalidDynRealm("org.apache.syncope.core.persistence.validation.dynrealm"),
InvalidReport("org.apache.syncope.core.persistence.validation.report"),
InvalidResource("org.apache.syncope.core.persistence.validation.externalresource"),
InvalidGroupOwner("org.apache.syncope.core.persistence.validation.group.owner"),
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
index aa3fd17..81709f6 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
@@ -78,6 +78,16 @@ public final class StandardEntitlement {
public static final String ROLE_DELETE = "ROLE_DELETE";
+ public static final String DYNREALM_LIST = "DYNREALM_LIST";
+
+ public static final String DYNREALM_CREATE = "DYNREALM_CREATE";
+
+ public static final String DYNREALM_READ = "DYNREALM_READ";
+
+ public static final String DYNREALM_UPDATE = "DYNREALM_UPDATE";
+
+ public static final String DYNREALM_DELETE = "DYNREALM_DELETE";
+
public static final String SCHEMA_LIST = "SCHEMA_LIST";
public static final String SCHEMA_CREATE = "SCHEMA_CREATE";
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DynRealmService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DynRealmService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DynRealmService.java
new file mode 100644
index 0000000..dc9836d
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DynRealmService.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.rest.api.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.DynRealmTO;
+
+/**
+ * REST operations for dynamic realms.
+ */
+@Path("dynRealms")
+public interface DynRealmService extends JAXRSService {
+
+ /**
+ * Returns a list of all dynamic realms.
+ *
+ * @return list of all dynamic realms.
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ List<DynRealmTO> list();
+
+ /**
+ * Returns dynamic realm with matching key.
+ *
+ * @param key dynamic realm key to be read
+ * @return dynamic realm with matching key
+ */
+ @GET
+ @Path("{key}")
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ DynRealmTO read(@NotNull @PathParam("key") String key);
+
+ /**
+ * Creates a new dynamic realm.
+ *
+ * @param dynDynRealmTO dynamic realm to be created
+ * @return Response object featuring Location header of created dynamic realm
+ */
+ @POST
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ Response create(@NotNull DynRealmTO dynDynRealmTO);
+
+ /**
+ * Updates the dynamic realm matching the provided key.
+ *
+ * @param dynDynRealmTO dynamic realm to be stored
+ */
+ @PUT
+ @Path("{key}")
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ void update(@NotNull DynRealmTO dynDynRealmTO);
+
+ /**
+ * Deletes the dynamic realm matching the provided key.
+ *
+ * @param key dynamic realm key to be deleted
+ */
+ @DELETE
+ @Path("{key}")
+ void delete(@NotNull @PathParam("key") String key);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/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 003058f..066b3d2 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
@@ -38,12 +38,16 @@ import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.UserTO;
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;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -55,6 +59,15 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> extends AbstractResourceAssociator<TO> {
@Autowired
+ protected UserDAO userDAO;
+
+ @Autowired
+ protected GroupDAO groupDAO;
+
+ @Autowired
+ protected AnyObjectDAO anyObjectDAO;
+
+ @Autowired
private RealmDAO realmDAO;
@Autowired
@@ -191,9 +204,7 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
}
- protected Set<String> getEffectiveRealms(
- final Set<String> allowedRealms, final String requestedRealm) {
-
+ 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);
@@ -202,18 +213,35 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
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);
+
return effective;
}
protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
- if (!IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+ boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
@Override
public boolean evaluate(final String ownedRealm) {
return realm.startsWith(ownedRealm);
}
- })) {
-
+ });
+ if (!authorized) {
+ AnyDAO<?> anyDAO = this instanceof UserLogic
+ ? userDAO
+ : this instanceof GroupLogic
+ ? groupDAO
+ : anyObjectDAO;
+ authorized = !CollectionUtils.intersection(anyDAO.findDynRealms(key), effectiveRealms).isEmpty();
+ }
+ if (!authorized) {
throw new DelegatedAdministrationException(
this instanceof UserLogic
? AnyTypeKind.USER
@@ -225,7 +253,7 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
}
public abstract Date findLastChange(String key);
-
+
public abstract TO read(String key);
public abstract int count(String realm);
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/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 b4779df..c585dd0 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
@@ -39,7 +39,6 @@ import org.apache.syncope.common.lib.types.AnyEntitlement;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -62,9 +61,6 @@ import org.springframework.transaction.annotation.Transactional;
public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch> {
@Autowired
- protected AnyObjectDAO anyObjectDAO;
-
- @Autowired
protected AnySearchDAO searchDAO;
@Autowired
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java
new file mode 100644
index 0000000..bed7028
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.to.DynRealmTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.DynRealm;
+import org.apache.syncope.core.provisioning.api.data.DynRealmDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DynRealmLogic extends AbstractTransactionalLogic<DynRealmTO> {
+
+ @Autowired
+ private DynRealmDataBinder binder;
+
+ @Autowired
+ private DynRealmDAO dynRealmDAO;
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.DYNREALM_READ + "')")
+ public DynRealmTO read(final String key) {
+ DynRealm dynRealm = dynRealmDAO.find(key);
+ if (dynRealm == null) {
+ LOG.error("Could not find dynamic realm '" + key + "'");
+
+ throw new NotFoundException(key);
+ }
+
+ return binder.getDynRealmTO(dynRealm);
+ }
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.DYNREALM_LIST + "')")
+ public List<DynRealmTO> list() {
+ return CollectionUtils.collect(dynRealmDAO.findAll(), new Transformer<DynRealm, DynRealmTO>() {
+
+ @Override
+ public DynRealmTO transform(final DynRealm input) {
+ return binder.getDynRealmTO(input);
+ }
+ }, new ArrayList<DynRealmTO>());
+ }
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.DYNREALM_CREATE + "')")
+ public DynRealmTO create(final DynRealmTO dynRealmTO) {
+ return binder.getDynRealmTO(dynRealmDAO.save(binder.create(dynRealmTO)));
+ }
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.DYNREALM_UPDATE + "')")
+ public DynRealmTO update(final DynRealmTO dynRealmTO) {
+ DynRealm dynRealm = dynRealmDAO.find(dynRealmTO.getKey());
+ if (dynRealm == null) {
+ LOG.error("Could not find dynamic realm '" + dynRealmTO.getKey() + "'");
+ throw new NotFoundException(dynRealmTO.getKey());
+ }
+
+ return binder.getDynRealmTO(dynRealmDAO.save(binder.update(dynRealm, dynRealmTO)));
+ }
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.DYNREALM_DELETE + "')")
+ public DynRealmTO delete(final String key) {
+ DynRealm dynRealm = dynRealmDAO.find(key);
+ if (dynRealm == null) {
+ LOG.error("Could not find dynamic realm '" + key + "'");
+
+ throw new NotFoundException(key);
+ }
+
+ DynRealmTO deleted = binder.getDynRealmTO(dynRealm);
+ dynRealmDAO.delete(key);
+ return deleted;
+ }
+
+ @Override
+ protected DynRealmTO resolveReference(final Method method, final Object... args)
+ throws UnresolvedReferenceException {
+
+ String key = null;
+
+ if (ArrayUtils.isNotEmpty(args)) {
+ for (int i = 0; key == null && i < args.length; i++) {
+ if (args[i] instanceof String) {
+ key = (String) args[i];
+ } else if (args[i] instanceof DynRealmTO) {
+ key = ((DynRealmTO) args[i]).getKey();
+ }
+ }
+ }
+
+ if (key != null) {
+ try {
+ return binder.getDynRealmTO(dynRealmDAO.find(key));
+ } catch (Throwable ignore) {
+ LOG.debug("Unresolved reference", ignore);
+ throw new UnresolvedReferenceException(ignore);
+ }
+ }
+
+ throw new UnresolvedReferenceException();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/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 b93142d..1ddc108 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
@@ -49,10 +49,8 @@ import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
@@ -84,12 +82,6 @@ import org.springframework.transaction.annotation.Transactional;
public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
@Autowired
- protected GroupDAO groupDAO;
-
- @Autowired
- protected UserDAO userDAO;
-
- @Autowired
protected AnySearchDAO searchDAO;
@Autowired
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/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 7cc5414..02d88cb 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
@@ -45,9 +45,7 @@ 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.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -70,12 +68,6 @@ import org.springframework.transaction.annotation.Transactional;
public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
@Autowired
- protected UserDAO userDAO;
-
- @Autowired
- protected GroupDAO groupDAO;
-
- @Autowired
protected AnySearchDAO searchDAO;
@Autowired
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
index 979e39b..75b0411 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
@@ -93,4 +93,5 @@ public interface AnyDAO<A extends Any<?>> extends DAO<A> {
void delete(A any);
+ List<String> findDynRealms(String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index 448aca6..8a10f0b 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -43,7 +43,7 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
AnyObject authFindByName(String name);
- List<Group> findDynGroups(AnyObject anyObject);
+ List<Group> findDynGroups(String key);
List<ARelationship> findAllRelationships(AnyObject anyObject);
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DynRealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DynRealmDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DynRealmDAO.java
new file mode 100644
index 0000000..a782ea8
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DynRealmDAO.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DynRealm;
+
+public interface DynRealmDAO extends DAO<DynRealm> {
+
+ DynRealm find(String key);
+
+ List<DynRealm> findAll();
+
+ DynRealm save(DynRealm dynRealm);
+
+ void delete(String key);
+
+ void clearDynMembers(DynRealm dynRealm);
+
+ void refreshDynMemberships(Any<?> any);
+
+ void removeDynMemberships(String key);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RoleDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RoleDAO.java
index f76b382..cc29852 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RoleDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RoleDAO.java
@@ -45,6 +45,6 @@ public interface RoleDAO extends DAO<Role> {
void refreshDynMemberships(User user);
- void removeDynMemberships(User user);
+ void removeDynMemberships(String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
index 9e44bb3..2a5d76d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
@@ -42,11 +42,11 @@ public interface UserDAO extends AnyDAO<User> {
List<User> findBySecurityQuestion(SecurityQuestion securityQuestion);
- List<Role> findDynRoles(User user);
+ List<Role> findDynRoles(String key);
Collection<Role> findAllRoles(User user);
- List<Group> findDynGroups(User user);
+ List<Group> findDynGroups(String key);
Collection<Group> findAllGroups(User user);
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
new file mode 100644
index 0000000..e3f3590
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao.search;
+
+public class DynRealmCond extends AbstractSearchCond {
+
+ private static final long serialVersionUID = 9110213614796095482L;
+
+ private String dynRealm;
+
+ public String getDynRealm() {
+ return dynRealm;
+ }
+
+ public void setDynRealm(final String dynRealm) {
+ this.dynRealm = dynRealm;
+ }
+
+ @Override
+ public final boolean isValid() {
+ return dynRealm != null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
index 0ee7648..08972fa 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
@@ -22,18 +22,18 @@ public class RoleCond extends AbstractSearchCond {
private static final long serialVersionUID = 3581958527829522490L;
- private String roleKey;
+ private String role;
- public String getRoleKey() {
- return roleKey;
+ public String getRole() {
+ return role;
}
- public void setRoleKey(final String roleKey) {
- this.roleKey = roleKey;
+ public void setRole(final String role) {
+ this.role = role;
}
@Override
public final boolean isValid() {
- return roleKey != null;
+ return role != null;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
index e87df92..520fc58 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
@@ -49,6 +49,8 @@ public class SearchCond extends AbstractSearchCond {
private RoleCond roleCond;
+ private DynRealmCond dynRealmCond;
+
private ResourceCond resourceCond;
private AssignableCond assignableCond;
@@ -117,6 +119,15 @@ public class SearchCond extends AbstractSearchCond {
return nodeCond;
}
+ public static SearchCond getLeafCond(final DynRealmCond dynRealmCond) {
+ SearchCond nodeCond = new SearchCond();
+
+ nodeCond.type = Type.LEAF;
+ nodeCond.dynRealmCond = dynRealmCond;
+
+ return nodeCond;
+ }
+
public static SearchCond getLeafCond(final ResourceCond resourceCond) {
SearchCond nodeCond = new SearchCond();
@@ -196,7 +207,9 @@ public class SearchCond extends AbstractSearchCond {
}
public static SearchCond getAndCond(final List<SearchCond> conditions) {
- if (conditions.size() > 2) {
+ if (conditions.size() == 1) {
+ return conditions.get(0);
+ } else if (conditions.size() > 2) {
SearchCond removed = conditions.remove(0);
return getAndCond(removed, getAndCond(conditions));
} else {
@@ -215,7 +228,9 @@ public class SearchCond extends AbstractSearchCond {
}
public static SearchCond getOrCond(final List<SearchCond> conditions) {
- if (conditions.size() > 2) {
+ if (conditions.size() == 1) {
+ return conditions.get(0);
+ } else if (conditions.size() > 2) {
SearchCond removed = conditions.remove(0);
return getOrCond(removed, getOrCond(conditions));
} else {
@@ -291,6 +306,10 @@ public class SearchCond extends AbstractSearchCond {
return roleCond;
}
+ public DynRealmCond getDynRealmCond() {
+ return dynRealmCond;
+ }
+
public ResourceCond getResourceCond() {
return resourceCond;
}
@@ -326,7 +345,7 @@ public class SearchCond extends AbstractSearchCond {
switch (type) {
case LEAF:
case NOT_LEAF:
- isValid = (anyTypeCond != null || anyCond != null || attributeCond != null
+ isValid = (anyTypeCond != null || anyCond != null || attributeCond != null || dynRealmCond != null
|| relationshipCond != null || relationshipTypeCond != null || membershipCond != null
|| roleCond != null || resourceCond != null || assignableCond != null || memberCond != null)
&& (anyTypeCond == null || anyTypeCond.isValid())
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRealm.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRealm.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRealm.java
new file mode 100644
index 0000000..e8be2aa
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRealm.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity;
+
+public interface DynRealm extends DynMembership<Any<?>>, ProvidedKeyEntity {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
index 441f87a..68a1e9c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
@@ -30,6 +30,10 @@ public interface Role extends ProvidedKeyEntity {
List<? extends Realm> getRealms();
+ boolean add(DynRealm dynRealm);
+
+ List<? extends DynRealm> getDynRealms();
+
DynRoleMembership getDynMembership();
void setDynMembership(DynRoleMembership dynMembership);
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
index bd95fe8..ce607bf 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
@@ -37,6 +37,7 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.DynRealmCond;
import org.apache.syncope.core.persistence.api.dao.search.MemberCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
@@ -143,10 +144,16 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
case ROLES:
RoleCond roleCond = new RoleCond();
- roleCond.setRoleKey(value);
+ roleCond.setRole(value);
leaf = SearchCond.getLeafCond(roleCond);
break;
+ case DYNREALMS:
+ DynRealmCond dynRealmCond = new DynRealmCond();
+ dynRealmCond.setDynRealm(value);
+ leaf = SearchCond.getLeafCond(dynRealmCond);
+ break;
+
case ASSIGNABLE:
AssignableCond assignableCond = new AssignableCond();
assignableCond.setRealmFullPath(realm);
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/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 144d42d..08b2f12 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
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.search;
import static org.junit.Assert.assertEquals;
+import java.util.UUID;
import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
import org.apache.syncope.common.lib.search.SpecialAttr;
@@ -32,6 +33,7 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.DynRealmCond;
import org.apache.syncope.core.persistence.api.dao.search.MemberCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
@@ -109,7 +111,8 @@ public class SearchCondConverterTest {
@Test
public void nilike() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").query();
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").
+ query();
assertEquals("username!~ros*", fiqlExpression);
AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
@@ -193,13 +196,26 @@ public class SearchCondConverterTest {
assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
RoleCond roleCond = new RoleCond();
- roleCond.setRoleKey("User reviewer");
+ roleCond.setRole("User reviewer");
SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
}
@Test
+ public void dynRealms() {
+ String dynRealm = UUID.randomUUID().toString();
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inDynRealms(dynRealm).query();
+ assertEquals(SpecialAttr.DYNREALMS + "==" + dynRealm, fiqlExpression);
+
+ DynRealmCond dynRealmCond = new DynRealmCond();
+ dynRealmCond.setDynRealm(dynRealm);
+ SearchCond simpleCond = SearchCond.getLeafCond(dynRealmCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
public void resources() {
String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index af58940..9b2a5e4 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -140,6 +140,24 @@ under the License.
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.seleniumhq.selenium</groupId>
+ <artifactId>selenium-java</artifactId>
+ <scope>test</scope>
+ <version>2.44.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.opera</groupId>
+ <artifactId>operadriver</artifactId>
+ <scope>test</scope>
+ <version>1.5</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.seleniumhq.selenium</groupId>
+ <artifactId>selenium-remote-driver</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index 0c4fdcb..89d27e9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
+import static org.apache.syncope.core.persistence.jpa.dao.AbstractDAO.LOG;
+
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
@@ -41,6 +43,7 @@ import org.apache.syncope.core.persistence.api.dao.AllowedSchemas;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
@@ -51,6 +54,7 @@ import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.DynRealm;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Schema;
@@ -80,6 +84,8 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
private AnySearchDAO searchDAO;
+ private DynRealmDAO dynRealmDAO;
+
private AnyUtils anyUtils;
private PlainSchemaDAO plainSchemaDAO() {
@@ -109,6 +115,15 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
return searchDAO;
}
+ protected DynRealmDAO dynRealmDAO() {
+ synchronized (this) {
+ if (dynRealmDAO == null) {
+ dynRealmDAO = ApplicationContextProvider.getApplicationContext().getBean(DynRealmDAO.class);
+ }
+ }
+ return dynRealmDAO;
+ }
+
protected abstract AnyUtils init();
protected AnyUtils anyUtils() {
@@ -539,4 +554,28 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
delete(any);
}
+
+ @Transactional(readOnly = true)
+ @Override
+ public List<String> findDynRealms(final String key) {
+ Query query = entityManager().createNativeQuery(
+ "SELECT dynRealm_id FROM " + JPADynRealmDAO.DYNMEMB_TABLE + " WHERE any_id=?");
+ query.setParameter(1, key);
+
+ List<String> result = new ArrayList<>();
+ for (Object resultKey : query.getResultList()) {
+ String actualKey = resultKey instanceof Object[]
+ ? (String) ((Object[]) resultKey)[0]
+ : ((String) resultKey);
+
+ DynRealm dynRealm = dynRealmDAO().find(actualKey);
+ if (dynRealm == null) {
+ LOG.error("Could not find dynRealm with id {}, even though returned by the native query", actualKey);
+ } else if (!result.contains(dynRealm)) {
+ result.add(actualKey);
+ }
+ }
+ return result;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
index d9b4e95..7c1a1b0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
@@ -29,6 +29,8 @@ import javax.persistence.Entity;
import javax.validation.ValidationException;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -38,6 +40,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
@@ -45,6 +48,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.DynRealmCond;
import org.apache.syncope.core.persistence.api.dao.search.MemberCond;
import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -70,6 +74,9 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
protected RealmDAO realmDAO;
@Autowired
+ protected DynRealmDAO dynRealmDAO;
+
+ @Autowired
protected AnyObjectDAO anyObjectDAO;
@Autowired
@@ -92,6 +99,21 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
return search(SearchCond.getLeafCond(assignableCond), kind);
}
+ protected SearchCond buildEffectiveCond(final SearchCond cond, final Set<String> dynRealmKeys) {
+ List<SearchCond> effectiveConds = CollectionUtils.collect(dynRealmKeys, new Transformer<String, SearchCond>() {
+
+ @Override
+ public SearchCond transform(final String input) {
+ DynRealmCond dynRealmCond = new DynRealmCond();
+ dynRealmCond.setDynRealm(input);
+ return SearchCond.getLeafCond(dynRealmCond);
+ }
+ }, new ArrayList<SearchCond>());
+ effectiveConds.add(cond);
+
+ return SearchCond.getAndCond(effectiveConds);
+ }
+
protected abstract int doCount(Set<String> adminRealms, SearchCond cond, AnyTypeKind kind);
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/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 d010e4b..e0545d2 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
@@ -143,6 +143,9 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
return anyObject.getRealm().getFullPath().startsWith(realm);
}
});
+ if (!authorized) {
+ authorized = !CollectionUtils.intersection(findDynRealms(anyObject.getKey()), authRealms).isEmpty();
+ }
if (authRealms == null || authRealms.isEmpty() || !authorized) {
throw new DelegatedAdministrationException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
}
@@ -213,6 +216,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged, AuthContextUtils.getDomain()));
groupDAO().refreshDynMemberships(merged);
+ dynRealmDAO().refreshDynMemberships(merged);
return merged;
}
@@ -238,6 +242,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
@Override
public void delete(final AnyObject anyObject) {
groupDAO().removeDynMemberships(anyObject);
+ dynRealmDAO().removeDynMemberships(anyObject.getKey());
for (ARelationship relationship : findARelationships(anyObject)) {
relationship.getLeftEnd().getRelationships().remove(relationship);
@@ -259,16 +264,16 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@Override
- public List<Group> findDynGroups(final AnyObject anyObject) {
+ public List<Group> findDynGroups(final String key) {
Query query = entityManager().createNativeQuery(
"SELECT group_id FROM " + JPAGroupDAO.ADYNMEMB_TABLE + " WHERE any_id=?");
- query.setParameter(1, anyObject.getKey());
+ query.setParameter(1, key);
List<Group> result = new ArrayList<>();
- for (Object key : query.getResultList()) {
- String actualKey = key instanceof Object[]
- ? (String) ((Object[]) key)[0]
- : ((String) key);
+ for (Object resultKey : query.getResultList()) {
+ String actualKey = resultKey instanceof Object[]
+ ? (String) ((Object[]) resultKey)[0]
+ : ((String) resultKey);
Group group = groupDAO().find(actualKey);
if (group == null) {
@@ -291,7 +296,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
return input.getRightEnd();
}
}, new ArrayList<Group>()),
- findDynGroups(anyObject));
+ findDynGroups(anyObject.getKey()));
}
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 61d4a7f..cc44ef8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -44,11 +44,13 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.DynRealmCond;
import org.apache.syncope.core.persistence.api.dao.search.MemberCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.DynRealm;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
@@ -61,21 +63,34 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
private static final String EMPTY_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
- private String getAdminRealmsFilter(
+ private Pair<String, Set<String>> getAdminRealmsFilter(
final Set<String> adminRealms,
final SearchSupport svs,
final List<Object> parameters) {
Set<String> realmKeys = new HashSet<>();
+ Set<String> dynRealmKeys = new HashSet<>();
for (String realmPath : RealmUtils.normalize(adminRealms)) {
- Realm realm = realmDAO.findByFullPath(realmPath);
- if (realm == null) {
- LOG.warn("Ignoring invalid realm {}", realmPath);
+ if (realmPath.startsWith("/")) {
+ Realm realm = realmDAO.findByFullPath(realmPath);
+ if (realm == null) {
+ LOG.warn("Ignoring invalid realm {}", realmPath);
+ } else {
+ CollectionUtils.collect(
+ realmDAO.findDescendants(realm), EntityUtils.<Realm>keyTransformer(), realmKeys);
+ }
} else {
- CollectionUtils.collect(
- realmDAO.findDescendants(realm), EntityUtils.<Realm>keyTransformer(), realmKeys);
+ DynRealm dynRealm = dynRealmDAO.find(realmPath);
+ if (dynRealm == null) {
+ LOG.warn("Ignoring invalid dynamic realm {}", realmPath);
+ } else {
+ dynRealmKeys.add(dynRealm.getKey());
+ }
}
}
+ if (!dynRealmKeys.isEmpty()) {
+ CollectionUtils.collect(realmDAO.findAll(), EntityUtils.keyTransformer(), realmKeys);
+ }
StringBuilder adminRealmFilter = new StringBuilder("u.any_id IN (").
append("SELECT any_id FROM ").append(svs.field().name).
@@ -94,20 +109,23 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
adminRealmFilter.append("))");
- return adminRealmFilter.toString();
+ return Pair.of(adminRealmFilter.toString(), dynRealmKeys);
}
@Override
protected int doCount(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind kind) {
List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
- // 1. get the query string from the search condition
SearchSupport svs = new SearchSupport(kind);
- StringBuilder queryString = getQuery(cond, parameters, svs);
+
+ Pair<String, Set<String>> filter = getAdminRealmsFilter(adminRealms, svs, parameters);
+
+ // 1. get the query string from the search condition
+ StringBuilder queryString = getQuery(buildEffectiveCond(cond, filter.getRight()), parameters, svs);
// 2. take into account administrative realms
queryString.insert(0, "SELECT u.any_id FROM (");
- queryString.append(") u WHERE ").append(getAdminRealmsFilter(adminRealms, svs, parameters));
+ queryString.append(") u WHERE ").append(filter.getLeft());
// 3. prepare the COUNT query
queryString.insert(0, "SELECT COUNT(any_id) FROM (");
@@ -132,9 +150,12 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
try {
List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
- // 1. get the query string from the search condition
SearchSupport svs = new SearchSupport(kind);
- StringBuilder queryString = getQuery(cond, parameters, svs);
+
+ Pair<String, Set<String>> filter = getAdminRealmsFilter(adminRealms, svs, parameters);
+
+ // 1. get the query string from the search condition
+ StringBuilder queryString = getQuery(buildEffectiveCond(cond, filter.getRight()), parameters, svs);
// 2. take into account realms and ordering
OrderBySupport obs = parseOrderBy(kind, svs, orderBy);
@@ -146,7 +167,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
queryString.append(')').append(buildWhere(svs, obs));
}
queryString.
- append(getAdminRealmsFilter(adminRealms, svs, parameters)).
+ append(filter.getLeft()).
append(buildOrderBy(obs));
// 3. prepare the search query
@@ -340,6 +361,9 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
} else if (cond.getRoleCond() != null && AnyTypeKind.USER == svs.anyTypeKind) {
query.append(getQuery(cond.getRoleCond(),
cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+ } else if (cond.getDynRealmCond() != null) {
+ query.append(getQuery(cond.getDynRealmCond(),
+ cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
} else if (cond.getMemberCond() != null && AnyTypeKind.GROUP == svs.anyTypeKind) {
query.append(getQuery(cond.getMemberCond(),
cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
@@ -503,7 +527,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
query.append("SELECT DISTINCT any_id FROM ").
append(svs.role().name).append(" WHERE ").
- append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
+ append("role_id=?").append(setParameter(parameters, cond.getRole())).
append(") ");
if (not) {
@@ -514,7 +538,27 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
query.append("SELECT DISTINCT any_id FROM ").
append(svs.dynrolemembership().name).append(" WHERE ").
- append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
+ append("role_id=?").append(setParameter(parameters, cond.getRole())).
+ append("))");
+
+ return query.toString();
+ }
+
+ private String getQuery(
+ final DynRealmCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE (");
+
+ if (not) {
+ query.append("any_id NOT IN (");
+ } else {
+ query.append("any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id FROM ").
+ append(svs.dynrealmmembership().name).append(" WHERE ").
+ append("dynRealm_id=?").append(setParameter(parameters, cond.getDynRealm())).
append("))");
return query.toString();
http://git-wip-us.apache.org/repos/asf/syncope/blob/a1bb6723/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
new file mode 100644
index 0000000..874f0d3
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DynRealm;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.jpa.entity.JPADynRealm;
+import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPADynRealmDAO extends AbstractDAO<DynRealm> implements DynRealmDAO {
+
+ public static final String DYNMEMB_TABLE = "DynRealmMembers";
+
+ @Autowired
+ private ApplicationEventPublisher publisher;
+
+ private AnySearchDAO searchDAO;
+
+ private AnySearchDAO searchDAO() {
+ synchronized (this) {
+ if (searchDAO == null) {
+ searchDAO = ApplicationContextProvider.getApplicationContext().getBean(AnySearchDAO.class);
+ }
+ }
+ return searchDAO;
+ }
+
+ @Override
+ public DynRealm find(final String key) {
+ return entityManager().find(JPADynRealm.class, key);
+ }
+
+ @Override
+ public List<DynRealm> findAll() {
+ TypedQuery<DynRealm> query = entityManager().createQuery(
+ "SELECT e FROM " + JPADynRealm.class.getSimpleName() + " e ", DynRealm.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public DynRealm save(final DynRealm dynRealm) {
+ DynRealm merged = entityManager().merge(dynRealm);
+
+ // refresh dynamic memberships
+ if (merged.getFIQLCond() != null) {
+ clearDynMembers(merged);
+
+ List<Any<?>> matching = searchDAO().search(
+ SearchCondConverter.convert(merged.getFIQLCond()), AnyTypeKind.USER);
+ for (Any<?> any : matching) {
+ Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
+ insert.setParameter(1, any.getKey());
+ insert.setParameter(2, merged.getKey());
+ insert.executeUpdate();
+
+ publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, any, AuthContextUtils.getDomain()));
+ }
+
+ matching = searchDAO().search(
+ SearchCondConverter.convert(merged.getFIQLCond()), AnyTypeKind.GROUP);
+ for (Any<?> any : matching) {
+ Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
+ insert.setParameter(1, any.getKey());
+ insert.setParameter(2, merged.getKey());
+ insert.executeUpdate();
+
+ publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, any, AuthContextUtils.getDomain()));
+ }
+
+ matching = searchDAO().search(
+ SearchCondConverter.convert(merged.getFIQLCond()), AnyTypeKind.ANY_OBJECT);
+ for (Any<?> any : matching) {
+ Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
+ insert.setParameter(1, any.getKey());
+ insert.setParameter(2, merged.getKey());
+ insert.executeUpdate();
+
+ publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, any, AuthContextUtils.getDomain()));
+ }
+ }
+
+ return merged;
+ }
+
+ @Override
+ public void delete(final String key) {
+ DynRealm dynRealm = find(key);
+ if (dynRealm == null) {
+ return;
+ }
+
+ clearDynMembers(dynRealm);
+
+ entityManager().remove(dynRealm);
+ }
+
+ @Override
+ public void clearDynMembers(final DynRealm dynRealm) {
+ Query delete = entityManager().createNativeQuery("DELETE FROM " + DYNMEMB_TABLE + " WHERE dynRealm_id=?");
+ delete.setParameter(1, dynRealm.getKey());
+ delete.executeUpdate();
+ }
+
+ @Transactional
+ @Override
+ public void refreshDynMemberships(final Any<?> any) {
+ for (DynRealm dynRealm : findAll()) {
+ if (dynRealm.getFIQLCond() != null) {
+ Query delete = entityManager().createNativeQuery(
+ "DELETE FROM " + DYNMEMB_TABLE + " WHERE dynRealm_id=? AND any_id=?");
+ delete.setParameter(1, dynRealm.getKey());
+ delete.setParameter(2, any.getKey());
+ delete.executeUpdate();
+
+ if (searchDAO().matches(any, SearchCondConverter.convert(dynRealm.getFIQLCond()))) {
+ Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
+ insert.setParameter(1, any.getKey());
+ insert.setParameter(2, dynRealm.getKey());
+ insert.executeUpdate();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void removeDynMemberships(final String key) {
+ Query delete = entityManager().createNativeQuery("DELETE FROM " + DYNMEMB_TABLE + " WHERE any_id=?");
+ delete.setParameter(1, key);
+ delete.executeUpdate();
+ }
+
+}