diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupFormController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupFormController.java index 18e11c4ab..22784c16b 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupFormController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupFormController.java @@ -23,25 +23,17 @@ import org.libreccm.api.IdentifierParser; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.Group; -import org.libreccm.security.GroupManager; import org.libreccm.security.GroupRepository; import org.libreccm.security.RequiresPrivilege; -import org.libreccm.security.User; -import org.libreccm.security.UserRepository; import org.libreccm.ui.admin.AdminMessages; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.mvc.Controller; import javax.mvc.Models; -import javax.mvc.MvcContext; import javax.mvc.binding.BindingResult; import javax.mvc.binding.MvcBinding; import javax.transaction.Transactional; @@ -144,7 +136,7 @@ public class GroupFormController { ) ) ); - return "org/libreccm/ui/admin/users-groups-roles/group-form.xhtml"; + return "org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml"; } } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupMembersRolesController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupMembersRolesController.java index 1c70363de..80a899071 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupMembersRolesController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupMembersRolesController.java @@ -82,7 +82,7 @@ public class GroupMembersRolesController { private UserRepository userRepository; @POST - @Path("{groupIdentifier}/groups") + @Path("{groupIdentifier}/members") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserFormEntry.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserFormEntry.java index 022dad62d..d56e71d83 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserFormEntry.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserFormEntry.java @@ -23,13 +23,13 @@ package org.libreccm.ui.admin.usersgroupsroles; * @author Jens Pelzetter */ public class GroupUserFormEntry { - + private long userId; - + private String userUuid; - + private String userName; - + private boolean member; public long getUserId() { @@ -63,8 +63,5 @@ public class GroupUserFormEntry { public void setMember(final boolean member) { this.member = member; } - - - - + } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserMembership.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserMembership.java index 277f30bef..3dcd0865a 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserMembership.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupUserMembership.java @@ -20,6 +20,8 @@ package org.libreccm.ui.admin.usersgroupsroles; import org.libreccm.security.User; +import java.util.Objects; + /** * Model friendly representation of a member of a group. * @@ -42,7 +44,7 @@ public class GroupUserMembership implements Comparable { public GroupUserMembership() { // Nothing } - + public GroupUserMembership(final User user) { userId = user.getPartyId(); userUuid = user.getUuid(); @@ -51,7 +53,7 @@ public class GroupUserMembership implements Comparable { givenName = user.getGivenName(); familyName = user.getFamilyName(); } - + public long getUserId() { return userId; } @@ -102,7 +104,9 @@ public class GroupUserMembership implements Comparable { @Override public int compareTo(final GroupUserMembership other) { - int result = userName.compareTo(other.getUserName()); + int result = userName.compareTo( + Objects.requireNonNull(other.getUserName()) + ); if (result == 0) { return primaryEmailAddress.compareTo(other.getPrimaryEmailAddress()); } else { diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupsController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupsController.java index 060853ca4..69147e572 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupsController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/GroupsController.java @@ -23,8 +23,12 @@ import org.libreccm.api.IdentifierParser; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.Group; +import org.libreccm.security.GroupManager; +import org.libreccm.security.GroupMembership; import org.libreccm.security.GroupRepository; import org.libreccm.security.RequiresPrivilege; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleMembership; import org.libreccm.ui.Message; import org.libreccm.ui.MessageType; import org.libreccm.ui.admin.AdminMessages; @@ -38,7 +42,9 @@ import javax.inject.Inject; import javax.mvc.Controller; import javax.mvc.Models; import javax.transaction.Transactional; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -57,6 +63,9 @@ public class GroupsController { @Inject private GroupDetailsModel groupDetailsModel; + @Inject + private GroupManager groupManager; + @Inject private GroupRepository groupRepository; @@ -66,6 +75,9 @@ public class GroupsController { @Inject private Models models; + @Inject + private RoleManager roleManager; + @GET @Path("/") @AuthorizationRequired @@ -171,4 +183,68 @@ public class GroupsController { } } + @POST + @Path("/{groupIdentifier}/delete") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String deleteGroup( + @PathParam("groupIdentifier") final String groupIdentifierParam, + @FormParam("confirmed") final String confirmed + ) { + if ("true".equals(confirmed)) { + final Identifier identifier = identifierParser.parseIdentifier( + groupIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = groupRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = groupRepository.findByUuid(identifier + .getIdentifier()); + break; + default: + result = groupRepository.findByName(identifier + .getIdentifier()); + break; + } + + if (result.isPresent()) { + final Group group = result.get(); + for (final RoleMembership roleMembership : group + .getRoleMemberships()) { + roleManager.removeRoleFromParty( + roleMembership.getRole(), group + ); + } + + for (final GroupMembership groupMembership : group + .getMemberships()) { + groupManager.removeMemberFromGroup( + groupMembership.getMember(), group + ); + } + + groupRepository.delete(result.get()); + } else { + groupDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "usersgroupsroles.groups.not_found.message", + Arrays.asList(groupIdentifierParam) + ), + MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml"; + } + } + + return "redirect:users-groups-roles/groups"; + } + } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleDetailsModel.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleDetailsModel.java new file mode 100644 index 000000000..a22f07c45 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleDetailsModel.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2020 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 org.libreccm.ui.admin.usersgroupsroles; + +import org.libreccm.security.Party; +import org.libreccm.security.PartyRepository; +import org.libreccm.security.Role; +import org.libreccm.security.RoleMembership; +import org.libreccm.ui.Message; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.inject.Named; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("RoleDetailsModel") +public class RoleDetailsModel { + + @Inject + private PartyRepository partyRepository; + + private long roleId; + + private String uuid; + + private String roleName; + + private List members; + + private List permissions; + + private final List messages; + + public RoleDetailsModel() { + this.messages = new ArrayList<>(); + } + + public List getMessages() { + return Collections.unmodifiableList(messages); + } + + public void addMessage(final Message message) { + messages.add(message); + } + + public long getRoleId() { + return roleId; + } + + public String getUuid() { + return uuid; + } + + public String getRoleName() { + return roleName; + } + + public List getMembers() { + return Collections.unmodifiableList(members); + } + + public List getPermissions() { + return Collections.unmodifiableList(permissions); + } + + public List getRolePartyFormEnties() { + return partyRepository + .findAll() + .stream() + .map(this::buildRolePartyFormEntry) + .collect(Collectors.toList()); + } + + @Transactional(Transactional.TxType.REQUIRED) + protected void setRole(final Role role) { + Objects.requireNonNull(role); + + roleId = role.getRoleId(); + uuid = role.getUuid(); + roleName = role.getName(); + members = role + .getMemberships() + .stream() + .map(RoleMembership::getMember) + .map(RolePartyMembership::new) + .sorted() + .collect(Collectors.toList()); + } + + public boolean isNewRole() { + return roleId == 0; + } + + private RolePartyFormEntry buildRolePartyFormEntry(final Party party) { + final RolePartyFormEntry entry = new RolePartyFormEntry(); + entry.setPartyId(party.getPartyId()); + entry.setPartyUuid(party.getUuid()); + entry.setPartyName(party.getName()); + entry.setMember( + members + .stream() + .anyMatch( + membership -> membership.getPartyUuid().equals(party + .getUuid()) + ) + ); + return entry; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleFormController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleFormController.java new file mode 100644 index 000000000..80df106d9 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleFormController.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 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 org.libreccm.ui.admin.usersgroupsroles; + +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.core.CoreConstants; +import org.libreccm.security.AuthorizationRequired; +import org.libreccm.security.RequiresPrivilege; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; +import org.libreccm.ui.admin.AdminMessages; + +import java.util.Arrays; +import java.util.Optional; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +import javax.mvc.Models; +import javax.mvc.binding.BindingResult; +import javax.mvc.binding.MvcBinding; +import javax.transaction.Transactional; +import javax.validation.constraints.NotBlank; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * + * @author Jens Pelzetter + */ +@Controller +@Path("/users-groups-roles/roles/") +@RequestScoped +public class RoleFormController { + + @Inject + private AdminMessages adminMessages; + + @Inject + private BindingResult bindingResult; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private Models models; + + @Inject + private RoleRepository roleRepository; + + @MvcBinding + @FormParam("roleName") + @NotBlank + private String roleName; + + @POST + @Path("/new") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String createRole() { + if (bindingResult.isFailed()) { + models.put("errors", bindingResult.getAllMessages()); + return "org/libreccm/ui/admin/users-groups-roles/role-form.xhtml"; + } + + final Role role = new Role(); + role.setName(roleName); + roleRepository.save(role); + + return "redirect:users-groups-roles/roles"; + } + + @POST + @Path("{roleIdentifier}/edit") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String updateRole( + @PathParam("roleIdentifier") final String roleIdentifierParam + ) { + if (bindingResult.isFailed()) { + models.put("errors", bindingResult.getAllMessages()); + return "org/libreccm/ui/admin/users-groups-roles/role-form.xhtml"; + } + + final Identifier identifier = identifierParser.parseIdentifier( + roleIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = roleRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = roleRepository.findByUuid(identifier.getIdentifier()); + break; + default: + result = roleRepository.findByName(identifier.getIdentifier()); + break; + } + + if (result.isPresent()) { + final Role role = result.get(); + role.setName(roleName); + + return "redirect:users-groups-roles/roles"; + } else { + models.put( + "errors", Arrays.asList( + adminMessages.getMessage( + "usersgroupsroles.roles.not_found.message", + Arrays.asList(roleIdentifierParam) + ) + ) + ); + return "org/libreccm/ui/admin/users-groups-roles/role-not-found.xhtml"; + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleMembersController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleMembersController.java new file mode 100644 index 000000000..8bf005a29 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RoleMembersController.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2020 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 org.libreccm.ui.admin.usersgroupsroles; + +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.core.CoreConstants; +import org.libreccm.security.AuthorizationRequired; +import org.libreccm.security.Party; +import org.libreccm.security.PartyRepository; +import org.libreccm.security.RequiresPrivilege; +import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleRepository; +import org.libreccm.ui.admin.AdminMessages; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * + * @author Jens Pelzetter + */ +@Controller +@Path("/users-groups-roles/roles/") +@RequestScoped + +public class RoleMembersController { + + @Inject + private AdminMessages adminMessages; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private Models models; + + @Inject + private PartyRepository partyRepository; + + @Inject + private RoleManager roleManager; + + @Inject + private RoleRepository roleRepository; + + @POST + @Path("{roleIdentifier}/members") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String updateRoleMemberships( + @PathParam("roleIdentifier") final String roleIdentifierParam, + @FormParam("roleMembers") final String[] roleMembersParam + ) { + final Identifier identifier = identifierParser.parseIdentifier( + roleIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = roleRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = roleRepository.findByUuid( + identifier.getIdentifier() + ); + break; + default: + result = roleRepository.findByName( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Role role = result.get(); + final List memberNames = Arrays.asList(roleMembersParam); + + // Check for new members + final List newMemberNames = memberNames + .stream() + .filter(memberName -> !hasMember(role, memberName)) + .collect(Collectors.toList()); + + // Check for removed members + final List removedMemberNames = role + .getMemberships() + .stream() + .map(membership -> membership.getMember().getName()) + .filter(memberName -> !memberNames.contains(memberName)) + .collect(Collectors.toList()); + + for (final String newMemberName : newMemberNames) { + addNewMember(role, newMemberName); + } + + for (final String removedMemberName : removedMemberNames) { + removeMember(role, removedMemberName); + } + + return String.format( + "redirect:/users-groups-roles/roles/%s/details", + roleIdentifierParam + ); + } else { + models.put( + "errors", Arrays.asList( + adminMessages.getMessage( + "usersgroupsroles.roles.not_found.message", + Arrays.asList(roleIdentifierParam) + ) + ) + ); + return "org/libreccm/ui/admin/users-groups-roles/role-not-found.xhtml"; + } + } + + private boolean hasMember(final Role role, final String memberName) { + return role + .getMemberships() + .stream() + .map(membership -> membership.getMember().getName()) + .anyMatch(name -> name.equals(memberName)); + } + + private void addNewMember(final Role role, final String newMemberName) { + final Optional result = partyRepository.findByName( + newMemberName + ); + if (result.isPresent()) { + final Party party = result.get(); + roleManager.assignRoleToParty(role, party); + } + } + + private void removeMember(final Role role, final String removedMemberName) { + final Optional result = partyRepository.findByName( + removedMemberName + ); + if (result.isPresent()) { + final Party party = result.get(); + roleManager.removeRoleFromParty(role, party); + } + } +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePartyFormEntry.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePartyFormEntry.java new file mode 100644 index 000000000..cab35dc5e --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePartyFormEntry.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 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 org.libreccm.ui.admin.usersgroupsroles; + +/** + * + * @author Jens Pelzetter + */ +public class RolePartyFormEntry { + + private long partyId; + + private String partyUuid; + + private String partyName; + + private boolean member; + + public long getPartyId() { + return partyId; + } + + public void setPartyId(final long partyId) { + this.partyId = partyId; + } + + public String getPartyUuid() { + return partyUuid; + } + + public void setPartyUuid(final String partyUuid) { + this.partyUuid = partyUuid; + } + + public String getPartyName() { + return partyName; + } + + public void setPartyName(final String partyName) { + this.partyName = partyName; + } + + public boolean isMember() { + return member; + } + + public void setMember(final boolean member) { + this.member = member; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePartyMembership.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePartyMembership.java new file mode 100644 index 000000000..c5b272468 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePartyMembership.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 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 org.libreccm.ui.admin.usersgroupsroles; + +import org.libreccm.security.Party; + +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + */ +public class RolePartyMembership implements Comparable{ + + private long partyId; + + private String partyUuid; + + private String partyName; + + public RolePartyMembership() { + // Nothing + } + + public RolePartyMembership(final Party party) { + partyId = party.getPartyId(); + partyUuid = party.getUuid(); + partyName = party.getName(); + } + + public long getPartyId() { + return partyId; + } + + public void setPartyId(final long partyId) { + this.partyId = partyId; + } + + public String getPartyUuid() { + return partyUuid; + } + + public void setPartyUuid(final String partyUuid) { + this.partyUuid = partyUuid; + } + + public String getPartyName() { + return partyName; + } + + public void setPartyName(final String partyName) { + this.partyName = partyName; + } + + @Override + public int compareTo(final RolePartyMembership other) { + return partyName.compareTo( + Objects.requireNonNull(other).getPartyName() + ); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePermission.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePermission.java new file mode 100644 index 000000000..c17199a7f --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolePermission.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 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 org.libreccm.ui.admin.usersgroupsroles; + +import org.libreccm.security.Permission; + +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + */ +public class RolePermission implements Comparable { + + private long permissionId; + + private String permissionUuid; + + private String grantedPrivilege; + + private String objectName; + + private boolean objectPermission; + + public RolePermission() { + // Nothing + } + + public RolePermission(final Permission permission) { + permissionId = permission.getPermissionId(); + permissionUuid = permission.getUuid(); + grantedPrivilege = permission.getGrantedPrivilege(); + objectPermission = permission.getObject() != null; + if (objectPermission) { + objectName = permission.getObject().getDisplayName(); + } + } + + public long getPermissionId() { + return permissionId; + } + + public void setPermissionId(final long permissionId) { + this.permissionId = permissionId; + } + + public String getPermissionUuid() { + return permissionUuid; + } + + public void setPermissionUuid(final String permissionUuid) { + this.permissionUuid = permissionUuid; + } + + public String getGrantedPrivilege() { + return grantedPrivilege; + } + + public void setGrantedPrivilege(final String grantedPrivilege) { + this.grantedPrivilege = grantedPrivilege; + } + + public String getObjectName() { + return objectName; + } + + public void setObjectName(final String objectName) { + this.objectName = objectName; + } + + public boolean isObjectPermission() { + return objectPermission; + } + + public void setObjectPermission(final boolean objectPermission) { + this.objectPermission = objectPermission; + } + + @Override + public int compareTo(final RolePermission other) { + int result = Objects.compare( + grantedPrivilege, + Objects.requireNonNull(other).getGrantedPrivilege(), + (privilege1, privilege2) -> privilege1.compareTo(privilege2) + ); + if (result == 0 && isObjectPermission()) { + return Objects.compare( + objectName, + Objects.requireNonNull(other).getObjectName(), + (name1, name2) -> name1.compareTo(name2) + ); + } else { + return result; + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolesController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolesController.java index d694dd0b7..f71b5080e 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolesController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/RolesController.java @@ -18,14 +18,29 @@ */ package org.libreccm.ui.admin.usersgroupsroles; +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; +import org.libreccm.ui.Message; +import org.libreccm.ui.MessageType; +import org.libreccm.ui.admin.AdminMessages; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; import javax.mvc.Controller; +import javax.mvc.Models; import javax.transaction.Transactional; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -38,11 +53,29 @@ import javax.ws.rs.PathParam; @Path("/users-groups-roles/roles") public class RolesController { + @Inject + private AdminMessages adminMessages; + + @Inject + private RoleDetailsModel rolesDetailsModel; + + @Inject + private RoleRepository roleRepository; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private Models models; + @GET @Path("/") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) public String getRoles() { + final List roles = roleRepository.findAll(); + models.put("roles", roles); + return "org/libreccm/ui/admin/users-groups-roles/roles.xhtml"; } @@ -54,7 +87,149 @@ public class RolesController { public String getRoleDetails( @PathParam("roleIdentifier") final String roleIdentifierParam ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + roleIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = roleRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = roleRepository.findByUuid( + identifier.getIdentifier() + ); + break; + default: + result = roleRepository.findByName( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + rolesDetailsModel.setRole(result.get()); + return "org/libreccm/ui/admin/users-groups-roles/role-details.xhtml"; + } else { + rolesDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "usersgroupsroles.roles.not_found_message", + Arrays.asList(roleIdentifierParam) + ), + MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/users-groups-roles/role-not-found.xhtml"; + } + } + + @GET + @Path("/new") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + public String newRole() { + return "org/libreccm/ui/admin/users-groups-roles/role-form.xhtml"; + } + + @GET + @Path("/{roleIdentifier}/edit") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String editRole( + @PathParam("roleIdentifier") final String roleIdentifierParam + ) { + final Identifier identifier = identifierParser.parseIdentifier( + roleIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = roleRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = roleRepository.findByUuid( + identifier.getIdentifier() + ); + break; + default: + result = roleRepository.findByName( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + rolesDetailsModel.setRole(result.get()); + return "org/libreccm/ui/admin/users-groups-roles/role-form.xhtml"; + } else { + rolesDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "usersgroupsroles.roles.not_found_message", + Arrays.asList(roleIdentifierParam) + ), + MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/users-groups-roles/role-not-found.xhtml"; + } + } + + @POST + @Path("/{roleIdentifier}/delete") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String deleteRole( + @PathParam("roleIdentifier") final String roleIdentifierParam, + @FormParam("confirmed") final String confirmed + ) { + if ("true".equals(confirmed)) { + final Identifier identifier = identifierParser.parseIdentifier( + roleIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = roleRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = roleRepository.findByUuid( + identifier.getIdentifier() + ); + break; + default: + result = roleRepository.findByName( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + roleRepository.delete(result.get()); + } else { + rolesDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "usersgroupsroles.roles.not_found_message", + Arrays.asList(roleIdentifierParam) + ), + MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/users-groups-roles/role-not-found.xhtml"; + } + } + + return "redirect:users-groups-roles/roles"; } } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UserFormController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UserFormController.java index ee0b9688a..57cbb9968 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UserFormController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UserFormController.java @@ -205,7 +205,7 @@ public class UserFormController { Arrays.asList(userIdentifierParam) ) )); - return "org/libreccm/ui/admin/users-groups-roles/user-form.xhtml"; + return "org/libreccm/ui/admin/users-groups-roles/user-not-found.xhtml"; } } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UsersGroupsRolesPage.java b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UsersGroupsRolesPage.java index ec9db6a98..2a2c833d5 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UsersGroupsRolesPage.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/usersgroupsroles/UsersGroupsRolesPage.java @@ -41,6 +41,8 @@ public class UsersGroupsRolesPage implements AdminPage { classes.add(GroupFormController.class); classes.add(GroupMembersRolesController.class); classes.add(RolesController.class); + classes.add(RoleFormController.class); + classes.add(RoleMembersController.class); classes.add(UsersController.class); classes.add(UserFormController.class); classes.add(UserGroupsRolesController.class); diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-form.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-form.xhtml index 3c7ed9b55..8dbdfcfc7 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-form.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-form.xhtml @@ -21,12 +21,11 @@
  • - #{GroupDetailsModel.newGroup ? AdminMessages['usersgroupsroles.groups.breadcrumb.new'] : AdminMessages['usersgroupsroles.groups.breadcrumb.edit']}
  • diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml index 89a5ed0cc..23cbab073 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml @@ -16,12 +16,12 @@ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/groups.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/groups.xhtml index 75688c26c..fe90baa6f 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/groups.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/users-groups-roles/groups.xhtml @@ -83,7 +83,7 @@ id="confirm-delete-#{group.name}" tabindex="-1">