[SYNCOPE-119] (re)Introducing Roles
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/18958ba2 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/18958ba2 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/18958ba2 Branch: refs/heads/master Commit: 18958ba234672741adba9b9fa42a503166b9692a Parents: 423e4cc Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Fri Apr 10 15:11:19 2015 +0200 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Fri Apr 10 15:11:19 2015 +0200 ---------------------------------------------------------------------- .../apache/syncope/common/lib/to/RoleTO.java | 87 +++++++++++++ .../syncope/common/lib/types/Entitlement.java | 103 +++++++++++++++ .../common/rest/api/service/RoleService.java | 97 ++++++++++++++ .../syncope/core/logic/NotificationLogic.java | 20 +-- .../apache/syncope/core/logic/RoleLogic.java | 129 +++++++++++++++++++ .../core/misc/search/SearchCondConverter.java | 6 +- .../core/persistence/api/dao/RoleDAO.java | 40 ++++++ .../core/persistence/api/entity/Role.java | 43 +++++++ .../core/persistence/jpa/dao/JPARealmDAO.java | 11 ++ .../core/persistence/jpa/dao/JPARoleDAO.java | 89 +++++++++++++ .../persistence/jpa/entity/JPAConnInstance.java | 2 +- .../jpa/entity/JPAEntityFactory.java | 3 + .../jpa/entity/JPAExternalResource.java | 2 +- .../persistence/jpa/entity/JPANotification.java | 2 +- .../core/persistence/jpa/entity/JPARole.java | 125 ++++++++++++++++++ .../resources/META-INF/spring-orm-oracle.xml | 9 ++ .../resources/META-INF/spring-orm-sqlserver.xml | 9 ++ .../src/main/resources/META-INF/spring-orm.xml | 9 ++ .../src/main/resources/content.xml | 9 +- .../persistence/jpa/entity/EntitlementTest.java | 2 +- .../core/persistence/jpa/entity/RoleTest.java | 109 ++++++++++++++++ .../persistence/jpa/relationship/RealmTest.java | 60 +++++++++ .../src/test/resources/content.xml | 126 ++++++++++-------- .../provisioning/api/data/RoleDataBinder.java | 31 +++++ .../java/data/RoleDataBinderImpl.java | 96 ++++++++++++++ .../core/rest/cxf/service/RoleServiceImpl.java | 67 ++++++++++ .../fit/core/reference/AbstractITCase.java | 4 + .../syncope/fit/core/reference/RoleITCase.java | 124 ++++++++++++++++++ 28 files changed, 1344 insertions(+), 70 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/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 new file mode 100644 index 0000000..f7e46de --- /dev/null +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.common.lib.to; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import org.apache.syncope.common.lib.AbstractBaseBean; +import org.apache.syncope.common.lib.types.Entitlement; + +@XmlRootElement(name = "role") +@XmlType +public class RoleTO extends AbstractBaseBean { + + private static final long serialVersionUID = 4560822655754800031L; + + private long key; + + private String name; + + private String criteria; + + private final Set<Entitlement> entitlements = EnumSet.noneOf(Entitlement.class); + + private final List<String> realms = new ArrayList<>(); + + public long getKey() { + return key; + } + + public void setKey(final long key) { + this.key = key; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getCriteria() { + return criteria; + } + + public void setCriteria(final String criteria) { + this.criteria = criteria; + } + + @XmlElementWrapper(name = "entitlements") + @XmlElement(name = "entitlement") + @JsonProperty("entitlements") + public Set<Entitlement> getEntitlements() { + return entitlements; + } + + @XmlElementWrapper(name = "realms") + @XmlElement(name = "realm") + @JsonProperty("realms") + public List<String> getRealms() { + return realms; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java new file mode 100644 index 0000000..8e40551 --- /dev/null +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.common.lib.types; + +public enum Entitlement { + + REALM_LIST, + REALM_CREATE, + REALM_UPDATE, + REALM_DELETE, + ROLE_LIST, + ROLE_CREATE, + ROLE_READ, + ROLE_UPDATE, + ROLE_DELETE, + SCHEMA_LIST, + SCHEMA_CREATE, + SCHEMA_READ, + SCHEMA_UPDATE, + SCHEMA_DELETE, + USER_LIST, + USER_CREATE, + USER_READ, + USER_UPDATE, + USER_DELETE, + USER_VIEW, + GROUP_LIST, + GROUP_CREATE, + GROUP_READ, + GROUP_UPDATE, + GROUP_DELETE, + RESOURCE_LIST, + RESOURCE_CREATE, + RESOURCE_READ, + RESOURCE_UPDATE, + RESOURCE_DELETE, + RESOURCE_GETCONNECTOROBJECT, + CONNECTOR_LIST, + CONNECTOR_CREATE, + CONNECTOR_READ, + CONNECTOR_UPDATE, + CONNECTOR_DELETE, + CONNECTOR_RELOAD, + CONFIGURATION_EXPORT, + CONFIGURATION_LIST, + CONFIGURATION_SET, + CONFIGURATION_DELETE, + TASK_LIST, + TASK_CREATE, + TASK_READ, + TASK_UPDATE, + TASK_DELETE, + TASK_EXECUTE, + POLICY_LIST, + POLICY_CREATE, + POLICY_READ, + POLICY_UPDATE, + POLICY_DELETE, + WORKFLOW_DEF_READ, + WORKFLOW_DEF_UPDATE, + WORKFLOW_TASK_LIST, + WORKFLOW_FORM_LIST, + WORKFLOW_FORM_READ, + WORKFLOW_FORM_CLAIM, + WORKFLOW_FORM_SUBMIT, + NOTIFICATION_LIST, + NOTIFICATION_CREATE, + NOTIFICATION_READ, + NOTIFICATION_UPDATE, + NOTIFICATION_DELETE, + REPORT_LIST, + REPORT_READ, + REPORT_CREATE, + REPORT_UPDATE, + REPORT_DELETE, + REPORT_EXECUTE, + LOG_LIST, + LOG_SET_LEVEL, + LOG_DELETE, + AUDIT_LIST, + AUDIT_ENABLE, + AUDIT_DISABLE, + SECURITY_QUESTION_CREATE, + SECURITY_QUESTION_UPDATE, + SECURITY_QUESTION_DELETE; + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java ---------------------------------------------------------------------- diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java new file mode 100644 index 0000000..172af5f --- /dev/null +++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java @@ -0,0 +1,97 @@ +/* + * 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.cxf.jaxrs.model.wadl.Description; +import org.apache.cxf.jaxrs.model.wadl.Descriptions; +import org.apache.cxf.jaxrs.model.wadl.DocTarget; +import org.apache.syncope.common.lib.to.RoleTO; + +/** + * REST operations for roles. + */ +@Path("roles") +public interface RoleService extends JAXRSService { + + /** + * Returns a list of all roles. + * + * @return list of all roles. + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + List<RoleTO> list(); + + /** + * Returns role with matching id. + * + * @param roleKey role id to be read + * @return role with matching id + */ + @GET + @Path("{roleKey}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + RoleTO read(@NotNull @PathParam("roleKey") Long roleKey); + + /** + * Creates a new role. + * + * @param roleTO role to be created + * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created role + */ + @Descriptions({ + @Description(target = DocTarget.RESPONSE, + value = "Featuring <tt>Location</tt> header of created role") + }) + @POST + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + Response create(@NotNull RoleTO roleTO); + + /** + * Updates the role matching the provided id. + * + * @param roleKey role id to be updated + * @param roleTO role to be stored + */ + @PUT + @Path("{roleKey}") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + void update(@NotNull @PathParam("roleKey") Long roleKey, @NotNull RoleTO roleTO); + + /** + * Deletes the role matching the provided id. + * + * @param roleKey role id to be deleted + */ + @DELETE + @Path("{roleKey}") + void delete(@NotNull @PathParam("roleKey") Long roleKey); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java index 8b8c387..c7ad949 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java @@ -43,12 +43,12 @@ public class NotificationLogic extends AbstractTransactionalLogic<NotificationTO private NotificationDataBinder binder; @PreAuthorize("hasRole('NOTIFICATION_READ')") - public NotificationTO read(final Long notificationId) { - Notification notification = notificationDAO.find(notificationId); + public NotificationTO read(final Long notificationKey) { + Notification notification = notificationDAO.find(notificationKey); if (notification == null) { - LOG.error("Could not find notification '" + notificationId + "'"); + LOG.error("Could not find notification '" + notificationKey + "'"); - throw new NotFoundException(String.valueOf(notificationId)); + throw new NotFoundException(String.valueOf(notificationKey)); } return binder.getNotificationTO(notification); @@ -84,17 +84,17 @@ public class NotificationLogic extends AbstractTransactionalLogic<NotificationTO return binder.getNotificationTO(notification); } - @PreAuthorize("hasRole('CONNECTOR_DELETE')") - public NotificationTO delete(final Long notificationId) { - Notification notification = notificationDAO.find(notificationId); + @PreAuthorize("hasRole('NOTIFICATION_DELETE')") + public NotificationTO delete(final Long notificationKey) { + Notification notification = notificationDAO.find(notificationKey); if (notification == null) { - LOG.error("Could not find notification '" + notificationId + "'"); + LOG.error("Could not find notification '" + notificationKey + "'"); - throw new NotFoundException(String.valueOf(notificationId)); + throw new NotFoundException(String.valueOf(notificationKey)); } NotificationTO deleted = binder.getNotificationTO(notification); - notificationDAO.delete(notificationId); + notificationDAO.delete(notificationKey); return deleted; } http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java new file mode 100644 index 0000000..668d263 --- /dev/null +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java @@ -0,0 +1,129 @@ +/* + * 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.RoleTO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.entity.Role; +import org.apache.syncope.core.provisioning.api.data.RoleDataBinder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component +public class RoleLogic extends AbstractTransactionalLogic<RoleTO> { + + @Autowired + private RoleDataBinder binder; + + @Autowired + private RoleDAO roleDAO; + + @PreAuthorize("hasRole('ROLE_READ')") + public RoleTO read(final Long roleKey) { + Role role = roleDAO.find(roleKey); + if (role == null) { + LOG.error("Could not find role '" + roleKey + "'"); + + throw new NotFoundException(String.valueOf(roleKey)); + } + + return binder.getRoleTO(role); + } + + @PreAuthorize("hasRole('ROLE_LIST')") + public List<RoleTO> list() { + return CollectionUtils.collect(roleDAO.findAll(), new Transformer<Role, RoleTO>() { + + @Override + public RoleTO transform(final Role input) { + return binder.getRoleTO(input); + } + }, new ArrayList<RoleTO>()); + } + + @PreAuthorize("hasRole('ROLE_CREATE')") + public RoleTO create(final RoleTO roleTO) { + return binder.getRoleTO(roleDAO.save(binder.create(roleTO))); + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + public RoleTO update(final RoleTO roleTO) { + Role role = roleDAO.find(roleTO.getKey()); + if (role == null) { + LOG.error("Could not find role '" + roleTO.getKey() + "'"); + throw new NotFoundException(String.valueOf(roleTO.getKey())); + } + + binder.update(role, roleTO); + role = roleDAO.save(role); + + return binder.getRoleTO(role); + } + + @PreAuthorize("hasRole('ROLE_DELETE')") + public RoleTO delete(final Long roleKey) { + Role role = roleDAO.find(roleKey); + if (role == null) { + LOG.error("Could not find role '" + roleKey + "'"); + + throw new NotFoundException(String.valueOf(roleKey)); + } + + RoleTO deleted = binder.getRoleTO(role); + roleDAO.delete(roleKey); + return deleted; + } + + @Override + protected RoleTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + Long key = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof Long) { + key = (Long) args[i]; + } else if (args[i] instanceof RoleTO) { + key = ((RoleTO) args[i]).getKey(); + } + } + } + + if ((key != null) && !key.equals(0L)) { + try { + return binder.getRoleTO(roleDAO.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/18958ba2/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java ---------------------------------------------------------------------- diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java index e6756ad..684592c 100644 --- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java +++ b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java @@ -24,7 +24,7 @@ import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; /** - * Converts FIQL expressions to Syncope's <tt>SearchCond</tt>. + * Converts FIQL expressions to Syncope's {@link SearchCond}. */ public final class SearchCondConverter { @@ -36,10 +36,10 @@ public final class SearchCondConverter { * @see FiqlParser */ public static SearchCond convert(final String fiqlExpression) { - FiqlParser<SearchBean> fiqlParser = new FiqlParser<SearchBean>( + FiqlParser<SearchBean> fiqlParser = new FiqlParser<>( SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES); - SearchCondVisitor searchCondVisitor = new SearchCondVisitor(); + SearchCondVisitor searchCondVisitor = new SearchCondVisitor(); searchCondVisitor.visit(fiqlParser.parse(fiqlExpression)); return searchCondVisitor.getQuery(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/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 new file mode 100644 index 0000000..76723b0 --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RoleDAO.java @@ -0,0 +1,40 @@ +/* + * 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.Realm; +import org.apache.syncope.core.persistence.api.entity.Role; + +public interface RoleDAO extends DAO<Role, Long> { + + Role find(Long key); + + Role find(String name); + + List<Role> findByRealm(Realm realm); + + List<Role> findAll(); + + Role save(Role role); + + void delete(Role role); + + void delete(Long key); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/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 new file mode 100644 index 0000000..7753ee2 --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java @@ -0,0 +1,43 @@ +/* + * 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; + +import java.util.List; +import java.util.Set; +import org.apache.syncope.common.lib.types.Entitlement; + +public interface Role extends Entity<Long> { + + String getName(); + + void setName(String name); + + String getCriteria(); + + void setCriteria(String criteria); + + Set<Entitlement> getEntitlements(); + + boolean addRealm(Realm realm); + + boolean removeReam(Realm realm); + + List<? extends Realm> getRealms(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java index 896277c..0921d8c 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java @@ -27,8 +27,11 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; import org.apache.syncope.core.persistence.api.dao.MalformedPathException; import org.apache.syncope.core.persistence.api.dao.RealmDAO; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; import org.apache.syncope.core.persistence.api.entity.Realm; +import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.jpa.entity.JPARealm; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository @@ -36,6 +39,9 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO { private static final Pattern PATH_PATTERN = Pattern.compile("^(/[A-Za-z0-9]+)+"); + @Autowired + private RoleDAO roleDAO; + @Override public Realm getRoot() { TypedQuery<Realm> query = entityManager.createQuery( @@ -128,7 +134,12 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO { @Override public void delete(final Realm realm) { for (Realm toBeDeleted : findDescendants(realm)) { + for (Role role : roleDAO.findByRealm(toBeDeleted)) { + role.getRealms().remove(toBeDeleted); + } + toBeDeleted.setParent(null); + entityManager.remove(toBeDeleted); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java new file mode 100644 index 0000000..f240850 --- /dev/null +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java @@ -0,0 +1,89 @@ +/* + * 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.NoResultException; +import javax.persistence.TypedQuery; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.entity.Realm; +import org.apache.syncope.core.persistence.api.entity.Role; +import org.apache.syncope.core.persistence.jpa.entity.JPARole; +import org.springframework.stereotype.Repository; + +@Repository +public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO { + + @Override + public Role find(final Long key) { + return entityManager.find(JPARole.class, key); + } + + @Override + public Role find(final String name) { + TypedQuery<Role> query = entityManager.createQuery( + "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.name=:name", Role.class); + query.setParameter("name", name); + + Role result = null; + try { + result = query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("Found more than one match", e); + } + + return result; + } + + @Override + public List<Role> findByRealm(final Realm realm) { + TypedQuery<Role> query = entityManager.createQuery( + "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE :realm MEMBER OF e.realms", Role.class); + query.setParameter("realm", realm); + return query.getResultList(); + } + + @Override + public List<Role> findAll() { + TypedQuery<Role> query = entityManager.createQuery( + "SELECT e FROM " + JPARole.class.getSimpleName() + " e ", Role.class); + return query.getResultList(); + } + + @Override + public Role save(final Role role) { + return entityManager.merge(role); + } + + @Override + public void delete(final Role role) { + entityManager.remove(role); + } + + @Override + public void delete(final Long key) { + Role role = find(key); + if (role == null) { + return; + } + + delete(role); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java index 6abedd5..746bf48 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java @@ -94,7 +94,7 @@ public class JPAConnInstance extends AbstractEntity<Long> implements ConnInstanc */ @ElementCollection(fetch = FetchType.EAGER) @Enumerated(EnumType.STRING) - @Column(name = "capabilities") + @Column(name = "capability") @CollectionTable(name = "ConnInstance_capabilities", joinColumns = @JoinColumn(name = "ConnInstance_id", referencedColumnName = "id")) http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java index a4cadf4..4d83b7c 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java @@ -34,6 +34,7 @@ import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.Report; import org.apache.syncope.core.persistence.api.entity.ReportExec; import org.apache.syncope.core.persistence.api.entity.ReportletConfInstance; +import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.SyncPolicy; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue; @@ -144,6 +145,8 @@ public class JPAEntityFactory implements EntityFactory { if (reference.equals(Realm.class)) { result = (T) new JPARealm(); + } else if (reference.equals(Role.class)) { + result = (T) new JPARole(); } else if (reference.equals(User.class)) { result = (T) new JPAUser(); } else if (reference.equals(Group.class)) { http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java index 908422b..2f28485 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java @@ -179,7 +179,7 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme * (Optional) classes for PropagationAction. */ @ElementCollection(fetch = FetchType.EAGER) - @Column(name = "action") + @Column(name = "actionClassName") @CollectionTable(name = "ExternalResource_PropActions", joinColumns = @JoinColumn(name = "ExternalResource_name", referencedColumnName = "name")) http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java index d2acd58..498032e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java @@ -53,10 +53,10 @@ public class JPANotification extends AbstractEntity<Long> implements Notificatio private Long id; @ElementCollection(fetch = FetchType.EAGER) + @Column(name = "event") @CollectionTable(name = "Notification_events", joinColumns = @JoinColumn(name = "Notification_id", referencedColumnName = "id")) - @Column(name = "events") private List<String> events; private String userAbout; http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java new file mode 100644 index 0000000..3d7ac29 --- /dev/null +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java @@ -0,0 +1,125 @@ +/* + * 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.entity; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.persistence.Cacheable; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import org.apache.syncope.common.lib.types.Entitlement; +import org.apache.syncope.core.persistence.api.entity.Realm; +import org.apache.syncope.core.persistence.api.entity.Role; + +@Entity +@Table(name = JPARole.TABLE) +@Cacheable +public class JPARole extends AbstractEntity<Long> implements Role { + + private static final long serialVersionUID = -7657701119422588832L; + + public static final String TABLE = "SyncopeRole"; + + @Id + private Long id; + + @Column(unique = true) + @NotNull + private String name; + + @ElementCollection(fetch = FetchType.EAGER) + @Enumerated(EnumType.STRING) + @Column(name = "entitlement") + @CollectionTable(name = "SyncopeRole_entitlements", + joinColumns = + @JoinColumn(name = "role_id", referencedColumnName = "id")) + private Set<Entitlement> entitlements = new HashSet<>(); + + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(joinColumns = + @JoinColumn(name = "role_id"), + inverseJoinColumns = + @JoinColumn(name = "realm_id")) + @Valid + private List<JPARealm> realms = new ArrayList<>(); + + private String criteria; + + @Override + public Long getKey() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override + public String getCriteria() { + return criteria; + } + + @Override + public void setCriteria(final String criteria) { + this.criteria = criteria; + } + + @Override + public Set<Entitlement> getEntitlements() { + return entitlements; + } + + @Override + public boolean addRealm(final Realm realm) { + checkType(realm, JPARealm.class); + return realms.add((JPARealm) realm); + } + + @Override + public boolean removeReam(final Realm realm) { + checkType(realm, JPARealm.class); + return realms.remove((JPARealm) realm); + } + + @Override + public List<? extends Realm> getRealms() { + return realms; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml index ea3a058..3a61895 100644 --- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml +++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml @@ -48,6 +48,15 @@ under the License. </attributes> </entity> + <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole"> + <attributes> + <id name="id"> + <generated-value generator="SEQ_Role" strategy="TABLE"/> + <table-generator name="SEQ_Role" pk-column-value="SEQ_Role" initial-value="100"/> + </id> + </attributes> + </entity> + <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser"> <attributes> <id name="id"> http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml index ea3a058..97af974 100644 --- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml +++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml @@ -48,6 +48,15 @@ under the License. </attributes> </entity> + <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole"> + <attributes> + <id name="id"> + <generated-value generator="SEQ_Role" strategy="TABLE"/> + <table-generator name="SEQ_Role" pk-column-value="SEQ_Role" initial-value="100"/> + </id> + </attributes> + </entity> + <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser"> <attributes> <id name="id"> http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml index e26f6d0..5921b94 100644 --- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml +++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml @@ -48,6 +48,15 @@ under the License. </attributes> </entity> + <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole"> + <attributes> + <id name="id"> + <generated-value generator="SEQ_Role" strategy="TABLE"/> + <table-generator name="SEQ_Role" pk-column-value="SEQ_Role" initial-value="100"/> + </id> + </attributes> + </entity> + <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser"> <attributes> <id name="id"> http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/main/resources/content.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/resources/content.xml b/core/persistence-jpa/src/main/resources/content.xml index e060c62..6b6c287 100644 --- a/core/persistence-jpa/src/main/resources/content.xml +++ b/core/persistence-jpa/src/main/resources/content.xml @@ -103,18 +103,23 @@ under the License. <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" sender="ad...@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" traceLevel="FAILURES" userAbout="token!=$null"/> - <Notification_events Notification_id="1" events="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/> + <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/> <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" sender="ad...@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" traceLevel="FAILURES" userAbout="token!=$null"/> - <Notification_events Notification_id="2" events="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/> + <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/> <!-- Authentication and authorization --> <Entitlement name="REALM_LIST"/> <Entitlement name="REALM_CREATE"/> <Entitlement name="REALM_UPDATE"/> <Entitlement name="REALM_DELETE"/> + <Entitlement name="ROLE_LIST"/> + <Entitlement name="ROLE_CREATE"/> + <Entitlement name="ROLE_READ"/> + <Entitlement name="ROLE_UPDATE"/> + <Entitlement name="ROLE_DELETE"/> <Entitlement name="SCHEMA_LIST"/> <Entitlement name="SCHEMA_CREATE"/> <Entitlement name="SCHEMA_READ"/> http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/EntitlementTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/EntitlementTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/EntitlementTest.java index ccea7da..82fa875 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/EntitlementTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/EntitlementTest.java @@ -39,7 +39,7 @@ public class EntitlementTest extends AbstractTest { @Test public void findAll() { List<Entitlement> list = entitlementDAO.findAll(); - assertEquals("did not get expected number of entitlements ", 90, list.size()); + assertEquals("did not get expected number of entitlements ", 95, list.size()); } @Test http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java new file mode 100644 index 0000000..b4830cf --- /dev/null +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.entity; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.List; +import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder; +import org.apache.syncope.common.lib.types.Entitlement; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.misc.search.SearchCondConverter; +import org.apache.syncope.core.persistence.api.GroupEntitlementUtil; +import org.apache.syncope.core.persistence.api.dao.EntitlementDAO; +import org.apache.syncope.core.persistence.api.dao.RealmDAO; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO; +import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; +import org.apache.syncope.core.persistence.api.entity.Role; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.jpa.AbstractTest; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class RoleTest extends AbstractTest { + + @Autowired + private RoleDAO roleDAO; + + @Autowired + private EntitlementDAO entitlementDAO; + + @Autowired + private SubjectSearchDAO searchDAO; + + @Autowired + private RealmDAO realmDAO; + + @Test + public void find() { + Role role1 = roleDAO.find(2L); + assertNotNull(role1); + assertNotNull(role1.getName()); + assertFalse(searchDAO.<User>search( + GroupEntitlementUtil.getGroupKeys(entitlementDAO.findAll()), + SearchCondConverter.convert(role1.getCriteria()), + Collections.<OrderByClause>emptyList(), SubjectType.USER).isEmpty()); + assertFalse(role1.getRealms().isEmpty()); + assertFalse(role1.getEntitlements().isEmpty()); + assertTrue(role1.getEntitlements().contains(Entitlement.USER_LIST)); + + Role role2 = roleDAO.find(role1.getName()); + assertEquals(role1, role2); + } + + @Test + public void findAll() { + List<Role> list = roleDAO.findAll(); + assertNotNull(list); + assertFalse(list.isEmpty()); + for (Role role : list) { + assertNotNull(role); + } + } + + @Test + public void save() { + Role role = entityFactory.newEntity(Role.class); + role.setName("new"); + role.setCriteria(new UserFiqlSearchConditionBuilder().inGroups(2L).query()); + role.addRealm(realmDAO.getRoot()); + role.addRealm(realmDAO.find("/even/two")); + role.getEntitlements().add(Entitlement.LOG_LIST); + role.getEntitlements().add(Entitlement.LOG_SET_LEVEL); + + Role actual = roleDAO.save(role); + assertNotNull(actual); + } + + @Test + public void delete() { + assertNotNull(roleDAO.find(3L)); + + roleDAO.delete(3L); + assertNull(roleDAO.find(3L)); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/18958ba2/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java new file mode 100644 index 0000000..e652e62 --- /dev/null +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.relationship; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.apache.syncope.core.persistence.api.dao.RealmDAO; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.entity.Realm; +import org.apache.syncope.core.persistence.api.entity.Role; +import org.apache.syncope.core.persistence.jpa.AbstractTest; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class RealmTest extends AbstractTest { + + @Autowired + private RealmDAO realmDAO; + + @Autowired + private RoleDAO roleDAO; + + @Test + public void test() { + Realm realm = realmDAO.find("/odd"); + assertNotNull(realm); + + Role role = roleDAO.find(1L); + assertTrue(role.getRealms().contains(realm)); + + int beforeSize = role.getRealms().size(); + + realmDAO.delete(realm); + + realmDAO.flush(); + + role = roleDAO.find(1L); + assertEquals(beforeSize - 1, role.getRealms().size()); + } +}