diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/UsersGroupsRolesTab.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/UsersGroupsRolesTab.java index 647a7a344..da20a77d7 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/UsersGroupsRolesTab.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/UsersGroupsRolesTab.java @@ -31,6 +31,7 @@ import com.arsdigita.bebop.list.ListModelBuilder; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.toolbox.ui.LayoutPanel; import com.arsdigita.ui.admin.usersgroupsroles.groups.GroupAdmin; +import com.arsdigita.ui.admin.usersgroupsroles.roles.RoleAdmin; import com.arsdigita.util.Assert; import com.arsdigita.util.LockableImpl; @@ -68,8 +69,8 @@ public class UsersGroupsRolesTab extends LayoutPanel { // final BoxPanel groupsPanel = new BoxPanel(); // groupsPanel.add(new Label("Groups Panel")); - final BoxPanel rolesPanel = new BoxPanel(); - rolesPanel.add(new Label("Roles Panel")); +// final BoxPanel rolesPanel = new BoxPanel(); +// rolesPanel.add(new Label("Roles Panel")); final BoxPanel body = new BoxPanel(); addSection( @@ -88,7 +89,7 @@ public class UsersGroupsRolesTab extends LayoutPanel { new Label(new GlobalizedMessage( "ui.admin.users_roles_roles.users.title", ADMIN_BUNDLE)), - rolesPanel, + new RoleAdmin(), body); setLeft(sections); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAddMemberForm.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAddMemberForm.java index 75842b1ee..f00d7324c 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAddMemberForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAddMemberForm.java @@ -22,7 +22,6 @@ import com.arsdigita.bebop.ActionLink; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.ControlLink; import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.ParameterSingleSelectionModel; @@ -70,6 +69,7 @@ public class GroupAddMemberForm extends Form { public GroupAddMemberForm( final GroupAdmin groupAdmin, final ParameterSingleSelectionModel selectedGroupId) { + super("groupAddMemberForm"); final ActionLink backToGroup = new ActionLink(new GlobalizedMessage( @@ -107,10 +107,6 @@ public class GroupAddMemberForm extends Form { "ui.admin.group_details.add_member.search", ADMIN_BUNDLE)); add(submit); -// addProcessListener(e -> { -// final PageState state = e.getPageState(); -// final FormData data = e.getFormData(); -// }); add(new UsersToAddTable(groupAdmin, selectedGroupId)); } @@ -188,8 +184,8 @@ public class GroupAddMemberForm extends Form { final User user = userRepository.findById(Long .parseLong(key)); final Group group = groupRepository.findById( - Long - .parseLong(selectedGroupId.getSelectedKey(state))); + Long.parseLong( + selectedGroupId.getSelectedKey(state))); groupManager.addMemberToGroup(user, group); groupAdmin.hideGroupMemberAddForm(state); break; @@ -229,7 +225,6 @@ public class GroupAddMemberForm extends Form { private int index = -1; public UsersToAddTableModel(final PageState state) { - final String term = (String) memberName.getValue(state); if (term == null || term.isEmpty()) { users = new ArrayList<>(); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java index 67a7357de..242f096d6 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java @@ -30,9 +30,6 @@ import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.globalization.GlobalizedMessage; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import static com.arsdigita.ui.admin.AdminUiConstants.*; /** @@ -51,7 +48,7 @@ public class GroupAdmin extends BoxPanel { private final GroupAddMemberForm groupAddMemberForm; public GroupAdmin() { - super(); + super(BoxPanel.VERTICAL); setBasicProperties(); @@ -69,7 +66,7 @@ public class GroupAdmin extends BoxPanel { "ui.admin.groups.table.filter.term", ADMIN_BUNDLE)); filterForm.add(groupsTableFilter); filterForm.add(new Submit(new GlobalizedMessage( - "ui.admin.groups.filter.submit", ADMIN_BUNDLE))); + "ui.admin.groups.table.filter.submit", ADMIN_BUNDLE))); final ActionLink clearLink = new ActionLink(new GlobalizedMessage( "ui.admin.groups.table.filter.clear", ADMIN_BUNDLE)); clearLink.addActionListener(e -> { @@ -146,8 +143,8 @@ public class GroupAdmin extends BoxPanel { } protected void hideGroupForm(final PageState state) { - //If we want to show the groups table or the group details depends - //if a group is selected or not. + //We want to show the groups table if no group is selected and the + //group details if a group is selected. boolean groupSelected = selectedGroupId.isSelected(state); groupsTablePanel.setVisible(state, !groupSelected); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupDetails.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupDetails.java index 65f927edc..878f7b736 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupDetails.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupDetails.java @@ -41,9 +41,9 @@ public class GroupDetails extends BoxPanel { public GroupDetails( final GroupAdmin groupAdmin, final ParameterSingleSelectionModel selectedGroupId) { + super(BoxPanel.VERTICAL); - final ActionLink backLink = new ActionLink(new GlobalizedMessage( "ui.admin.group_details.back", ADMIN_BUNDLE)); backLink.setClassAttr("back-link"); @@ -63,7 +63,8 @@ public class GroupDetails extends BoxPanel { selectedGroupId.getSelectedKey(state))); target.setLabel(new GlobalizedMessage( "ui.admin.group_details.header", - ADMIN_BUNDLE, new String[]{group.getName()})); + ADMIN_BUNDLE, + new String[]{group.getName()})); }); add(header); @@ -79,7 +80,6 @@ public class GroupDetails extends BoxPanel { groupAdmin.showGroupForm(e.getPageState()); }); links.add(editProperties); - add(links); final GroupMembersTable membersTable = new GroupMembersTable( diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java index c73b8149c..29511be3d 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java @@ -41,8 +41,6 @@ public class GroupForm extends Form { private static final String GROUP_NAME = "groupname"; - private final GroupAdmin groupAdmin; - private final ParameterSingleSelectionModel selectedGroupId; private final TextField groupName; private final SaveCancelSection saveCancelSection; @@ -52,10 +50,7 @@ public class GroupForm extends Form { super("groupform"); - this.groupAdmin = groupAdmin; - this.selectedGroupId = selectedGroupId; - - add(new Label(e -> { + final Label heading = new Label(e -> { final PageState state = e.getPageState(); final Label target = (Label) e.getTarget(); @@ -70,7 +65,9 @@ public class GroupForm extends Form { target.setLabel(new GlobalizedMessage("ui.admin.group.edit", ADMIN_BUNDLE)); } - })); + }); + heading.setClassAttr("heading"); + add(heading); groupName = new TextField(GROUP_NAME); groupName.setLabel(new GlobalizedMessage("ui.admin.group.name", diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupMembersTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupMembersTable.java index c3948f7cd..ab51e1115 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupMembersTable.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupMembersTable.java @@ -133,8 +133,8 @@ public class GroupMembersTable extends Table { final User user = userRepository.findById(Long .parseLong(key)); final Group group = groupRepository.findById( - Long - .parseLong(selectedGroupId.getSelectedKey(state))); + Long.parseLong( + selectedGroupId.getSelectedKey(state))); groupManager.removeMemberFromGroup(user, group); break; default: @@ -153,26 +153,26 @@ public class GroupMembersTable extends Table { setModelBuilder(new GroupMembersTableModelBuilder(selectedGroupId)); } - private class GroupMembersTableModelBuilder extends LockableImpl + private class GroupMembersTableModelBuilder extends LockableImpl implements TableModelBuilder { private final ParameterSingleSelectionModel selectedGroupId; - + public GroupMembersTableModelBuilder( final ParameterSingleSelectionModel selectedGroupId) { - + this.selectedGroupId = selectedGroupId; } - + @Override public TableModel makeModel(final Table table, final PageState state) { table.getRowSelectionModel().clearSelection(state); - + return new GroupMembersTableModel(selectedGroupId, state); } - + } - + private class GroupMembersTableModel implements TableModel { private final List members; @@ -193,7 +193,7 @@ public class GroupMembersTable extends Table { members.add(m.getMember()); }); - members.sort((User m1, User m2) -> { + members.sort((m1, m2) -> { return m1.getName().compareTo(m2.getName()); }); } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupPropertySheetModel.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupPropertySheetModel.java index 98e15a878..0058e6895 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupPropertySheetModel.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupPropertySheetModel.java @@ -22,14 +22,12 @@ import com.arsdigita.bebop.PropertySheetModel; import com.arsdigita.globalization.GlobalizedMessage; import org.libreccm.security.Group; -import org.libreccm.security.Role; import org.libreccm.security.RoleMembership; import java.util.Arrays; import java.util.Iterator; import java.util.Set; import java.util.SortedSet; -import java.util.StringJoiner; import java.util.TreeSet; import static com.arsdigita.ui.admin.AdminUiConstants.*; @@ -81,7 +79,8 @@ class GroupPropertySheetModel implements PropertySheetModel { private GlobalizedMessage generateGlobalizedLabel( final GroupProperty property) { - final String key = String.join("", "ui.admin.group.property_sheet.", + final String key = String.join("", + "ui.admin.group.property_sheet.", property.toString().toLowerCase()); return new GlobalizedMessage(key, ADMIN_BUNDLE); } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAddMemberForm.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAddMemberForm.java new file mode 100644 index 000000000..1762f0f38 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAddMemberForm.java @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.event.TableActionEvent; +import com.arsdigita.bebop.event.TableActionListener; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.table.TableCellRenderer; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.LockableImpl; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Group; +import org.libreccm.security.Party; +import org.libreccm.security.PartyRepository; +import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleRepository; +import org.libreccm.security.User; + +import java.util.ArrayList; +import java.util.List; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RoleAddMemberForm extends Form { + + private static final String MEMBER_NAME = "membername"; + + private static final int COL_MEMBER_NAME = 0; + private static final int COL_MEMBER_TYPE = 1; + private static final int COL_MEMBER_ADD = 2; + + private final TextField memberName; + + public RoleAddMemberForm( + final RoleAdmin roleAdmin, + final ParameterSingleSelectionModel selectedRoleId) { + + super("roleAddMemberForm"); + + final ActionLink backToRole = new ActionLink(new GlobalizedMessage( + "ui.admin.role_members.add.back", ADMIN_BUNDLE)); + backToRole.addActionListener(e -> { + roleAdmin.hideRoleMemberAddForm(e.getPageState()); + }); + add(backToRole); + + final Label heading = new Label(); + heading.setClassAttr("heading"); + heading.addPrintListener(e -> { + final PageState state = e.getPageState(); + final Label target = (Label) e.getTarget(); + + final RoleRepository roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + final Role role = roleRepository.findById(Long.parseLong( + selectedRoleId.getSelectedKey(state))); + + target.setLabel(new GlobalizedMessage( + "ui.admin.role_members.add.heading", + ADMIN_BUNDLE, + new String[]{role.getName()})); + }); + add(heading); + + memberName = new TextField(MEMBER_NAME); + memberName.setLabel(new GlobalizedMessage( + "ui.admin.role_members.add.find", ADMIN_BUNDLE)); + add(memberName); + + final Submit submit = new Submit(new GlobalizedMessage( + "ui.admin.role_members.add.search", ADMIN_BUNDLE)); + add(submit); + + add(new PartiesToAdd(roleAdmin, selectedRoleId)); + } + + private class PartiesToAdd extends Table { + + public PartiesToAdd( + final RoleAdmin roleAdmin, + final ParameterSingleSelectionModel selectedRoleId) { + + super(); + + setEmptyView(new Label(new GlobalizedMessage( + "ui.admin.role_members.add.table.empty", ADMIN_BUNDLE))); + + final TableColumnModel columnModel = getColumnModel(); + columnModel.add(new TableColumn( + COL_MEMBER_NAME, + new Label(new GlobalizedMessage( + "ui.admin.role_members.add.table.name", ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_MEMBER_TYPE, + new Label(new GlobalizedMessage( + "ui.admin.role_members.add.table.type", ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_MEMBER_ADD, + new Label(new GlobalizedMessage( + "ui.admin.role_members.add.table.add", ADMIN_BUNDLE)))); + + columnModel.get(COL_MEMBER_ADD).setCellRenderer( + new TableCellRenderer() { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + final ControlLink link = new ControlLink((Component) value); + return link; + } + + }); + + addTableActionListener(new TableActionListener() { + + @Override + public void cellSelected(final TableActionEvent event) { + final PageState state = event.getPageState(); + final String key = (String) event.getRowKey(); + + switch (event.getColumn()) { + case COL_MEMBER_ADD: + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PartyRepository partyRepository = cdiUtil + .findBean(PartyRepository.class); + final RoleRepository roleRepository = cdiUtil + .findBean(RoleRepository.class); + final RoleManager roleManager = cdiUtil.findBean( + RoleManager.class); + final Party party = partyRepository.findById( + Long.parseLong(key)); + final Role role = roleRepository.findById( + Long.parseLong( + selectedRoleId.getSelectedKey(state))); + roleManager.assignRoleToParty(role, party); + roleAdmin.hideRoleMemberAddForm(state); + break; + default: + throw new IllegalArgumentException( + "Invalid value for column"); + } + } + + @Override + public void headSelected(final TableActionEvent event) { + //Nothing + } + + }); + + setModelBuilder(new PartiesToAddTableModelBuilder()); + } + + } + + private class PartiesToAddTableModelBuilder extends LockableImpl + implements TableModelBuilder { + + @Override + public TableModel makeModel(final Table table, + final PageState state) { + return new PartiesToAddTableModel(state); + } + + } + + private class PartiesToAddTableModel implements TableModel { + + private final List parties; + private int index = -1; + + public PartiesToAddTableModel(final PageState state) { + final String term = (String) memberName.getValue(state); + if (term == null || term.isEmpty()) { + parties = new ArrayList<>(); + } else { + final PartyRepository partyRepository = CdiUtil.createCdiUtil() + .findBean(PartyRepository.class); + parties = partyRepository.searchByName(term); + } + } + + @Override + public int getColumnCount() { + return 3; + } + + @Override + public boolean nextRow() { + index++; + return index < parties.size(); + } + + @Override + public Object getElementAt(final int columnIndex) { + final Party party = parties.get(index); + switch (columnIndex) { + case COL_MEMBER_NAME: + return party.getName(); + case COL_MEMBER_TYPE: + if (party instanceof User) { + return new Label(new GlobalizedMessage( + "ui.admin.role_members.type.user", + ADMIN_BUNDLE)); + } else if (party instanceof Group) { + return new Label(new GlobalizedMessage( + "ui.admin.role_members.type.group", + ADMIN_BUNDLE)); + } else { + return "?"; + } + case COL_MEMBER_ADD: + return new Label(new GlobalizedMessage( + "ui.admin.role_members.table.add")); + default: + throw new IllegalArgumentException( + "Not a valid column index"); + } + } + + @Override + public Object getKeyAt(final int columnIndex) { + return parties.get(index).getPartyId(); + } + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java new file mode 100644 index 000000000..ca4efdff9 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.BoxPanel; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.globalization.GlobalizedMessage; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RoleAdmin extends BoxPanel { + + private final StringParameter roleIdParameter; + private final ParameterSingleSelectionModel selectedRoleId; + private final BoxPanel rolesTablePanel; + private final RoleForm roleForm; + private final RoleDetails roleDetails; + private final BoxPanel roleMembersPanel; + private final RoleAddMemberForm roleAddMemberForm; + private final BoxPanel rolePermissionsPanel; + + public RoleAdmin() { + super(BoxPanel.VERTICAL); + + setIdAttr("roleAdmin"); + + roleIdParameter = new StringParameter("selected_role_id"); + selectedRoleId = new ParameterSingleSelectionModel<>(roleIdParameter); + + rolesTablePanel = new BoxPanel(BoxPanel.VERTICAL); + rolesTablePanel.setIdAttr("rolesTablePanel"); + + final Form filterForm = new Form("rolesTableFilter"); + final TextField rolesTableFilter = new TextField("rolesTableFilter"); + rolesTableFilter.setLabel(new GlobalizedMessage( + "ui.admin.roles.table.filter.term", ADMIN_BUNDLE)); + filterForm.add(rolesTableFilter); + filterForm.add(new Submit(new GlobalizedMessage( + "ui.admin.roles.table.filter.submit", ADMIN_BUNDLE))); + final ActionLink clearLink = new ActionLink(new GlobalizedMessage( + "ui.admin.roles.table.filter.clear", ADMIN_BUNDLE)); + clearLink.addActionListener(e -> { + final PageState state = e.getPageState(); + rolesTableFilter.setValue(state, null); + }); + filterForm.add(clearLink); + rolesTablePanel.add(filterForm); + + final RolesTable rolesTable = new RolesTable(this, + rolesTableFilter, + selectedRoleId); + rolesTablePanel.add(rolesTable); + + final ActionLink addNewRole = new ActionLink(new GlobalizedMessage( + "ui.admin.new_role_link", ADMIN_BUNDLE)); + addNewRole.addActionListener(e -> { + showRoleForm(e.getPageState()); + }); + rolesTablePanel.add(addNewRole); + + add(rolesTablePanel); + + roleForm = new RoleForm(this, selectedRoleId); + add(roleForm); + + roleDetails = new RoleDetails(this, selectedRoleId); + add(roleDetails); + + roleMembersPanel = new BoxPanel(BoxPanel.VERTICAL); + final Label roleMembersHeading = new Label(new GlobalizedMessage( + "ui.admin.role_members.heading", + ADMIN_BUNDLE)); + roleMembersHeading.setClassAttr("heading"); + roleMembersPanel.add(roleMembersHeading); + roleMembersPanel.add(new RoleMembersTable(selectedRoleId)); + final ActionLink addRoleMember = new ActionLink(new GlobalizedMessage( + "ui.admin.role_members.add", ADMIN_BUNDLE)); + addRoleMember.addActionListener(e -> { + showRoleMemberAddForm(e.getPageState()); + }); + roleMembersPanel.add(addRoleMember); + add(roleMembersPanel); + + roleAddMemberForm = new RoleAddMemberForm(this, selectedRoleId); + add(roleAddMemberForm); + + rolePermissionsPanel = new BoxPanel(BoxPanel.VERTICAL); + final Label rolePermissionsHeading = new Label(new GlobalizedMessage( + "ui.admin.role_permissions.heading", + ADMIN_BUNDLE)); + rolePermissionsPanel.add(rolePermissionsHeading); + rolePermissionsPanel.add(new RolePermissionsTable(selectedRoleId)); + final ActionLink addRolePermission = new ActionLink( + new GlobalizedMessage( + "ui.admin.role_permissions.add_permission", ADMIN_BUNDLE)); + addRolePermission.addActionListener(e -> { + showRolePermissionAddForm(e.getPageState()); + }); + rolePermissionsPanel.add(addRolePermission); + add(rolePermissionsPanel); + } + + @Override + public void register(final Page page) { + super.register(page); + + page.addGlobalStateParam(roleIdParameter); + + page.setVisibleDefault(rolesTablePanel, true); + page.setVisibleDefault(roleForm, false); + page.setVisibleDefault(roleDetails, false); + page.setVisibleDefault(roleMembersPanel, false); + page.setVisibleDefault(roleAddMemberForm, false); + page.setVisibleDefault(rolePermissionsPanel, false); + } + + protected void showRoleDetails(final PageState state) { + rolesTablePanel.setVisible(state, false); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, true); + roleMembersPanel.setVisible(state, true); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, false); + } + + protected void hideRoleDetails(final PageState state) { + selectedRoleId.clearSelection(state); + + rolesTablePanel.setVisible(state, true); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, false); + roleMembersPanel.setVisible(state, false); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, false); + } + + protected void showRoleForm(final PageState state) { + rolesTablePanel.setVisible(state, false); + roleForm.setVisible(state, true); + roleDetails.setVisible(state, false); + roleMembersPanel.setVisible(state, false); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, false); + } + + protected void hideRoleForm(final PageState state) { + //We want to show the roles table if no role is selected and the + //role details if a role is selected. + boolean roleSelected = selectedRoleId.isSelected(state); + + rolesTablePanel.setVisible(state, !roleSelected); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, roleSelected); + roleMembersPanel.setVisible(state, roleSelected); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, false); + } + + protected void showRoleMemberAddForm(final PageState state) { + rolesTablePanel.setVisible(state, false); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, false); + roleMembersPanel.setVisible(state, false); + roleAddMemberForm.setVisible(state, true); + rolePermissionsPanel.setVisible(state, false); + } + + protected void showRoleMembersPanel(final PageState state) { + rolesTablePanel.setVisible(state, false); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, true); + roleMembersPanel.setVisible(state, true); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, false); + } + + protected void hideRoleMemberAddForm(final PageState state) { + rolesTablePanel.setVisible(state, false); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, true); + roleMembersPanel.setVisible(state, true); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, false); + } + + protected void showRolePermissionsPanel(final PageState state) { + rolesTablePanel.setVisible(state, false); + roleForm.setVisible(state, false); + roleDetails.setVisible(state, true); + roleMembersPanel.setVisible(state, false); + roleAddMemberForm.setVisible(state, false); + rolePermissionsPanel.setVisible(state, true); + } + +// protected void hideRolePermissionsPanel(final PageState state) { +// rolesTablePanel.setVisible(state, false); +// roleForm.setVisible(state, false); +// roleDetails.setVisible(state, true); +// roleMembersPanel.setVisible(state, true); +// roleAddMemberForm.setVisible(state, false); +// rolePermissionsPanel.setVisible(state, false); +// } + + protected void showRolePermissionAddForm(final PageState state) { + + } + + protected void hideRolePermissionAddForm(final PageState state) { + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleDetails.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleDetails.java new file mode 100644 index 000000000..839e3d261 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleDetails.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.BoxPanel; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.PropertySheet; +import com.arsdigita.globalization.GlobalizedMessage; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RoleDetails extends BoxPanel { + + public RoleDetails( + final RoleAdmin roleAdmin, + final ParameterSingleSelectionModel selectedRoleId) { + + super(BoxPanel.VERTICAL); + + final ActionLink backLink = new ActionLink(new GlobalizedMessage( + "ui.admin.role_details.back", ADMIN_BUNDLE)); + backLink.setClassAttr("back-link"); + backLink.addActionListener(e -> { + roleAdmin.hideRoleDetails(e.getPageState()); + }); + add(backLink); + + final Label heading = new Label(); + heading.setClassAttr("heading"); + heading.addPrintListener(e -> { + final PageState state = e.getPageState(); + final Label target = (Label) e.getTarget(); + final RoleRepository roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + final Role role = roleRepository.findById(Long.parseLong( + selectedRoleId.getSelectedKey(state))); + target.setLabel(new GlobalizedMessage( + "ui.admin.role_details.heading", + ADMIN_BUNDLE, + new String[]{role.getName()})); + }); + add(heading); + + final PropertySheet propertySheet = new PropertySheet( + new RolePropertySheetModelBuilder(selectedRoleId)); + add(propertySheet); + + final BoxPanel links = new BoxPanel(BoxPanel.HORIZONTAL); + + final ActionLink editProperties = new ActionLink(new GlobalizedMessage( + "ui.admin.role_details.edit_properties", ADMIN_BUNDLE)); + editProperties.addActionListener(e -> { + roleAdmin.showRoleForm(e.getPageState()); + }); + links.add(editProperties); + + final ActionLink manageMembers = new ActionLink(new GlobalizedMessage( + "ui.admin.role_details.manage_members", ADMIN_BUNDLE)); + manageMembers.addActionListener(e -> { + roleAdmin.showRoleMembersPanel(e.getPageState()); + }); + links.add(manageMembers); + + + final ActionLink managePermissions = new ActionLink(new GlobalizedMessage( + "ui.admin.role_details.manage_permissions", ADMIN_BUNDLE)); + managePermissions.addActionListener(e -> { + roleAdmin.showRolePermissionsPanel(e.getPageState()); + }); + links.add(managePermissions); + + add(links); + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleForm.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleForm.java new file mode 100644 index 000000000..2d4529667 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleForm.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormData; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.SaveCancelSection; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.globalization.GlobalizedMessage; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RoleForm extends Form { + + private static final String ROLE_NAME = "rolename"; + + private final TextField roleName; + private final SaveCancelSection saveCancelSection; + + public RoleForm( + final RoleAdmin roleAdmin, + final ParameterSingleSelectionModel selectedRoleId) { + + super("roleform"); + + final Label heading = new Label(e -> { + final PageState state = e.getPageState(); + + final Label target = (Label) e.getTarget(); + + final String selectedRoleIdStr = selectedRoleId.getSelectedKey( + state); + if (selectedRoleIdStr == null || selectedRoleIdStr.isEmpty()) { + target.setLabel( + new GlobalizedMessage("ui.admin.role.create_new", + ADMIN_BUNDLE)); + } else { + target.setLabel(new GlobalizedMessage("ui.admin.role.edit", + ADMIN_BUNDLE)); + } + }); + heading.setClassAttr("heading"); + add(heading); + + roleName = new TextField(ROLE_NAME); + roleName.setLabel(new GlobalizedMessage("ui.admin.role_name", + ADMIN_BUNDLE)); + add(roleName); + + saveCancelSection = new SaveCancelSection(); + add(saveCancelSection); + + addValidationListener(e -> { + final PageState state = e.getPageState(); + + if (saveCancelSection.getSaveButton().isSelected(state)) { + final FormData data = e.getFormData(); + + final String roleNameData = data.getString(ROLE_NAME); + + if (roleNameData == null || roleNameData.isEmpty()) { + data.addError(ROLE_NAME, new GlobalizedMessage( + "ui.admin.role.name.error.notempty", + ADMIN_BUNDLE)); + return; + } + + if (roleNameData.length() > 256) { + data.addError(ROLE_NAME, new GlobalizedMessage( + "ui.admin.role.name.error.length", + ADMIN_BUNDLE)); + return; + } + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final RoleRepository roleRepository = cdiUtil.findBean( + RoleRepository.class); + if (roleRepository.findByName(roleNameData) != null) { + data.addError(ROLE_NAME, new GlobalizedMessage( + "ui.admin.role.error.name_already_in_use", + ADMIN_BUNDLE)); + } + } + }); + + addInitListener(e -> { + final PageState state = e.getPageState(); + + final String selectedRoleIdStr = selectedRoleId + .getSelectedKey(state); + + if (selectedRoleIdStr != null && !selectedRoleIdStr.isEmpty()) { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final RoleRepository roleRepository = cdiUtil.findBean( + RoleRepository.class); + + final Role role = roleRepository.findById(Long.parseLong( + selectedRoleIdStr)); + roleName.setValue(state, role.getName()); + } + }); + + addProcessListener(e -> { + final PageState state = e.getPageState(); + + if (saveCancelSection.getSaveButton().isSelected(state)) { + final FormData data = e.getFormData(); + final String roleNameData = data.getString(ROLE_NAME); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final RoleRepository roleRepository = cdiUtil.findBean( + RoleRepository.class); + + final String selectedRoleIdStr = selectedRoleId.getSelectedKey( + state); + if (selectedRoleIdStr == null || selectedRoleIdStr.isEmpty()) { + final Role role = new Role(); + role.setName(roleNameData); + + roleRepository.save(role); + } else { + final Role role = roleRepository.findById(Long.parseLong( + selectedRoleIdStr)); + role.setName(roleNameData); + + roleRepository.save(role); + } + } + + roleAdmin.hideRoleForm(state); + }); + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleMembersTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleMembersTable.java new file mode 100644 index 000000000..68ab04cbd --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleMembersTable.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.event.TableActionEvent; +import com.arsdigita.bebop.event.TableActionListener; +import com.arsdigita.bebop.table.TableCellRenderer; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.LockableImpl; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Group; +import org.libreccm.security.Party; +import org.libreccm.security.PartyRepository; +import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleRepository; +import org.libreccm.security.User; + +import java.util.ArrayList; +import java.util.List; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RoleMembersTable extends Table { + + private static final int COL_MEMBER_NAME = 0; + private static final int COL_MEMBER_TYPE = 1; + private static final int COL_MEMBER_REMOVE = 2; + + public RoleMembersTable( + final ParameterSingleSelectionModel selectedRoleId) { + + super(); + setIdAttr("roleMembersTable"); + + setEmptyView(new Label(new GlobalizedMessage( + "ui.admin.role_members.none", ADMIN_BUNDLE))); + + final TableColumnModel columnModel = getColumnModel(); + columnModel.add(new TableColumn( + COL_MEMBER_NAME, + new Label(new GlobalizedMessage("ui.admin.role_members.name", + ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_MEMBER_TYPE, + new Label(new GlobalizedMessage("ui.admin.role_members.type", + ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_MEMBER_REMOVE, + new Label(new GlobalizedMessage("ui.admin.role_members.remove", + ADMIN_BUNDLE)))); + + columnModel.get(COL_MEMBER_REMOVE).setCellRenderer( + new TableCellRenderer() { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + final ControlLink link = new ControlLink((Component) value); + link.setConfirmation(new GlobalizedMessage( + "ui.admin.role_members.remove_member.confirm", + ADMIN_BUNDLE)); + return link; + } + + }); + + addTableActionListener(new TableActionListener() { + + @Override + public void cellSelected(final TableActionEvent event) { + final PageState state = event.getPageState(); + final String key = (String) event.getRowKey(); + + switch (event.getColumn()) { + case COL_MEMBER_REMOVE: + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PartyRepository partyRepository = cdiUtil + .findBean(PartyRepository.class); + final RoleRepository roleRepository = cdiUtil.findBean( + RoleRepository.class); + final RoleManager roleManager = cdiUtil.findBean( + RoleManager.class); + final Party party = partyRepository.findById(Long + .parseLong(key)); + final Role role = roleRepository.findById( + Long.parseLong(selectedRoleId.getSelectedKey(state))); + roleManager.removeRoleFromParty(role, party); + break; + default: + throw new IllegalArgumentException( + "Invalid value for column"); + } + } + + @Override + public void headSelected(final TableActionEvent event) { + //Nothing + } + + }); + + setModelBuilder(new RoleMembersTableModelBuilder(selectedRoleId)); + } + + private class RoleMembersTableModelBuilder extends LockableImpl + implements TableModelBuilder { + + private final ParameterSingleSelectionModel selectedRoleId; + + public RoleMembersTableModelBuilder( + final ParameterSingleSelectionModel selectedRoleId) { + + this.selectedRoleId = selectedRoleId; + } + + @Override + public TableModel makeModel(final Table table, + final PageState state) { + table.getRowSelectionModel().clearSelection(state); + + return new RoleMembersTableModel(selectedRoleId, state); + } + + } + + private class RoleMembersTableModel implements TableModel { + + private final List members; + private int index = -1; + + public RoleMembersTableModel( + final ParameterSingleSelectionModel selectedRoleId, + final PageState state) { + + final RoleRepository roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + final Role role = roleRepository.findById(Long.parseLong( + selectedRoleId.getSelectedKey(state))); + + members = new ArrayList<>(); + + role.getMemberships().forEach(m -> { + members.add(m.getMember()); + }); + + members.sort((m1, m2) -> { + return m1.getName().compareTo(m2.getName()); + }); + } + + @Override + public int getColumnCount() { + return 3; + } + + @Override + public boolean nextRow() { + index++; + return index < members.size(); + } + + @Override + public Object getElementAt(final int columnIndex) { + final Party member = members.get(index); + switch (columnIndex) { + case COL_MEMBER_NAME: + return member.getName(); + case COL_MEMBER_TYPE: + if (member instanceof User) { + return new Label(new GlobalizedMessage( + "ui.admin.role_members.type.user", + ADMIN_BUNDLE)); + } else if (member instanceof Group) { + return new Label(new GlobalizedMessage( + "ui.admin.role_members.type.group", + ADMIN_BUNDLE)); + } else { + return "?"; + } + case COL_MEMBER_REMOVE: + return new Label(new GlobalizedMessage( + "ui.admin.role_members.remove", ADMIN_BUNDLE)); + default: + throw new IllegalArgumentException( + "Not a valid column index"); + } + + } + + @Override + public Object getKeyAt(final int columnIndex) { + return members.get(index).getPartyId(); + } + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java new file mode 100644 index 000000000..5aabf0dfa --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.event.TableActionEvent; +import com.arsdigita.bebop.event.TableActionListener; +import com.arsdigita.bebop.table.TableCellRenderer; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.LockableImpl; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.CcmObject; +import org.libreccm.security.Permission; +import org.libreccm.security.PermissionManager; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; + +import java.util.ArrayList; +import java.util.List; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RolePermissionsTable extends Table { + + private static final int COL_PRIVILEGE = 0; + private static final int COL_ON_OBJECT = 1; + private static final int COL_REVOKE = 2; + + public RolePermissionsTable( + final ParameterSingleSelectionModel selectedRoleId) { + + super(); + setIdAttr("rolePermissionsTable"); + + setEmptyView(new Label(new GlobalizedMessage( + "ui.admin.role_permissions.none", ADMIN_BUNDLE))); + + final TableColumnModel columnModel = getColumnModel(); + columnModel.add(new TableColumn( + COL_PRIVILEGE, + new Label(new GlobalizedMessage( + "ui.admin.role_permissions.privilege", ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_ON_OBJECT, + new Label(new GlobalizedMessage( + "ui.admin.role_permissions.on_object", ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_REVOKE, + new Label(new GlobalizedMessage( + "ui.admin.role_permissions.revoke", ADMIN_BUNDLE)))); + + columnModel.get(COL_REVOKE).setCellRenderer(new TableCellRenderer() { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + final ControlLink link = new ControlLink((Component) value); + link.setConfirmation(new GlobalizedMessage( + "ui.admin.role_permissions.revoke.confirm", ADMIN_BUNDLE)); + return link; + } + + }); + + addTableActionListener(new TableActionListener() { + + @Override + public void cellSelected(final TableActionEvent event) { + final PageState state = event.getPageState(); + final String key = (String) event.getRowKey(); + + switch (event.getColumn()) { + case COL_REVOKE: + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final RoleRepository roleRepository = cdiUtil.findBean( + RoleRepository.class); + final PermissionManager permissionManager = cdiUtil + .findBean(PermissionManager.class); + final Role role = roleRepository.findById( + Long.parseLong(selectedRoleId.getSelectedKey(state))); + final Permission permission = permissionManager + .findById(Long.parseLong(key)); + if (permission.getObject() == null) { + permissionManager.revokePrivilege( + permission.getGrantedPrivilege(), role); + } else { + permissionManager.revokePrivilege( + permission.getGrantedPrivilege(), + role, + permission.getObject()); + } + break; + default: + throw new IllegalArgumentException( + "Invalid value for column"); + } + } + + @Override + public void headSelected(final TableActionEvent event) { + //Nothing + } + + }); + + setModelBuilder(new RolePermissionsTableModelBuilder(selectedRoleId)); + } + + private class RolePermissionsTableModelBuilder extends LockableImpl + implements TableModelBuilder { + + private final ParameterSingleSelectionModel selectedRoleId; + + public RolePermissionsTableModelBuilder( + final ParameterSingleSelectionModel selectedRoleId) { + + this.selectedRoleId = selectedRoleId; + } + + @Override + public TableModel makeModel(final Table table, + final PageState state) { + table.getRowSelectionModel().clearSelection(state); + + return new RolePermissionsTableModel(selectedRoleId, state); + } + + } + + private class RolePermissionsTableModel implements TableModel { + + private final List permissions; + private int index = -1; + + public RolePermissionsTableModel( + final ParameterSingleSelectionModel selectedRoleId, + final PageState state) { + + final RoleRepository roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + final Role role = roleRepository.findById(Long.parseLong( + selectedRoleId.getSelectedKey(state))); + + permissions = new ArrayList<>(role.getPermissions()); + + permissions.sort((p1, p2) -> { + final int result = p1.getGrantedPrivilege() + .compareTo(p2.getGrantedPrivilege()); + if (result != 0) { + return result; + } else if (p1.getObject() != null + && p1.getObject().getDisplayName() != null + && p2.getObject() != null) { + return p1.getObject().getDisplayName() + .compareTo(p2.getObject().getDisplayName()); + } else { + return result; + } + }); + } + + @Override + public int getColumnCount() { + return 3; + } + + @Override + public boolean nextRow() { + index++; + return index < permissions.size(); + } + + @Override + public Object getElementAt(final int columnIndex) { + final Permission permission = permissions.get(index); + switch (columnIndex) { + case COL_PRIVILEGE: + return permission.getGrantedPrivilege(); + case COL_ON_OBJECT: + if (permission.getObject() == null) { + return ""; + } else { + final CcmObject object = permission.getObject(); + return String.join(" ", + Long.toString(object.getObjectId()), + object.getDisplayName()); + } + case COL_REVOKE: + return new Label(new GlobalizedMessage( + "ui.admin.role_permissions.revoke", ADMIN_BUNDLE)); + default: + throw new IllegalArgumentException( + "Not a valid column index"); + } + } + + @Override + public Object getKeyAt(final int columnIndex) { + return permissions.get(index).getPermissionId(); + } + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePropertySheetModel.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePropertySheetModel.java new file mode 100644 index 000000000..4ae215598 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePropertySheetModel.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.PropertySheetModel; +import com.arsdigita.globalization.GlobalizedMessage; + +import org.libreccm.security.Role; + +import java.util.Arrays; +import java.util.Iterator; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RolePropertySheetModel implements PropertySheetModel { + + private static enum RoleProperty { + ROLE_NAME + } + + private final Role selectedRole; + private final Iterator propertyIterator; + private RoleProperty currentProperty; + + public RolePropertySheetModel(final Role selectedRole) { + this.selectedRole = selectedRole; + propertyIterator = Arrays.asList(RoleProperty.values()).iterator(); + } + + @Override + public boolean nextRow() { + if (selectedRole == null) { + return false; + } + + if (propertyIterator.hasNext()) { + currentProperty = propertyIterator.next(); + return true; + } else { + return false; + } + } + + @Override + public String getLabel() { + return currentProperty.toString(); + } + + @Override + public GlobalizedMessage getGlobalizedLabel() { + return generateGlobalizedLabel(currentProperty); + } + + private GlobalizedMessage generateGlobalizedLabel( + final RoleProperty roleProperty) { + + final String key = String.join("", + "ui.admin.role.property_sheet.", + roleProperty.toString().toLowerCase()); + return new GlobalizedMessage(key, ADMIN_BUNDLE); + } + + @Override + public String getValue() { + switch(currentProperty) { + case ROLE_NAME: + return selectedRole.getName(); + default: + return ""; + } + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePropertySheetModelBuilder.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePropertySheetModelBuilder.java new file mode 100644 index 000000000..494ef45fb --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePropertySheetModelBuilder.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.PropertySheet; +import com.arsdigita.bebop.PropertySheetModel; +import com.arsdigita.bebop.PropertySheetModelBuilder; +import com.arsdigita.util.LockableImpl; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; + +/** + * + * @author Jens Pelzetter + */ +public class RolePropertySheetModelBuilder extends LockableImpl + implements PropertySheetModelBuilder { + + private final ParameterSingleSelectionModel selectedRoleId; + + public RolePropertySheetModelBuilder( + final ParameterSingleSelectionModel selectedRoleId) { + this.selectedRoleId = selectedRoleId; + } + + @Override + public PropertySheetModel makeModel(final PropertySheet sheet, + final PageState state) { + final String roleIdStr = selectedRoleId.getSelectedKey(state); + final Role selectedRole; + if (roleIdStr == null || roleIdStr.isEmpty()) { + selectedRole = null; + } else { + final RoleRepository roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + selectedRole = roleRepository.findById(Long.parseLong(roleIdStr)); + } + + return new RolePropertySheetModel(selectedRole); + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolesTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolesTable.java new file mode 100644 index 000000000..74694c151 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolesTable.java @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin.usersgroupsroles.roles; + +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.event.TableActionEvent; +import com.arsdigita.bebop.event.TableActionListener; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.table.TableCellRenderer; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.LockableImpl; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; + +import java.util.List; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class RolesTable extends Table { + + private static final int COL_ROLE_NAME = 0; + private static final int COL_DELETE = 1; + + private final TextField rolesTableFilter; + private final ParameterSingleSelectionModel selectedRoleId; + + public RolesTable( + final RoleAdmin parent, + final TextField rolesTableFilter, + final ParameterSingleSelectionModel selectedRoleId) { + + super(); + + setIdAttr("rolesTable"); + setStyleAttr("width: 30em"); + + this.rolesTableFilter = rolesTableFilter; + this.selectedRoleId = selectedRoleId; + + setEmptyView(new Label(new GlobalizedMessage( + "ui.admin.roles.table.empty", ADMIN_BUNDLE))); + + final TableColumnModel columnModel = getColumnModel(); + columnModel.add(new TableColumn( + COL_ROLE_NAME, + new Label(new GlobalizedMessage("ui.admin.roles.table.name", + ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_DELETE, + new Label(new GlobalizedMessage("ui.admin.roles.table.delete", + ADMIN_BUNDLE)))); + + columnModel.get(COL_ROLE_NAME).setCellRenderer(new TableCellRenderer() { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + return new ControlLink((String) value); + } + + }); + + columnModel.get(COL_DELETE).setCellRenderer(new TableCellRenderer() { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + final ControlLink link = new ControlLink((Component) value); + link.setConfirmation(new GlobalizedMessage( + "ui.admin.roles.delete.confirm", ADMIN_BUNDLE)); + return link; + } + + }); + + addTableActionListener(new TableActionListener() { + + @Override + public void cellSelected(final TableActionEvent event) { + final PageState state = event.getPageState(); + final String key = (String) event.getRowKey(); + + switch (event.getColumn()) { + case COL_ROLE_NAME: + selectedRoleId.setSelectedKey(state, key); + parent.showRoleDetails(state); + break; + case COL_DELETE: + final RoleRepository roleRepository = CdiUtil + .createCdiUtil().findBean(RoleRepository.class); + final Role role = roleRepository.findById(Long + .parseLong(key)); + roleRepository.delete(role); + break; + default: + throw new IllegalArgumentException( + "Invalid value for column."); + } + } + + @Override + public void headSelected(final TableActionEvent event) { + //Nothing + } + + }); + + setModelBuilder(new RolesTableModelBuilder()); + } + + private class RolesTableModelBuilder extends LockableImpl + implements TableModelBuilder { + + @Override + public TableModel makeModel(final Table table, + final PageState state) { + table.getRowSelectionModel().clearSelection(state); + + return new RolesTableModel(state); + } + + } + + private class RolesTableModel implements TableModel { + + private final List roles; + private int index = -1; + + public RolesTableModel(final PageState state) { + final String filterTerm = (String) rolesTableFilter.getValue(state); + final RoleRepository roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + if (filterTerm == null || filterTerm.isEmpty()) { + roles = roleRepository.findAllOrderedByRoleName(); + } else { + roles = roleRepository.searchByName(filterTerm); + } + } + + @Override + public int getColumnCount() { + return 2; + } + + @Override + public boolean nextRow() { + index++; + return index < roles.size(); + } + + @Override + public Object getElementAt(final int columnIndex) { + final Role role = roles.get(index); + switch (columnIndex) { + case COL_ROLE_NAME: + return role.getName(); + case COL_DELETE: + return new Label(new GlobalizedMessage( + "ui.admin.roles.table.delete", ADMIN_BUNDLE)); + default: + throw new IllegalArgumentException( + "Not a valid column index"); + } + } + + @Override + public Object getKeyAt(final int columnIndex) { + return roles.get(index).getRoleId(); + } + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/users/UserAdmin.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/users/UserAdmin.java index fc8585a0c..63fcc3ddc 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/users/UserAdmin.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/users/UserAdmin.java @@ -105,7 +105,7 @@ public class UserAdmin extends BoxPanel { private final Form newUserForm; public UserAdmin() { - super(); + super(BoxPanel.VERTICAL); setBasicProperties(); diff --git a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java index 748e9f103..2a37a7a86 100644 --- a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java +++ b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java @@ -32,7 +32,6 @@ import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Order; import javax.persistence.criteria.Root; import javax.transaction.Transactional; diff --git a/ccm-core/src/main/java/org/libreccm/security/Group.java b/ccm-core/src/main/java/org/libreccm/security/Group.java index 54e391344..94f74a4e2 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Group.java +++ b/ccm-core/src/main/java/org/libreccm/security/Group.java @@ -53,35 +53,38 @@ import javax.xml.bind.annotation.XmlRootElement; @Entity @Table(name = "GROUPS", schema = DB_SCHEMA) @NamedQueries({ - @NamedQuery(name = "Group.findByName", - query = "SELECT g FROM Group g WHERE g.name = :name " - + "ORDER BY g.name"), - @NamedQuery(name = "Group.searchByName", - query = "SELECT g FROM Group g " - + "WHERE LOWER(g.name) LIKE '%:name%' " - + "ORDER BY g.name"), - @NamedQuery(name = "Group.findAllOrderedByGroupName", - query = "SELECT g FROM Group g ORDER BY g.name") + @NamedQuery( + name = "Group.findByName", + query = "SELECT g FROM Group g WHERE g.name = :name " + + "ORDER BY g.name"), + @NamedQuery( + name = "Group.searchByName", + query = "SELECT g FROM Group g " + + "WHERE LOWER(g.name) LIKE CONCAT(LOWER(:name), '%') " + + "ORDER BY g.name"), + @NamedQuery( + name = "Group.findAllOrderedByGroupName", + query = "SELECT g FROM Group g ORDER BY g.name") }) @NamedEntityGraphs({ @NamedEntityGraph( - name = "Group.withMembersAndRoleMemberships", - attributeNodes = { - @NamedAttributeNode(value = "memberships"), - @NamedAttributeNode(value = "roleMemberships", - subgraph = "role")}, - subgraphs = { - @NamedSubgraph( - name = "role", - attributeNodes = { - @NamedAttributeNode(value = "role", - subgraph = "permissions") - }), - @NamedSubgraph( - name = "permissions", - attributeNodes = { - @NamedAttributeNode(value = "permissions")}) - }) + name = "Group.withMembersAndRoleMemberships", + attributeNodes = { + @NamedAttributeNode(value = "memberships"), + @NamedAttributeNode(value = "roleMemberships", + subgraph = "role")}, + subgraphs = { + @NamedSubgraph( + name = "role", + attributeNodes = { + @NamedAttributeNode(value = "role", + subgraph = "permissions") + }), + @NamedSubgraph( + name = "permissions", + attributeNodes = { + @NamedAttributeNode(value = "permissions")}) + }) }) @DefaultEntityGraph("Group.withMembersAndRoleMemberships") @XmlRootElement(name = "user-group", namespace = CORE_XML_NS) diff --git a/ccm-core/src/main/java/org/libreccm/security/GroupRepository.java b/ccm-core/src/main/java/org/libreccm/security/GroupRepository.java index 2bcabd658..4d3d720ac 100644 --- a/ccm-core/src/main/java/org/libreccm/security/GroupRepository.java +++ b/ccm-core/src/main/java/org/libreccm/security/GroupRepository.java @@ -103,6 +103,6 @@ public class GroupRepository extends AbstractEntityRepository { getEntityManager().remove(m); }); - getEntityManager().remove(getEntityManager().merge(entity)); + getEntityManager().remove(delete); } } diff --git a/ccm-core/src/main/java/org/libreccm/security/Party.java b/ccm-core/src/main/java/org/libreccm/security/Party.java index 2e6b681d0..7f17420e2 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Party.java +++ b/ccm-core/src/main/java/org/libreccm/security/Party.java @@ -58,8 +58,14 @@ import javax.xml.bind.annotation.XmlElementWrapper; @Table(name = "PARTIES", schema = DB_SCHEMA) @Inheritance(strategy = InheritanceType.JOINED) @NamedQueries({ - @NamedQuery(name = "Party.findByName", - query = "SELECT p FROM Party p WHERE p.name = :name") + @NamedQuery( + name = "Party.findByName", + query = "SELECT p FROM Party p WHERE p.name = :name"), + @NamedQuery( + name = "Party.searchByName", + query = "SELECT p FROM Party p " + + "WHERE LOWER(p.name) LIKE CONCAT(LOWER(:term), '%') " + + "ORDER BY p.name") }) @NamedEntityGraphs({ @NamedEntityGraph(name = "Party.withRoleMemberships", @@ -77,7 +83,7 @@ public class Party implements Serializable { private long partyId; /** - * The name of the party. Must only contain the letters a to z and A to Z, + * The name of the party. Must only contain the letters a to z and A to Z, * the numbers 0 to 9 the {@code -} (dash) and the {@code _} (underscore). */ @Column(name = "NAME", length = 256, nullable = false) diff --git a/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java b/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java index e94961561..5bce02879 100644 --- a/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java +++ b/ccm-core/src/main/java/org/libreccm/security/PartyRepository.java @@ -28,7 +28,7 @@ import javax.persistence.TypedQuery; /** * Repository class for parties. - * + * * @author Jens Pelzetter */ @RequestScoped @@ -49,15 +49,16 @@ public class PartyRepository extends AbstractEntityRepository { /** * Finds a party (which can be a user or group) by its name. - * + * * @param name - * @return + * + * @return */ public Party findByName(final String name) { final TypedQuery query = getEntityManager().createNamedQuery( "Party.findByName", Party.class); query.setParameter("name", name); - + final List result = query.getResultList(); if (result.isEmpty()) { return null; @@ -66,4 +67,11 @@ public class PartyRepository extends AbstractEntityRepository { } } + public List searchByName(final String term) { + final TypedQuery query = getEntityManager().createNamedQuery( + "Party.searchByName", Party.class); + query.setParameter("term", term); + return query.getResultList(); + } + } 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 809e733de..7afd92f29 100644 --- a/ccm-core/src/main/java/org/libreccm/security/PermissionManager.java +++ b/ccm-core/src/main/java/org/libreccm/security/PermissionManager.java @@ -49,6 +49,16 @@ public class PermissionManager { @Inject private EntityManager entityManager; + /** + * Retrieves a permission by its ID. Useful for UI classes. + * + * @param permissionId The id of the permission to retrieve. + * @return The permission identified by the provided {@code permissionId). + */ + public Permission findById(final long permissionId) { + return entityManager.find(Permission.class, permissionId); + } + /** * Grants a privilege on an object to a role. If the privilege was already * granted, the method does nothing. 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 29fc17e0e..994e093c5 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Role.java +++ b/ccm-core/src/main/java/org/libreccm/security/Role.java @@ -59,7 +59,14 @@ import javax.xml.bind.annotation.XmlRootElement; @NamedQueries({ @NamedQuery(name = "Role.findByName", query = "SELECT r FROM Role r " - + "WHERE r.name = :name") + + "WHERE r.name = :name"), + @NamedQuery( + name = "Role.findAllOrderedByRoleName", + query = "SELECT r FROM Role r ORDER BY r.name"), + @NamedQuery( + name = "Role.searchByName", + query = "SELECT r FROM Role r WHERE LOWER(r.name) LIKE CONCAT(LOWER(:name), '%') " + + "ORDER BY r.name ") }) @NamedEntityGraphs({ @NamedEntityGraph( @@ -110,7 +117,7 @@ public class Role implements Serializable { @OneToMany(mappedBy = "role") private List assignedTasks; - protected Role() { + public Role() { super(); } diff --git a/ccm-core/src/main/java/org/libreccm/security/RoleRepository.java b/ccm-core/src/main/java/org/libreccm/security/RoleRepository.java index 4225c1522..d1100decf 100644 --- a/ccm-core/src/main/java/org/libreccm/security/RoleRepository.java +++ b/ccm-core/src/main/java/org/libreccm/security/RoleRepository.java @@ -19,13 +19,17 @@ package org.libreccm.security; import java.util.List; + import javax.enterprise.context.RequestScoped; import javax.persistence.TypedQuery; + import org.libreccm.core.AbstractEntityRepository; +import javax.transaction.Transactional; + /** * Repository class for {@link Role} entities. - * + * * @author Jens Pelzetter */ @RequestScoped @@ -46,14 +50,15 @@ public class RoleRepository extends AbstractEntityRepository { /** * Finds a role a its name. - * + * * @param name The name of the role to retrieve. + * * @return The role identified by the provided {@code name} or {@code null} - * if there is no matching role. + * if there is no matching role. */ public Role findByName(final String name) { final TypedQuery query = getEntityManager().createNamedQuery( - "Role.findByName", Role.class); + "Role.findByName", Role.class); query.setParameter("name", name); final List result = query.getResultList(); if (result.isEmpty()) { @@ -63,4 +68,30 @@ public class RoleRepository extends AbstractEntityRepository { } } + public List findAllOrderedByRoleName() { + final TypedQuery query = getEntityManager().createNamedQuery( + "Role.findAllOrderedByRoleName", Role.class); + return query.getResultList(); + } + + public List searchByName(final String name) { + final TypedQuery query = getEntityManager().createNamedQuery( + "Role.searchByName", Role.class); + query.setParameter("name", name); + return query.getResultList(); + } + + @Override + @Transactional(Transactional.TxType.REQUIRED) + public void delete(final Role role) { + final Role delete = getEntityManager().find(Role.class, + role.getRoleId()); + + delete.getMemberships().forEach(m -> { + getEntityManager().remove(m); + }); + + getEntityManager().remove(delete); + } + } diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties index 06c70ffc9..9d1b7e5b7 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties @@ -240,7 +240,7 @@ ui.admin.user.edit_group_memberships.back_to_user_details=Back to user details ui.admin.user_edit_role_memberships=Edit role memberships for user {0} ui.admin.user.edit_role_memberships.back_to_user_details=Back to user details ui.admin.groups.table.filter.term=Filter groups -ui.admin.groups.filter.submit=Apply +ui.admin.groups.table.filter.submit=Apply ui.admin.groups.table.filter.clear=Clear filter ui.admin.groups.table.no_groups=No groups available ui.admin.groups.table.name=Name @@ -278,3 +278,46 @@ ui.admin.group_details.add_member.back=Back to group details ui.admin.group_details.add_member.header=Add member to group {0} ui.admin.group_details.header=Details for group {0} ui.admin.groups.heading=Groups +ui.admin.roles.table.filter.term=Filter roles +ui.admin.roles.table.filter.submit=Apply +ui.admin.roles.table.filter.clear=Clear filter +ui.admin.roles.table.empty=No roles available +ui.admin.roles.table.name=Name +ui.admin.roles.table.delete=Delete +ui.admin.roles.delete.confirm=Are you sure to delete this role? +ui.admin.new_role_link=Create new role +ui.admin.role.create_new=Create new role +ui.admin.role.edit=Edit role +ui.admin.role_name=Name +ui.admin.role.name.error.notempty=The name of a role can't be empty. +ui.admin.role.name.error.length=The name of role can't be longer then 256 characters. +ui.admin.role.error.name_already_in_use=An role with this name already exists. +ui.admin.role_details.back=Back to roles table +ui.admin.role_details.heading=Properties of role {0} +ui.admin.role.property_sheet.role_name=Name +ui.admin.role_details.edit_properties=Rename role +ui.admin.role_details.manage_members=Manage members +ui.admin.role_details.manage_permissions=Manage permissions +ui.admin.role_members.none=There are no members assigned to this role. +ui.admin.role_members.remove_member.confirm=Are you sure to remove this member from this role? +ui.admin.role_members.type.user=User +ui.admin.role_members.type.group=Group +ui.admin.role_members.remove=Remove +ui.admin.role_members.heading=Members +ui.admin.role_members.name=Name +ui.admin.role_members.type=Type +ui.admin.role_members.add.heading=Add member to role {} +ui.admin.role_members.add.find=Find users/groups +ui.admin.role_members.add.search=Search +ui.admin.role_members.add.table.empty=No matching users/groups +ui.admin.role_members.add.table.name=Name +ui.admin.role_members.add.table.type=Type +ui.admin.role_members.table.add=Add +ui.admin.role_members.add=Add member +ui.admin.role_members.add.back=Back to role properties +ui.admin.role_permissions.none=No permissions granted to this role +ui.admin.role_permissions.privilege=Privilege +ui.admin.role_permissions.on_object=On object +ui.admin.role_permissions.revoke=Revoke +ui.admin.role_permissions.revoke.confirm=Are you sure to revoke this permission? +ui.admin.role_permissions.heading=Permissions diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties index 6fcc76f91..bf0828fd4 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties @@ -240,7 +240,7 @@ ui.admin.user.edit_group_memberships.back_to_user_details=Zur\u00fcck zu den Eig ui.admin.user_edit_role_memberships=Rollen f\u00fcr Benutzer {0} bearbeiten ui.admin.user.edit_role_memberships.back_to_user_details=Zur\u00fcck zu den Eigenschaften des Benutzers ui.admin.groups.table.filter.term=Gruppen filtern -ui.admin.groups.filter.submit=Anwenden +ui.admin.groups.table.filter.submit=Anwenden ui.admin.groups.table.filter.clear=Filter zur\u00fccksetzen ui.admin.groups.table.no_groups=Keine Gruppen gefunden ui.admin.groups.table.name=Name @@ -279,3 +279,48 @@ ui.admin.group_details.add_member.back=Zur\u00fcck zur Detailansicht der Gruppe ui.admin.group_details.add_member.header=Mitglieder zur Gruppe {0} hinzuf\u00fcgen ui.admin.group_details.header=Details Gruppe {0} ui.admin.groups.heading=Gruppen +ui.admin.roles.table.filter.term=Rollen filtern +ui.admin.roles.table.filter.submit=Anwenden +#Clear filter +ui.admin.roles.table.filter.clear=Filter zur\u00fccksetzen +ui.admin.roles.table.empty=Keine Rollen gefunden +ui.admin.roles.table.name=Name +ui.admin.roles.table.delete=L\u00f6schen +#Are you sure to delete this role? +ui.admin.roles.delete.confirm=Sind sie sicher, dass Sie diese Rolle l\u00f6schen wollen? +ui.admin.new_role_link=Neue Rolle erstellen +ui.admin.role.create_new=Neue Rolle erstellen +ui.admin.role.edit=Rolle bearbeiten +ui.admin.role_name=Name +ui.admin.role.name.error.notempty=Der Name einer Rolle kann nicht leer sein. +ui.admin.role.name.error.length=Der Name einer Rolle kann maximal 256 Zeichen lang sein. +ui.admin.role.error.name_already_in_use=Eine Rolle mit diesem Name existert bereits. +ui.admin.role_details.back=Zur\u00fcck zur Liste der Rollen +ui.admin.role_details.heading=Eigenschaften der Rolle {0} +ui.admin.role.property_sheet.role_name=Name +ui.admin.role_details.edit_properties=Rolle umbenennen +ui.admin.role_details.manage_members=Mitglieder verwalten +ui.admin.role_details.manage_permissions=Berechtigungen verwalten +ui.admin.role_members.none=Dieser Rolle sind keine Mitglieder zugewiesen. +ui.admin.role_members.remove_member.confirm=Sine Sie sicher, dass Sie dieses Mitglied aus dieser Rolle entfernen wollen? +ui.admin.role_members.type.user=Benutzer +ui.admin.role_members.type.group=Gruppe +ui.admin.role_members.remove=Entfernen +ui.admin.role_members.heading=Mitglieder +ui.admin.role_members.name=Name +ui.admin.role_members.type=Typ +ui.admin.role_members.add.heading=Mitglied zur Rolle {0} hinzuf\u00fcgen +ui.admin.role_members.add.find=Benutzer/Gruppen finden +ui.admin.role_members.add.search=Suchen +ui.admin.role_members.add.table.empty=Keine passenden Benutzer/Gruppen +ui.admin.role_members.add.table.name=Name +ui.admin.role_members.add.table.type=Typ +ui.admin.role_members.table.add=Hinzuf\u00fcgen +ui.admin.role_members.add=Mitglied hinzuf\u00fcgen +ui.admin.role_members.add.back=Zur\u00fcck zu den Eigenschaften der Rolle +ui.admin.role_permissions.none=Dieser Rolle wurde keine Berechtigungen gew\u00e4hrt +ui.admin.role_permissions.privilege=Privileg +ui.admin.role_permissions.on_object=Auf Objekt +ui.admin.role_permissions.revoke=L\u00f6schen +ui.admin.role_permissions.revoke.confirm=Sind Sie sicher, dass Sie diese Berechtigung l\u00f6schen wollen? +ui.admin.role_permissions.heading=Berechtigungen diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties index afa5273a7..f1b6db68f 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties @@ -213,7 +213,7 @@ ui.admin.user.edit_group_memberships.back_to_user_details=Back to user details ui.admin.user_edit_role_memberships=Edit role memberships for user {0} ui.admin.user.edit_role_memberships.back_to_user_details=Back to user details ui.admin.groups.table.filter.term=Filter groups -ui.admin.groups.filter.submit=Apply +ui.admin.groups.table.filter.submit=Apply ui.admin.groups.table.filter.clear=Clear filter ui.admin.groups.table.no_groups=No groups available ui.admin.groups.table.name=Name @@ -252,3 +252,48 @@ ui.admin.group_details.add_member.back=Back to group details ui.admin.group_details.add_member.header=Add member to group {0} ui.admin.group_details.header=Details for group {0} ui.admin.groups.heading=Groups +ui.admin.roles.table.filter.term=Filter roles +ui.admin.roles.table.filter.submit=Apply +#Clear filter +ui.admin.roles.table.filter.clear=Clear filter +ui.admin.roles.table.empty=No roles available +ui.admin.roles.table.name=Name +ui.admin.roles.table.delete=Delete +#Are you sure to delete this role? +ui.admin.roles.delete.confirm=Are you sure to delete this role? +ui.admin.new_role_link=Create new role +ui.admin.role.create_new=Create new role +ui.admin.role.edit=Edit role +ui.admin.role_name=Name +ui.admin.role.name.error.notempty=The name of a role can't be empty. +ui.admin.role.name.error.length=The name of role can't be longer then 256 characters. +ui.admin.role.error.name_already_in_use=An role with this name already exists. +ui.admin.role_details.back=Back to roles table +ui.admin.role_details.heading=Properties of role {0} +ui.admin.role.property_sheet.role_name=Name +ui.admin.role_details.edit_properties=Rename role +ui.admin.role_details.manage_members=Manage members +ui.admin.role_details.manage_permissions=Manage permissions +ui.admin.role_members.none=There are no members assigned to this role. +ui.admin.role_members.remove_member.confirm=Are you sure to remove this member from this role? +ui.admin.role_members.type.user=User +ui.admin.role_members.type.group=Group +ui.admin.role_members.remove=Remove +ui.admin.role_members.heading=Members +ui.admin.role_members.name=Name +ui.admin.role_members.type=Type +ui.admin.role_members.add.heading=Add member to role {} +ui.admin.role_members.add.find=Find users/groups +ui.admin.role_members.add.search=Search +ui.admin.role_members.add.table.empty=No matching users/groups +ui.admin.role_members.add.table.name=Name +ui.admin.role_members.add.table.type=Type +ui.admin.role_members.table.add=Add +ui.admin.role_members.add=Add member +ui.admin.role_members.add.back=Back to role properties +ui.admin.role_permissions.none=No permissions granted to this role +ui.admin.role_permissions.privilege=Privilege +ui.admin.role_permissions.on_object=On object +ui.admin.role_permissions.revoke=Revoke +ui.admin.role_permissions.revoke.confirm=Are you sure to revoke this permission? +ui.admin.role_permissions.heading=Permissions diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties index 5208152c6..751e0384a 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -204,7 +204,7 @@ ui.admin.user.edit_group_memberships.back_to_user_details=Back to user details ui.admin.user_edit_role_memberships=Edit role memberships for user {0} ui.admin.user.edit_role_memberships.back_to_user_details=Back to user details ui.admin.groups.table.filter.term=Filter groups -ui.admin.groups.filter.submit=Apply +ui.admin.groups.table.filter.submit=Apply ui.admin.groups.table.filter.clear=Clear filter ui.admin.groups.table.no_groups=No groups available ui.admin.groups.table.name=Name @@ -243,3 +243,48 @@ ui.admin.group_details.add_member.back=Back to group details ui.admin.group_details.add_member.header=Add member to group {0} ui.admin.group_details.header=Details for group {0} ui.admin.groups.heading=Groups +ui.admin.roles.table.filter.term=Filter roles +ui.admin.roles.table.filter.submit=Apply +#Clear filter +ui.admin.roles.table.filter.clear=Clear filter +ui.admin.roles.table.empty=No roles available +ui.admin.roles.table.name=Name +ui.admin.roles.table.delete=Delete +#Are you sure to delete this role? +ui.admin.roles.delete.confirm=Are you sure to delete this role? +ui.admin.new_role_link=Create new role +ui.admin.role.create_new=Create new role +ui.admin.role.edit=Edit role +ui.admin.role_name=Name +ui.admin.role.name.error.notempty=The name of a role can't be empty. +ui.admin.role.name.error.length=The name of role can't be longer then 256 characters. +ui.admin.role.error.name_already_in_use=An role with this name already exists. +ui.admin.role_details.back=Back to roles table +ui.admin.role_details.heading=Properties of role {0} +ui.admin.role.property_sheet.role_name=Name +ui.admin.role_details.edit_properties=Rename role +ui.admin.role_details.manage_members=Manage members +ui.admin.role_details.manage_permissions=Manage permissions +ui.admin.role_members.none=There are no members assigned to this role. +ui.admin.role_members.remove_member.confirm=Are you sure to remove this member from this role? +ui.admin.role_members.type.user=User +ui.admin.role_members.type.group=Group +ui.admin.role_members.remove=Remove +ui.admin.role_members.heading=Members +ui.admin.role_members.name=Name +ui.admin.role_members.type=Type +ui.admin.role_members.add.heading=Add member to role {} +ui.admin.role_members.add.find=Find users/groups +ui.admin.role_members.add.search=Search +ui.admin.role_members.add.table.empty=No matching users/groups +ui.admin.role_members.add.table.name=Name +ui.admin.role_members.add.table.type=Type +ui.admin.role_members.table.add=Add +ui.admin.role_members.add=Add member +ui.admin.role_members.add.back=Back to role properties +ui.admin.role_permissions.none=No permissions granted to this role +ui.admin.role_permissions.privilege=Privilege +ui.admin.role_permissions.on_object=On object +ui.admin.role_permissions.revoke=Revoke +ui.admin.role_permissions.revoke.confirm=Are you sure to revoke this permission? +ui.admin.role_permissions.heading=Permissions diff --git a/ccm-theme-foundry/src/main/resources/themes/foundry/foundry/lib/bebop/label.xsl b/ccm-theme-foundry/src/main/resources/themes/foundry/foundry/lib/bebop/label.xsl index 711246bba..70b0aff5c 100644 --- a/ccm-theme-foundry/src/main/resources/themes/foundry/foundry/lib/bebop/label.xsl +++ b/ccm-theme-foundry/src/main/resources/themes/foundry/foundry/lib/bebop/label.xsl @@ -1,9 +1,9 @@ ]> - - - + - + @@ -56,7 +56,7 @@ - @@ -76,7 +76,7 @@ - + @@ -89,7 +89,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -119,7 +119,7 @@ - + @@ -132,7 +132,7 @@ - + @@ -141,7 +141,7 @@ {$alt} - + @@ -150,7 +150,7 @@ - + @@ -205,13 +205,13 @@ - + no - + @@ -225,10 +225,10 @@ no - - - @@ -238,7 +238,7 @@ - + @@ -252,5 +252,5 @@ - +