From 86bcc1192eebe6366af32b13ca233a7063206f0f Mon Sep 17 00:00:00 2001 From: jensp Date: Thu, 15 Jun 2017 12:55:30 +0000 Subject: [PATCH] CCM NG/ccm-cms: Bugfixes git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4784 8810af33-2d31-482b-a856-94f89814c4df --- .../com/arsdigita/cms/dispatcher/CMSPage.java | 4 +- .../contentsection/ContentItemRepository.java | 42 ++++++++++++++--- .../org/libreccm/security/RoleManager.java | 47 +++++++++++++++++-- 3 files changed, 82 insertions(+), 11 deletions(-) diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java index 83ad1092c..915048cc1 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java @@ -293,11 +293,13 @@ public class CMSPage extends Page implements ResourceHandler { if (itemId != null) { final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final ContentItemRepository itemRepo = cdiUtil.findBean(ContentItemRepository.class); - final ContentItem item = itemRepo.findById(Long.parseLong("item_id")).get(); + final ContentItem item = itemRepo + .findById(Long.parseLong(itemId)).get(); final PermissionChecker permissionChecker = cdiUtil.findBean( PermissionChecker.class); permissionChecker.checkPermission(ItemPrivileges.PREVIEW, item); + CMS.getContext().setContentItem(item); } final Document document = buildDocument(request, response); diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemRepository.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemRepository.java index b09a6928f..29c1a1ba9 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemRepository.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemRepository.java @@ -32,6 +32,7 @@ import org.libreccm.core.CcmObjectRepository; import org.libreccm.core.UnexpectedErrorException; import org.libreccm.security.PermissionChecker; import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; import java.util.List; import java.util.Optional; @@ -44,8 +45,11 @@ import javax.persistence.TypedQuery; import org.libreccm.security.Shiro; import org.libreccm.security.User; +import org.libreccm.security.UserManager; +import org.libreccm.security.UserRepository; import org.libreccm.workflow.Workflow; +import java.util.ArrayList; import java.util.Collections; import java.util.stream.Collectors; @@ -75,6 +79,15 @@ public class ContentItemRepository @Inject private Shiro shiro; + @Inject + private UserRepository userRepository; + + @Inject + private UserManager userManager; + + @Inject + private RoleManager roleManager; + @Inject private PermissionChecker permissionChecker; @@ -110,6 +123,7 @@ public class ContentItemRepository * @return The content item identified by the provided {@code itemId} or * nothing if there is such content item. */ + @Transactional(Transactional.TxType.REQUIRED) public Optional findById(final long itemId) { final TypedQuery query = getEntityManager() @@ -166,6 +180,7 @@ public class ContentItemRepository * @return The content item identified by the provided {@code uuid} or * nothing if there is such content item. */ + @Transactional(Transactional.TxType.REQUIRED) public Optional findByUuid(final String uuid) { final TypedQuery query = getEntityManager() @@ -193,6 +208,7 @@ public class ContentItemRepository * {@link Optional} if there is no such item or if it is not of the * requested type. */ + @Transactional(Transactional.TxType.REQUIRED) @SuppressWarnings("unchecked") public Optional findByUuid(final String uuid, final Class type) { @@ -224,6 +240,7 @@ public class ContentItemRepository * * @return A list of all content items of the requested type. */ + @Transactional(Transactional.TxType.REQUIRED) @SuppressWarnings("unchecked") public List findByType(final Class type) { @@ -242,6 +259,7 @@ public class ContentItemRepository * * @return A list of all items in the provided folder. */ + @Transactional(Transactional.TxType.REQUIRED) public List findByFolder(final Category folder) { final TypedQuery query = getEntityManager() @@ -260,6 +278,7 @@ public class ContentItemRepository * * @return The number of content items in the category/folder. */ + @Transactional(Transactional.TxType.REQUIRED) public long countItemsInFolder(final Category folder) { final TypedQuery query = getEntityManager() @@ -499,20 +518,29 @@ public class ContentItemRepository final Optional user = shiro.getUser(); final List roles; if (user.isPresent()) { - roles = user - .get() - .getRoleMemberships() - .stream() - .map(membership -> membership.getRole()) - .collect(Collectors.toList()); + final User theUser = userRepository + .findById(user.get().getPartyId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format( + "No user with id %d in the database. " + + "Where did that ID come from?", + user.get().getPartyId()))); + roles = roleManager.findAllRolesForUser(theUser); } else { + roles = Collections.emptyList(); } final boolean isSystemUser = shiro.isSystemUser(); final boolean isAdmin = permissionChecker.isPermitted("*"); - query.setParameter("roles", roles); + // The roles collection is passed to an IN JPQL query. JPQL/SQL + // does not allow empty collections as paramete of IN. But null works... + if (roles.isEmpty()) { + query.setParameter("roles", null); + } else { + query.setParameter("roles", roles); + } query.setParameter("isSystemUser", isSystemUser); query.setParameter("isAdmin", isAdmin); } diff --git a/ccm-core/src/main/java/org/libreccm/security/RoleManager.java b/ccm-core/src/main/java/org/libreccm/security/RoleManager.java index c9c4b06b7..95fb39216 100644 --- a/ccm-core/src/main/java/org/libreccm/security/RoleManager.java +++ b/ccm-core/src/main/java/org/libreccm/security/RoleManager.java @@ -20,7 +20,11 @@ package org.libreccm.security; import org.libreccm.core.CoreConstants; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; @@ -125,11 +129,12 @@ public class RoleManager { /** * Determines if a role is assigned to a party. - * + * * @param party The party to check. - * @param role The role to check. + * @param role The role to check. + * * @return {@code true} if the provided {@code role} is assigned to the - * provided {@code party}. + * provided {@code party}. */ public boolean hasRole(final Party party, final Role role) { final TypedQuery query = entityManager @@ -142,4 +147,40 @@ public class RoleManager { return !result.isEmpty(); } + /** + * Finds all roles directly or indirectly assigned to a user. + * + * @param user The user + * + * @return A list of all roles assigned to the user or to a group the user + * is a member of, sorted by name. + */ + @Transactional(Transactional.TxType.REQUIRED) + public List findAllRolesForUser(final User user) { + + final List directlyAssigned = user + .getRoleMemberships() + .stream() + .map(membership -> membership.getRole()) + .collect(Collectors.toList()); + + final Set roles = new HashSet<>(); + + final List groups = user + .getGroupMemberships() + .stream() + .map(membership -> membership.getGroup()) + .collect(Collectors.toList()); + + for (final Group group : groups) { + roles.addAll(group + .getRoleMemberships() + .stream() + .map(membership -> membership.getRole()) + .collect(Collectors.toList())); + } + + return new ArrayList<>(roles); + } + }