From ea84d04c771f523ade83f5c63ce8f59ba3d7bb6a Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 8 Mar 2017 19:18:15 +0000 Subject: [PATCH] CCM NG/ccm-cms: Roles tab git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4624 8810af33-2d31-482b-a856-94f89814c4df Former-commit-id: 6a8fe951a4d828e6d3a00319555488bd1601083f --- .../arsdigita/cms/ui/role/BaseRoleForm.java | 110 ++++--- .../cms/ui/role/BaseRoleItemPane.java | 15 +- .../arsdigita/cms/ui/role/RoleAddForm.java | 70 ++--- .../arsdigita/cms/ui/role/RoleAdminPane.java | 10 +- .../cms/ui/role/RoleAdminPaneController.java | 285 +++++++++++++++++- .../arsdigita/cms/ui/role/RoleEditForm.java | 96 +++--- .../org/librecms/CmsResources.properties | 21 ++ .../org/librecms/CmsResources_de.properties | 21 ++ .../org/librecms/CmsResources_fr.properties | 21 ++ .../org/libreccm/security/Permission.java | 4 + .../libreccm/security/PermissionManager.java | 12 + .../main/java/org/libreccm/security/Role.java | 4 +- 12 files changed, 505 insertions(+), 164 deletions(-) diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleForm.java index 848258694..63d647634 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleForm.java @@ -39,13 +39,13 @@ import org.libreccm.security.Role; import org.librecms.CmsConstants; import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.privileges.AdminPrivileges; +import org.librecms.contentsection.privileges.AssetPrivileges; +import org.librecms.contentsection.privileges.ItemPrivileges; -import java.util.Collection; +import java.util.ArrayList; import java.util.List; import java.util.TooManyListenersException; - - /** * For more detailed information see {@link com.arsdigita.bebop.Form}. * @@ -55,25 +55,25 @@ import java.util.TooManyListenersException; */ class BaseRoleForm extends BaseForm { - final Name m_name; - final Description m_description; - CheckboxGroup m_privileges; + private final Name roleName; + private final Description roleDescription; + private CheckboxGroup privileges; BaseRoleForm(final String key, final GlobalizedMessage message) { super(key, message); - m_name = new Name("label", 200, true); - addField(gz("cms.ui.name"), m_name); + roleName = new Name("label", 200, true); + addField(gz("cms.ui.role.name"), roleName); - m_description = new Description("description", 4000, false); - addField(gz("cms.ui.description"), m_description); + roleDescription = new Description("description", 4000, false); + addField(gz("cms.ui.role.description"), roleDescription); - m_privileges = new CheckboxGroup("privileges"); - addField(gz("cms.ui.role.privileges"), m_privileges); + privileges = new CheckboxGroup("privileges"); + addField(gz("cms.ui.role.privileges"), privileges); try { - m_privileges.addPrintListener(new PrivilegePrinter()); + privileges.addPrintListener(new PrivilegePrinter()); } catch (TooManyListenersException tmle) { throw new UncheckedWrapperException(tmle); } @@ -84,51 +84,85 @@ class BaseRoleForm extends BaseForm { addSecurityListener(AdminPrivileges.ADMINISTER_ROLES); } + protected Name getRoleName() { + return roleName; + } + + protected Description getRoleDescription() { + return roleDescription; + } + + protected CheckboxGroup getPrivileges() { + return privileges; + } + private class PrivilegePrinter implements PrintListener { - @Override - public final void prepare(final PrintEvent e) { - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionManager permissionManager = cdiUtil.findBean(PermissionManager.class); - final CheckboxGroup target = (CheckboxGroup) e.getTarget(); + @Override + public final void prepare(final PrintEvent event) { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PermissionManager permissionManager = cdiUtil.findBean( + PermissionManager.class); - final List possiblePrivileges = permissionManager.listDefiniedPrivileges(CmsConstants.class); + final CheckboxGroup target = (CheckboxGroup) event.getTarget(); + target.clearOptions(); + + final List adminPrivileges = permissionManager + .listDefiniedPrivileges(AdminPrivileges.class); + final List itemPrivileges = permissionManager + .listDefiniedPrivileges(ItemPrivileges.class); + final List assetPrivileges = permissionManager + .listDefiniedPrivileges(AssetPrivileges.class); + + final List possiblePrivileges = new ArrayList<>(); + possiblePrivileges.addAll(adminPrivileges); + possiblePrivileges.addAll(itemPrivileges); + possiblePrivileges.addAll(assetPrivileges); for (final String privilege : possiblePrivileges) { - target.addOption(new Option(privilege, new Label(new GlobalizedMessage(privilege, CmsConstants.CMS_BUNDLE)))); + target.addOption(new Option( + privilege, + new Label(new GlobalizedMessage(privilege, + CmsConstants.CMS_BUNDLE)))); } } + } class NameUniqueListener implements ParameterListener { - private final RoleRequestLocal m_role; + + private final RoleRequestLocal roleRequestLocal; NameUniqueListener(final RoleRequestLocal role) { - m_role = role; + roleRequestLocal = role; } /** * Validates that there are no duplicates between the names of roles. */ - @Override - public final void validate(final ParameterEvent e) - throws FormProcessException { - final PageState state = e.getPageState(); - final ContentSection section = - CMS.getContext().getContentSection(); - final String name = (String) m_name.getValue(state); + @Override + public final void validate(final ParameterEvent event) + throws FormProcessException { - Collection roles = section.getRoles(); + final PageState state = event.getPageState(); + final String name = (String) roleName.getValue(state); - for (Role role : roles) { - if (role.getName().equalsIgnoreCase(name) - && (m_role == null - || !m_role.getRole(state).equals(role))) { - - throw new FormProcessException - (GlobalizationUtil.globalize("cms.ui.role.name_not_unique")); - } + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final RoleAdminPaneController controller = cdiUtil.findBean( + RoleAdminPaneController.class); + final Role selectedRole; + if (roleRequestLocal == null) { + selectedRole = null; + } else { + selectedRole = roleRequestLocal.getRole(state); + } + + if (!controller.validateRoleNameUniqueness(name, selectedRole)) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.role.name_not_unique")); } } + } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java index 7d5d1b45f..6b6497276 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java @@ -30,6 +30,7 @@ import com.arsdigita.bebop.event.TableActionEvent; import com.arsdigita.bebop.table.DefaultTableCellRenderer; import com.arsdigita.bebop.table.TableColumn; import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.cms.CMS; import com.arsdigita.cms.ui.BaseItemPane; import com.arsdigita.cms.ui.PartySearchForm; import com.arsdigita.cms.ui.VisibilityComponent; @@ -46,15 +47,12 @@ import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.security.Party; import org.libreccm.security.PartyRepository; -import org.libreccm.security.Permission; import org.libreccm.security.PermissionChecker; import org.libreccm.security.Role; import org.libreccm.security.RoleManager; import org.librecms.CmsConstants; import org.librecms.contentsection.privileges.AdminPrivileges; -import java.util.stream.Collectors; - /** * This pane is for showing the properties of a {@link Role}. That includes * name, description, permissions and members. The last one is a list of @@ -70,9 +68,6 @@ import java.util.stream.Collectors; */ class BaseRoleItemPane extends BaseItemPane { - private static final Logger LOGGER = LogManager.getLogger( - BaseRoleItemPane.class); - private final RoleRequestLocal roleRequestLocal; private final MemberTable membersTable; @@ -147,18 +142,20 @@ class BaseRoleItemPane extends BaseItemPane { final Role role = roleRequestLocal.getRole(state); - properties.add(new Property(lz("cms.ui.name"), + properties.add(new Property(lz("cms.ui.role.name"), role.getName())); // Right now just loads the default locale description. properties.add(new Property( - lz("cms.ui.description"), + lz("cms.ui.role.description"), role.getDescription().getValue(config.getDefaultLocale()))); // Since Permissions don't seem to have a "pretty" form, the granted privilege is used. final RoleAdminPaneController controller = cdiUtil.findBean( RoleAdminPaneController.class); final String permissions = controller - .generateGrantedPermissionsString(role); + .generateGrantedPermissionsString( + role, + CMS.getContext().getContentSection()); if (permissions.length() > 0) { properties.add(new Property(lz("cms.ui.role.privileges"), diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAddForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAddForm.java index 7a4406302..93751117e 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAddForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAddForm.java @@ -23,75 +23,65 @@ import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.SingleSelectionModel; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.kernel.KernelConfig; import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.configuration.ConfigurationManager; -import org.libreccm.l10n.LocalizedString; - - -import org.libreccm.security.PermissionManager; import org.libreccm.security.Role; -import org.libreccm.security.RoleRepository; /** * Provides a {@link com.arsdigita.bebop.Form} for adding {@link Role roles}. * - + * * @author Michael Pih * @author Justin Ross <jross@redhat.com> * @author Yannick Bülter */ final class RoleAddForm extends BaseRoleForm { - private SingleSelectionModel m_model; + private final SingleSelectionModel selectionModel; - RoleAddForm(SingleSelectionModel model) { + RoleAddForm(final SingleSelectionModel selectionModel) { super("AddStaffRole", gz("cms.ui.role.add")); - m_model = model; + this.selectionModel = selectionModel; - m_name.addValidationListener(new NameUniqueListener(null)); + getRoleName().addValidationListener(new NameUniqueListener(null)); addProcessListener(new ProcessListener()); } /** - * The {@link Role} gets saved to the database and permissions are granted as needed. + * The {@link Role} gets saved to the database and permissions are granted + * as needed. * - * NOTE: The part about granting and revoking privileges is mostly Copy & Paste from {@link RoleEditForm}. - * If you find any bugs or errors in this code, be sure to change it there accordingly. + * NOTE: The part about granting and revoking privileges is mostly Copy & + * Paste from {@link RoleEditForm}. If you find any bugs or errors in this + * code, be sure to change it there accordingly. */ private class ProcessListener implements FormProcessListener { + @Override - public final void process(final FormSectionEvent e) - throws FormProcessException { - final PageState state = e.getPageState(); + public final void process(final FormSectionEvent event) + throws FormProcessException { + + final PageState state = event.getPageState(); + final String roleName = (String) getRoleName().getValue(state); + final String roleDesc = (String) getRoleDescription() + .getValue(state); + final String[] selectedPrivileges = (String[]) getPrivileges() + .getValue(state); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionManager permissionManager = cdiUtil.findBean(PermissionManager.class); - final ConfigurationManager manager = cdiUtil.findBean(ConfigurationManager.class); - final KernelConfig config = manager.findConfiguration(KernelConfig.class); - final RoleRepository roleRepository = cdiUtil.findBean(RoleRepository.class); + final RoleAdminPaneController controller = cdiUtil.findBean( + RoleAdminPaneController.class); + + final Role role = controller.addRole(roleName, + roleDesc, + selectedPrivileges); - final Role role = new Role(); - - role.setName((String) m_name.getValue(state)); - - LocalizedString localizedDescription = role.getDescription(); - localizedDescription.addValue(config.getDefaultLocale(), (String) m_description.getValue(state)); - role.setDescription(localizedDescription); - - //We don't now if the permissions list is empty, so we have to save beforehand to not lose data. - roleRepository.save(role); - - String[] selectedPermissions = (String[]) m_privileges.getValue(state); - - for (String s : selectedPermissions) { - permissionManager.grantPrivilege(s, role); - } - - m_model.setSelectedKey(state, Long.toString(role.getRoleId())); + selectionModel + .setSelectedKey(state, Long.toString(role.getRoleId())); } + } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java index 33863c56f..95541f0e0 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java @@ -197,15 +197,15 @@ public class RoleAdminPane extends BaseAdminPane { @Override public final void process(final FormSectionEvent event) throws FormProcessException { + final PageState state = event.getPageState(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final RoleRepository roleRepository = cdiUtil.findBean( - RoleRepository.class); - final Long id = Long.parseLong(selectionModel.getSelectedKey(state)); - final Role role = roleRepository.findById(id).get(); + final RoleAdminPaneController controller = cdiUtil.findBean( + RoleAdminPaneController.class); - roleRepository.delete(role); + controller.deleteRole(CMS.getContext().getContentSection(), + selectionModel.getSelectedKey(state)); selectionModel.clearSelection(state); } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPaneController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPaneController.java index 020b62010..85f226d45 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPaneController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPaneController.java @@ -18,16 +18,28 @@ */ package com.arsdigita.cms.ui.role; +import com.arsdigita.cms.CMS; +import com.arsdigita.kernel.KernelConfig; + +import org.libreccm.configuration.ConfigurationManager; import org.libreccm.security.Party; import org.libreccm.security.Permission; +import org.libreccm.security.PermissionManager; import org.libreccm.security.Role; import org.libreccm.security.RoleRepository; import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentSectionManager; import org.librecms.contentsection.ContentSectionRepository; +import org.librecms.contentsection.Folder; +import org.librecms.contentsection.privileges.AdminPrivileges; +import org.librecms.contentsection.privileges.AssetPrivileges; +import org.librecms.contentsection.privileges.ItemPrivileges; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; @@ -41,6 +53,9 @@ import javax.transaction.Transactional; @RequestScoped public class RoleAdminPaneController { + @Inject + private PermissionManager permissionManager; + @Inject private ContentSectionRepository sectionRepo; @@ -50,6 +65,9 @@ public class RoleAdminPaneController { @Inject private RoleRepository roleRepo; + @Inject + private ConfigurationManager confManager; + @Transactional(Transactional.TxType.REQUIRED) public List findRolesForContentSection(final ContentSection section) { final ContentSection contentSection = sectionRepo @@ -62,21 +80,53 @@ public class RoleAdminPaneController { return new ArrayList<>(contentSection.getRoles()); } - @Transactional(Transactional.TxType.REQUIRED) - public String generateGrantedPermissionsString(final Role role) { - final Role theRole = roleRepo - .findById(role.getRoleId()) - .orElseThrow(() -> new IllegalArgumentException(String.format( - "No role with ID %d in the database. Where did that Id come from?", - role.getRoleId()))); - - return theRole.getPermissions().stream() + public String[] getGrantedPrivileges(final Role role, + final ContentSection section) { + final List sectionPermissions = permissionManager + .findPermissionsForRoleAndObject(role, section); + final List itemPermissions = permissionManager + .findPermissionsForRoleAndObject(role, + section.getRootDocumentsFolder()); + final List assetPermissions = permissionManager + .findPermissionsForRoleAndObject(role, + section.getRootAssetsFolder()); + final List permissions = new ArrayList<>(); + permissions.addAll(sectionPermissions); + permissions.addAll(itemPermissions); + permissions.addAll(assetPermissions); + final List privileges = permissions.stream() .map(Permission::getGrantedPrivilege) - .collect(Collectors.joining(", ")); + .collect(Collectors.toList()); + + return privileges.toArray(new String[]{}); + } + + @Transactional(Transactional.TxType.REQUIRED) + public String generateGrantedPermissionsString(final Role role, + final ContentSection section) { + + final List sectionPermissions = permissionManager + .findPermissionsForRoleAndObject(role, section); + final List itemPermissions = permissionManager + .findPermissionsForRoleAndObject(role, + section.getRootDocumentsFolder()); + final List assetPermissions = permissionManager + .findPermissionsForRoleAndObject(role, + section.getRootAssetsFolder()); + final List permissions = new ArrayList<>(); + permissions.addAll(sectionPermissions); + permissions.addAll(itemPermissions); + permissions.addAll(assetPermissions); + + return permissions.stream() + .map(Permission::getGrantedPrivilege) + .collect(Collectors.joining("; ")); + } @Transactional(Transactional.TxType.REQUIRED) public List createRoleMemberList(final Role role) { + final Role theRole = roleRepo .findById(role.getRoleId()) .orElseThrow(() -> new IllegalArgumentException(String.format( @@ -92,4 +142,219 @@ public class RoleAdminPaneController { .collect(Collectors.toList()); } + @Transactional(Transactional.TxType.REQUIRED) + public void deleteRole(final ContentSection section, + final String roleId) { + + final Role role = roleRepo.findById(Long.parseLong(roleId)) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No Role with ID %s in the database. Where did that ID come from?", + roleId))); + final ContentSection contentSection = sectionRepo + .findById(section.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No ContentSection with ID %d in the database. " + + "Where did that ID come from?", + section.getObjectId()))); + + sectionManager.removeRoleFromContentSection(contentSection, role); + roleRepo.delete(role); + } + + /** + * + * @param name + * @param selectedRole + * + * @return {@code true} if name is unique, {@code false} otherwise. + */ + @Transactional(Transactional.TxType.REQUIRED) + public boolean validateRoleNameUniqueness(final String name, + final Role selectedRole) { + + final ContentSection section = CMS.getContext().getContentSection(); + + final ContentSection contentSection = sectionRepo + .findById(section.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No ContentSection with ID %d in the database." + + " Where did that ID come from?", + section.getObjectId()))); + + final Collection roles = contentSection.getRoles(); + boolean result = true; + for (final Role role : roles) { + if (role.getName().equalsIgnoreCase(name) + && (selectedRole == null + || selectedRole.getRoleId() != role.getRoleId())) { + result = false; + break; + } + } + + return result; + } + + public void saveRole(final Role role, + final String roleName, + final String roleDescription, + final String[] selectedPermissions) { + + final Role roleToSave = roleRepo.findById(role.getRoleId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No Role with ID %d in the database. Where did that ID come from?", + role.getRoleId()))); + + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + + role.setName(roleName); + role.getDescription().addValue(defaultLocale, roleDescription); + + roleRepo.save(role); + + final ContentSection contentSection = sectionRepo.findById( + CMS.getContext().getContentSection().getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No ContentSection with ID %d in the database." + + "Where did that ID come from?", + CMS.getContext().getContentSection().getObjectId()))); + + final List adminPrivileges = permissionManager + .listDefiniedPrivileges(AdminPrivileges.class); + final List itemPrivileges = permissionManager + .listDefiniedPrivileges(ItemPrivileges.class); + final List assetPrivileges = permissionManager + .listDefiniedPrivileges(AssetPrivileges.class); + + final Folder rootDocumentsFolder = contentSection + .getRootDocumentsFolder(); + final Folder rootAssetsFolder = contentSection.getRootAssetsFolder(); + + final List currentPermissionsSection = permissionManager + .findPermissionsForRoleAndObject(role, contentSection); + final List currentPermissionsDocuments = permissionManager + .findPermissionsForRoleAndObject(role, rootDocumentsFolder); + final List currentPermissionsAssets = permissionManager + .findPermissionsForRoleAndObject(role, rootAssetsFolder); + + //Revoke permissions not in selectedPermissions + revokeNotSelectedPrivileges(selectedPermissions, + role, + currentPermissionsSection); + revokeNotSelectedPrivileges(selectedPermissions, + role, + currentPermissionsDocuments); + revokeNotSelectedPrivileges(selectedPermissions, + role, + currentPermissionsAssets); + + // Grant selected privileges + for (final String privilege : adminPrivileges) { + if (isPrivilegeSelected(selectedPermissions, privilege)) { + permissionManager.grantPrivilege(privilege, + role, + contentSection); + } + } + + for (final String privilege : itemPrivileges) { + if (isPrivilegeSelected(selectedPermissions, privilege)) { + permissionManager.grantPrivilege(privilege, + role, + rootDocumentsFolder); + } + } + + for (final String privilege : assetPrivileges) { + if (isPrivilegeSelected(selectedPermissions, privilege)) { + permissionManager.grantPrivilege(privilege, + role, + rootAssetsFolder); + } + } + } + + private void revokeNotSelectedPrivileges(final String[] selectedPrivileges, + final Role role, + final List permissions) { + for (final Permission permission : permissions) { + if (!isPrivilegeSelected(selectedPrivileges, + permission.getGrantedPrivilege())) { + permissionManager.revokePrivilege( + permission.getGrantedPrivilege(), + role, + permission.getObject()); + } + } + } + + private boolean isPrivilegeSelected( + final String[] selectedPrivileges, final String privilege) { + + return Arrays.stream(selectedPrivileges) + .anyMatch(current -> current.equals(privilege)); + + } + + @Transactional(Transactional.TxType.REQUIRED) + public Role addRole(final String name, + final String description, + final String[] selectedPrivileges) { + + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + + final Role role = new Role(); + role.setName(name); + role.getDescription().addValue(defaultLocale, description); + + roleRepo.save(role); + + final List adminPrivileges = permissionManager + .listDefiniedPrivileges(AdminPrivileges.class); + final List itemPrivileges = permissionManager + .listDefiniedPrivileges(ItemPrivileges.class); + final List assetPrivileges = permissionManager + .listDefiniedPrivileges(AssetPrivileges.class); + + final ContentSection contentSection = sectionRepo.findById( + CMS.getContext().getContentSection().getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No ContentSection with ID %d in the database." + + "Where did that ID come from?", + CMS.getContext().getContentSection().getObjectId()))); + final Folder rootDocumentsFolder = contentSection + .getRootDocumentsFolder(); + final Folder rootAssetsFolder = contentSection.getRootAssetsFolder(); + + for (final String privilege : adminPrivileges) { + if (isPrivilegeSelected(selectedPrivileges, privilege)) { + permissionManager.grantPrivilege(privilege, + role, + contentSection); + } + } + + for (final String privilege : itemPrivileges) { + if (isPrivilegeSelected(selectedPrivileges, privilege)) { + permissionManager.grantPrivilege(privilege, + role, + rootDocumentsFolder); + } + } + + for (final String privilege : assetPrivileges) { + if (isPrivilegeSelected(selectedPrivileges, privilege)) { + permissionManager.grantPrivilege(privilege, + role, + rootAssetsFolder); + } + } + + return role; + } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleEditForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleEditForm.java index 955c5ed57..bdfb7534a 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleEditForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleEditForm.java @@ -23,10 +23,9 @@ import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.event.FormInitListener; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.cms.CMS; import com.arsdigita.kernel.KernelConfig; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.l10n.LocalizedString; @@ -38,6 +37,7 @@ import org.libreccm.security.RoleRepository; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; /** * Represents a {@link com.arsdigita.bebop.Form Form} to edit @@ -47,20 +47,19 @@ import java.util.List; * @author Michael Pih * @author Justin Ross <jross@redhat.com> * @author Yannick Bülter + * @author Jens Pelzetter */ final class RoleEditForm extends BaseRoleForm { - private static final Logger LOGGER = LogManager - .getLogger(RoleEditForm.class); + private final RoleRequestLocal roleRequestLocal; - private final RoleRequestLocal m_role; - - RoleEditForm(RoleRequestLocal role) { + RoleEditForm(final RoleRequestLocal role) { super("EditStaffRole", gz("cms.ui.role.edit")); - m_role = role; + roleRequestLocal = role; - m_name.addValidationListener(new NameUniqueListener(m_role)); + getRoleName().addValidationListener(new NameUniqueListener( + roleRequestLocal)); addInitListener(new InitListener()); addProcessListener(new ProcessListener()); @@ -73,17 +72,26 @@ final class RoleEditForm extends BaseRoleForm { private class InitListener implements FormInitListener { @Override - public final void init(final FormSectionEvent e) { - final PageState state = e.getPageState(); - final Role role = m_role.getRole(state); + public final void init(final FormSectionEvent event) { + final PageState state = event.getPageState(); + final Role role = roleRequestLocal.getRole(state); - m_name.setValue(state, role.getName()); - m_description.setValue(state, role.getDescription()); + final KernelConfig kernelConfig = KernelConfig.getConfig(); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); - final String[] permissions = role.getPermissions().stream(). - map(Permission::getGrantedPrivilege).toArray(String[]::new); + getRoleName().setValue(state, role.getName()); + getRoleDescription().setValue( + state, + role.getDescription().getValue(defaultLocale)); - m_privileges.setValue(state, permissions); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final RoleAdminPaneController controller = cdiUtil.findBean( + RoleAdminPaneController.class); + + final String[] permissions = controller.getGrantedPrivileges( + role, CMS.getContext().getContentSection()); + + getPrivileges().setValue(state, permissions); } } @@ -92,58 +100,26 @@ final class RoleEditForm extends BaseRoleForm { * Updates a role and it's permissions. It uses the * {@link PermissionManager} to grant and revoke permissions as needed. * - * NOTE: The part about granting and revoking privileges is mostly identical - * to {@link RoleAddForm}. If you find any bugs or errors in this code, be - * sure to change it there accordingly. */ private class ProcessListener implements FormProcessListener { @Override - public final void process(final FormSectionEvent e) + public final void process(final FormSectionEvent event) throws FormProcessException { - final PageState state = e.getPageState(); - final Role role = m_role.getRole(state); - role.setName((String) m_name.getValue(state)); + final PageState state = event.getPageState(); + final String roleName = (String) getRoleName().getValue(state); + final String roleDesc = (String) getRoleDescription() + .getValue(state); + final String[] selectedPermissions = (String[]) getPrivileges() + .getValue(state); + final Role role = roleRequestLocal.getRole(state); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionManager permissionManager = cdiUtil.findBean( - PermissionManager.class); - final ConfigurationManager manager = cdiUtil.findBean( - ConfigurationManager.class); - final KernelConfig config = manager.findConfiguration( - KernelConfig.class); - final RoleRepository roleRepository = cdiUtil.findBean( - RoleRepository.class); + final RoleAdminPaneController controller = cdiUtil.findBean( + RoleAdminPaneController.class); - LocalizedString localizedDescription = role.getDescription(); - localizedDescription.addValue(config.getDefaultLocale(), - (String) m_description.getValue(state)); - role.setDescription(localizedDescription); - - //We don't now if the permissions list is empty, so we have to save beforehand to not lose data. - roleRepository.save(role); - - List newPermissions = new ArrayList<>(); - String[] selectedPermissions = (String[]) m_privileges.getValue( - state); - - for (Permission p : role.getPermissions()) { - if (Arrays.stream(selectedPermissions).anyMatch(x -> x.equals(p - .getGrantedPrivilege()))) { - newPermissions.add(p); - } else { - permissionManager.revokePrivilege(p.getGrantedPrivilege(), - role); - } - } - - for (String s : selectedPermissions) { - if (newPermissions.stream().noneMatch(x -> x - .getGrantedPrivilege().equals(s))) { - permissionManager.grantPrivilege(s, role); - } - } + controller.saveRole(role, roleName, roleDesc, selectedPermissions); } } diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties index fdae2cd21..db66272c6 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties @@ -125,3 +125,24 @@ cms.ui.folderform.error.child.name_not_unique=The current folder already contain cms.ui.folderform.error.parent.name_not_unique=The parent folder of the selected folder already contains a child with the name {0}. cms.ui.choose_target_folder=Choose target folder cms.ui.folder.copy=Copy {0} items from {1} +cms.ui.role.staff=Roles +cms.ui.role.intro=Select a role or create a new one +cms.ui.role.staff.add=Create new role +cms.ui.role.details=Role details +cms.ui.role.name=Name: +cms.ui.role.description=Description: +cms.ui.role.privileges=Privileges for this content section: +cms.ui.role.privilege.none=No privileges granted for this content section to the role +cms.ui.role.edit=Edit +cms.ui.role.delete=Delete +cms.ui.role.members=Members +cms.ui.role.member.none=This role has no members +cms.ui.role.member.add=Add member +cms.ui.attention=Warning +cms.ui.role.delete_prompt=Are you sure to delete this role? +cms.ui.delete=Delete +cms.ui.cancel=Cancel +cms.ui.finish=Finish +cms.ui.save=Save +cms.ui.role.name_not_unique=A role with this name already exists. +cms.ui.role.add=Add role diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties index 8412c487f..d47c7c2c2 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties @@ -124,3 +124,24 @@ cms.ui.folderform.error.child.name_not_unique=Der derzeit ausgew\u00e4hlte Ordne cms.ui.folderform.error.parent.name_not_unique=Der \u00fcbergeordnete Ordner enth\u00e4lt bereits einen ein Objekt mit dem Namen {0}. cms.ui.choose_target_folder=Zielordner ausw\u00e4hlen cms.ui.folder.copy=Kopiere {0} Dokumente von {1} nach +cms.ui.role.staff=Rollen +cms.ui.role.intro=W\u00e4hlen Sie eine Rolle oder erstellen Sie einen neue Rolle +cms.ui.role.staff.add=Neue Rolle erzeugen +cms.ui.role.details=Details der Rolle +cms.ui.role.name=Name: +cms.ui.role.description=Beschreibung: +cms.ui.role.privileges=Berechtigungen f\u00fcr die aktuelle Content Section: +cms.ui.role.privilege.none=Dieser Rolle wurden keine Berechtigungen f\u00fcr die aktuelle Content Section erteilt. +cms.ui.role.edit=Bearbeiten +cms.ui.role.delete=L\u00f6schen +cms.ui.role.members=Mitglieder +cms.ui.role.member.none=Diese Rolle hat keine Mitglieder +cms.ui.role.member.add=Mitglied hinzuf\u00fcgen +cms.ui.attention=Achtung +cms.ui.role.delete_prompt=Sind Sie sicher, dass Sie diese Rolle l\u00f6schen wollen? +cms.ui.delete=L\u00f6schen +cms.ui.cancel=Abbrechen +cms.ui.finish=Beenden +cms.ui.save=Speichern +cms.ui.role.name_not_unique=Eine Rolle mit diesem Namen existiert bereits. +cms.ui.role.add=Rolle hinzuf\u00fcgen diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties index f607d0f1d..dff96587d 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties @@ -93,3 +93,24 @@ cms.ui.folderform.error.child.name_not_unique=The current folder already contain cms.ui.folderform.error.parent.name_not_unique=The parent folder of the selected folder already contains a child with the name {0}. cms.ui.choose_target_folder=Choose target folder cms.ui.folder.copy=Copy {0} items from {1} +cms.ui.role.staff=Roles +cms.ui.role.intro=Select a role or create a new one +cms.ui.role.staff.add=Create new role +cms.ui.role.details=Role details +cms.ui.role.name=Name: +cms.ui.role.description=Description: +cms.ui.role.privileges=Privileges for this content section granted to this role: +cms.ui.role.privilege.none=No privileges granted for this content section to the role +cms.ui.role.edit=Edit +cms.ui.role.delete=Delete +cms.ui.role.members=Members +cms.ui.role.member.none=This role has no members +cms.ui.role.member.add=Add member +cms.ui.attention=Warning +cms.ui.role.delete_prompt=Are you sure to delete this role? +cms.ui.delete=Delete +cms.ui.cancel=Cancel +cms.ui.finish=Finish +cms.ui.save=Save +cms.ui.role.name_not_unique=A role with this name already exists. +cms.ui.role.add=Add role diff --git a/ccm-core/src/main/java/org/libreccm/security/Permission.java b/ccm-core/src/main/java/org/libreccm/security/Permission.java index db6c08835..0d08fb2ea 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Permission.java +++ b/ccm-core/src/main/java/org/libreccm/security/Permission.java @@ -92,6 +92,10 @@ import javax.persistence.OneToOne; @NamedQuery(name = "Permission.findPermissionsForCcmObject", query = "SELECT p FROM Permission p " + "WHERE p.object = :object") + , + @NamedQuery(name = "Permission.findPermissionsForRoleAndObject", + query = "SELECT p FROM Permission p " + + "WHERE p.object = :object and p.grantee = :grantee") }) @XmlRootElement(name = "permission", namespace = CORE_XML_NS) diff --git a/ccm-core/src/main/java/org/libreccm/security/PermissionManager.java b/ccm-core/src/main/java/org/libreccm/security/PermissionManager.java index 2ff21c7d6..a18af9201 100644 --- a/ccm-core/src/main/java/org/libreccm/security/PermissionManager.java +++ b/ccm-core/src/main/java/org/libreccm/security/PermissionManager.java @@ -106,6 +106,18 @@ public class PermissionManager { return query.getResultList(); } + public List findPermissionsForRoleAndObject( + final Role role, final CcmObject object) { + + final TypedQuery query = entityManager.createNamedQuery( + "Permission.findPermissionsForRoleAndObject", Permission.class); + query.setParameter("object", object); + query.setParameter("grantee", role); + + return query.getResultList(); + + } + /** * Grants a privilege on an object to a role. If the privilege was already * granted, the method does nothing. If the object on which the privilege is diff --git a/ccm-core/src/main/java/org/libreccm/security/Role.java b/ccm-core/src/main/java/org/libreccm/security/Role.java index f26fc2c2a..30618a2e1 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Role.java +++ b/ccm-core/src/main/java/org/libreccm/security/Role.java @@ -180,7 +180,7 @@ public class Role implements Serializable, Portable { @OneToMany(mappedBy = "role") @JsonManagedReference(value = "role-taskassignment") - private List assignedTasks; + private List assignedTasks = new ArrayList<>(); /** * An optional description for a role. @@ -194,7 +194,7 @@ public class Role implements Serializable, Portable { @JoinColumn(name = "ROLE_ID") })) @XmlElement(name = "description", namespace = CORE_XML_NS) - private LocalizedString description; + private LocalizedString description = new LocalizedString(); public Role() { super();