User and groups management implementaiton completed
parent
a6b7c7e900
commit
f83d4b4833
|
|
@ -26,12 +26,16 @@ import org.libreccm.security.Group;
|
||||||
import org.libreccm.security.GroupManager;
|
import org.libreccm.security.GroupManager;
|
||||||
import org.libreccm.security.GroupRepository;
|
import org.libreccm.security.GroupRepository;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
import org.libreccm.ui.admin.AdminMessages;
|
import org.libreccm.ui.admin.AdminMessages;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -68,12 +72,6 @@ public class GroupFormController {
|
||||||
@Inject
|
@Inject
|
||||||
private Models models;
|
private Models models;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private MvcContext mvc;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private GroupManager groupManager;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GroupRepository groupRepository;
|
private GroupRepository groupRepository;
|
||||||
|
|
||||||
|
|
@ -105,7 +103,7 @@ public class GroupFormController {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String updateUser(
|
public String updateGroup(
|
||||||
@PathParam("groupIdentifier") final String groupIdentifierParam
|
@PathParam("groupIdentifier") final String groupIdentifierParam
|
||||||
) {
|
) {
|
||||||
if (bindingResult.isFailed()) {
|
if (bindingResult.isFailed()) {
|
||||||
|
|
@ -138,53 +136,16 @@ public class GroupFormController {
|
||||||
groupRepository.save(group);
|
groupRepository.save(group);
|
||||||
return "redirect:users-groups-roles/groups";
|
return "redirect:users-groups-roles/groups";
|
||||||
} else {
|
} else {
|
||||||
models.put("errors", Arrays.asList(
|
models.put(
|
||||||
|
"errors", Arrays.asList(
|
||||||
adminMessages.getMessage(
|
adminMessages.getMessage(
|
||||||
"usersgroupsroles.groups.not_found.message",
|
"usersgroupsroles.groups.not_found.message",
|
||||||
Arrays.asList(groupIdentifierParam)
|
Arrays.asList(groupIdentifierParam)
|
||||||
)
|
)
|
||||||
));
|
)
|
||||||
|
);
|
||||||
return "org/libreccm/ui/admin/users-groups-roles/group-form.xhtml";
|
return "org/libreccm/ui/admin/users-groups-roles/group-form.xhtml";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{groupIdentifier}/groups")
|
|
||||||
@AuthorizationRequired
|
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public String updateGroupMemberships(
|
|
||||||
@PathParam("groupIdentifier") final String groupIdentifierParam,
|
|
||||||
@FormParam("groupMembers") final String[] groupMembers
|
|
||||||
) {
|
|
||||||
final Map<String, Object> params = new HashMap<>();
|
|
||||||
params.put("groupIdentifier", groupIdentifierParam);
|
|
||||||
return String.format(
|
|
||||||
"redirect:",
|
|
||||||
mvc.uri(
|
|
||||||
"GroupsController#getGroupDetails",
|
|
||||||
params
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{groupIdentifier}/roles")
|
|
||||||
@AuthorizationRequired
|
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public String updateRoleMemberships(
|
|
||||||
@PathParam("groupIdentifier") final String groupIdentifierParam,
|
|
||||||
@FormParam("groupRoles") final String[] groupRoles
|
|
||||||
) {
|
|
||||||
// ToDo
|
|
||||||
return String.format(
|
|
||||||
"redirect:%s",
|
|
||||||
mvc.uri(
|
|
||||||
"UsersController#getUserDetails",
|
|
||||||
Map.of("userIdentifier", groupIdentifierParam)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,286 @@
|
||||||
|
/*
|
||||||
|
* 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.Group;
|
||||||
|
import org.libreccm.security.GroupManager;
|
||||||
|
import org.libreccm.security.GroupRepository;
|
||||||
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
import org.libreccm.security.Role;
|
||||||
|
import org.libreccm.security.RoleManager;
|
||||||
|
import org.libreccm.security.RoleRepository;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
|
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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@Path("/users-groups-roles/groups/")
|
||||||
|
@RequestScoped
|
||||||
|
public class GroupMembersRolesController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AdminMessages adminMessages;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupManager groupManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupRepository groupRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Models models;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RoleManager roleManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RoleRepository roleRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{groupIdentifier}/groups")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String updateGroupMemberships(
|
||||||
|
@PathParam("groupIdentifier") final String groupIdentifierParam,
|
||||||
|
@FormParam("groupMembers") final String[] groupMembersParam
|
||||||
|
) {
|
||||||
|
final Identifier groupIdentifier = identifierParser.parseIdentifier(
|
||||||
|
groupIdentifierParam
|
||||||
|
);
|
||||||
|
final Optional<Group> result;
|
||||||
|
switch (groupIdentifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
result = groupRepository.findById(
|
||||||
|
Long.parseLong(groupIdentifier.getIdentifier())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case UUID:
|
||||||
|
result = groupRepository.findByUuid(
|
||||||
|
groupIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = groupRepository.findByName(
|
||||||
|
groupIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Group group = result.get();
|
||||||
|
final List<String> memberNames = Arrays.asList(groupMembersParam);
|
||||||
|
|
||||||
|
// Check for new members
|
||||||
|
final List<String> newMemberNames = memberNames
|
||||||
|
.stream()
|
||||||
|
.filter(memberName -> !hasMember(group, memberName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Check for removed members
|
||||||
|
final List<String> removedMemberNames = group
|
||||||
|
.getMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getMember().getName())
|
||||||
|
.filter(memberName -> !memberNames.contains(memberName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (final String newMemberName : newMemberNames) {
|
||||||
|
addNewMember(group, newMemberName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final String removedMemberName : removedMemberNames) {
|
||||||
|
removeMember(group, removedMemberName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"redirect:/users-groups-roles/groups/%s/details",
|
||||||
|
groupIdentifierParam
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
models.put(
|
||||||
|
"errors", Arrays.asList(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"usersgroupsroles.groups.not_found.message",
|
||||||
|
Arrays.asList(groupIdentifierParam)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return "org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{groupIdentifier}/roles")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String updateRoleMemberships(
|
||||||
|
@PathParam("groupIdentifier") final String groupIdentifierParam,
|
||||||
|
@FormParam("groupRoles") final String[] groupRoles
|
||||||
|
) {
|
||||||
|
final Identifier groupIdentifier = identifierParser.parseIdentifier(
|
||||||
|
groupIdentifierParam
|
||||||
|
);
|
||||||
|
final Optional<Group> result;
|
||||||
|
switch (groupIdentifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
result = groupRepository.findById(
|
||||||
|
Long.parseLong(groupIdentifier.getIdentifier())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case UUID:
|
||||||
|
result = groupRepository.findByUuid(
|
||||||
|
groupIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = groupRepository.findByName(
|
||||||
|
groupIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Group group = result.get();
|
||||||
|
final List<String> roleNames = Arrays.asList(groupRoles);
|
||||||
|
|
||||||
|
// Check for new roles
|
||||||
|
final List<String> newRoleNames = roleNames
|
||||||
|
.stream()
|
||||||
|
.filter(roleName -> !hasRole(group, roleName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Check for removed roles
|
||||||
|
final List<String> removedRoleNames = group
|
||||||
|
.getRoleMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getRole().getName())
|
||||||
|
.filter(roleName -> !roleNames.contains(roleName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (final String newRoleName : newRoleNames) {
|
||||||
|
addNewRole(group, newRoleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final String removedRoleName : removedRoleNames) {
|
||||||
|
removeRole(group, removedRoleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"redirect:/users-groups-roles/groups/%s/details",
|
||||||
|
groupIdentifierParam
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
models.put(
|
||||||
|
"errors", Arrays.asList(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"usersgroupsroles.groups.not_found.message",
|
||||||
|
Arrays.asList(groupIdentifierParam)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return "org/libreccm/ui/admin/users-groups-roles/group-not-found.xhtml";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasMember(final Group group, final String memberName) {
|
||||||
|
return group
|
||||||
|
.getMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getMember().getName())
|
||||||
|
.anyMatch(name -> name.equals(memberName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNewMember(final Group group, final String newMemberName) {
|
||||||
|
final Optional<User> result = userRepository.findByName(newMemberName);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final User user = result.get();
|
||||||
|
groupManager.addMemberToGroup(user, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeMember(
|
||||||
|
final Group group, final String removedMemberName
|
||||||
|
) {
|
||||||
|
final Optional<User> result = userRepository.findByName(
|
||||||
|
removedMemberName
|
||||||
|
);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final User user = result.get();
|
||||||
|
groupManager.removeMemberFromGroup(user, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasRole(final Group group, final String roleName) {
|
||||||
|
return group
|
||||||
|
.getRoleMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getMember().getName())
|
||||||
|
.anyMatch(name -> name.equals(roleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNewRole(final Group group, final String newRoleName) {
|
||||||
|
final Optional<Role> result = roleRepository.findByName(newRoleName);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Role role = result.get();
|
||||||
|
roleManager.assignRoleToParty(role, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRole(final Group group, final String removedRoleName) {
|
||||||
|
final Optional<Role> result = roleRepository.findByName(
|
||||||
|
removedRoleName
|
||||||
|
);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Role role = result.get();
|
||||||
|
roleManager.removeRoleFromParty(role, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -24,8 +24,10 @@ import org.libreccm.security.RequiresPrivilege;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.mvc.Controller;
|
import javax.mvc.Controller;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -44,4 +46,15 @@ public class RolesController {
|
||||||
return "org/libreccm/ui/admin/users-groups-roles/roles.xhtml";
|
return "org/libreccm/ui/admin/users-groups-roles/roles.xhtml";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{roleIdentifier}/details")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String getRoleDetails(
|
||||||
|
@PathParam("roleIdentifier") final String roleIdentifierParam
|
||||||
|
) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -209,42 +209,4 @@ public class UserFormController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{userIdentifier}/groups")
|
|
||||||
@AuthorizationRequired
|
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public String updateGroupMemberships(
|
|
||||||
@PathParam("userIdentifier") final String userIdentifierParam,
|
|
||||||
@FormParam("userGroups") final String[] userGroups
|
|
||||||
) {
|
|
||||||
// ToDo
|
|
||||||
return String.format(
|
|
||||||
"redirect:%s",
|
|
||||||
mvc.uri(
|
|
||||||
"UsersController#getUserDetails",
|
|
||||||
Map.of("userIdentifier", userIdentifierParam)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{userIdentifier}/roles")
|
|
||||||
@AuthorizationRequired
|
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public String updateRoleMemberships(
|
|
||||||
@PathParam("userIdentifier") final String userIdentifierParam,
|
|
||||||
@FormParam("userRoles") final String[] userRoles
|
|
||||||
) {
|
|
||||||
// ToDo
|
|
||||||
return String.format(
|
|
||||||
"redirect:%s",
|
|
||||||
mvc.uri(
|
|
||||||
"UsersController#getUserDetails",
|
|
||||||
Map.of("userIdentifier", userIdentifierParam)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
* 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.Group;
|
||||||
|
import org.libreccm.security.GroupManager;
|
||||||
|
import org.libreccm.security.GroupRepository;
|
||||||
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
import org.libreccm.security.Role;
|
||||||
|
import org.libreccm.security.RoleManager;
|
||||||
|
import org.libreccm.security.RoleRepository;
|
||||||
|
import org.libreccm.security.User;
|
||||||
|
import org.libreccm.security.UserRepository;
|
||||||
|
import org.libreccm.ui.admin.AdminMessages;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
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.transaction.Transactional;
|
||||||
|
import javax.ws.rs.FormParam;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@Path("/users-groups-roles/users/")
|
||||||
|
@RequestScoped
|
||||||
|
public class UserGroupsRolesController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AdminMessages adminMessages;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupManager groupManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupRepository groupRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Models models;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RoleManager roleManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RoleRepository roleRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{userIdentifier}/groups")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String updateGroupMemberships(
|
||||||
|
@PathParam("userIdentifier") final String userIdentifierParam,
|
||||||
|
@FormParam("userGroups") final String[] userGroups
|
||||||
|
) {
|
||||||
|
final Identifier userIdentifier = identifierParser.parseIdentifier(
|
||||||
|
userIdentifierParam
|
||||||
|
);
|
||||||
|
final Optional<User> result;
|
||||||
|
switch (userIdentifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
result = userRepository.findById(
|
||||||
|
Long.parseLong(userIdentifier.getIdentifier())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case UUID:
|
||||||
|
result = userRepository.findByUuid(
|
||||||
|
userIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = userRepository.findByName(
|
||||||
|
userIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final User user = result.get();
|
||||||
|
final List<String> groupNames = Arrays.asList(userGroups);
|
||||||
|
|
||||||
|
// Check for new groups
|
||||||
|
final List<String> newGroupNames = groupNames
|
||||||
|
.stream()
|
||||||
|
.filter(groupName -> !isMember(user, groupName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Check for removed groups
|
||||||
|
final List<String> removedGroupNames = user
|
||||||
|
.getGroupMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getGroup().getName())
|
||||||
|
.filter(groupName -> !groupNames.contains(groupName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (final String newGroupName : newGroupNames) {
|
||||||
|
addNewGroup(user, newGroupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final String removedGroupName : removedGroupNames) {
|
||||||
|
removeGroup(user, removedGroupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"redirect:/users-groups-roles/users/%s/details",
|
||||||
|
userIdentifierParam
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
models.put(
|
||||||
|
"errors", Arrays.asList(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"usersgroupsroles.users.not_found.message",
|
||||||
|
Arrays.asList(userIdentifierParam)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return "org/libreccm/ui/admin/users-groups-roles/user-not-found.xhtml";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{userIdentifier}/roles")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String updateRoleMemberships(
|
||||||
|
@PathParam("userIdentifier") final String userIdentifierParam,
|
||||||
|
@FormParam("userRoles") final String[] userRoles
|
||||||
|
) {
|
||||||
|
final Identifier userIdentifier = identifierParser.parseIdentifier(
|
||||||
|
userIdentifierParam
|
||||||
|
);
|
||||||
|
final Optional<User> result;
|
||||||
|
switch (userIdentifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
result = userRepository.findById(
|
||||||
|
Long.parseLong(userIdentifier.getIdentifier())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case UUID:
|
||||||
|
result = userRepository.findByUuid(
|
||||||
|
userIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = userRepository.findByName(
|
||||||
|
userIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final User user = result.get();
|
||||||
|
final List<String> roleNames = Arrays.asList(userRoles);
|
||||||
|
|
||||||
|
// Check for new roles
|
||||||
|
final List<String> newRoleNames = roleNames
|
||||||
|
.stream()
|
||||||
|
.filter(roleName -> !hasRole(user, roleName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Check for removed roles
|
||||||
|
final List<String> removedRoleNames = user
|
||||||
|
.getRoleMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getRole().getName())
|
||||||
|
.filter(roleName -> !roleNames.contains(roleName))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (final String newRoleName : newRoleNames) {
|
||||||
|
addNewRole(user, newRoleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final String removedRoleName : removedRoleNames) {
|
||||||
|
removeRole(user, removedRoleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"redirect:/users-groups-roles/users/%s/details",
|
||||||
|
userIdentifierParam
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
models.put(
|
||||||
|
"errors", Arrays.asList(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"usersgroupsroles.users.not_found.message",
|
||||||
|
Arrays.asList(userIdentifierParam)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return "org/libreccm/ui/admin/users-groups-roles/user-not-found.xhtml";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMember(final User user, final String groupName) {
|
||||||
|
return user
|
||||||
|
.getGroupMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getGroup().getName())
|
||||||
|
.anyMatch(name -> name.equals(groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNewGroup(final User user, final String newGroupName) {
|
||||||
|
final Optional<Group> result = groupRepository.findByName(newGroupName);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Group group = result.get();
|
||||||
|
groupManager.addMemberToGroup(user, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeGroup(final User user, final String removedGroupName) {
|
||||||
|
final Optional<Group> result = groupRepository.findByName(
|
||||||
|
removedGroupName
|
||||||
|
);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Group group = result.get();
|
||||||
|
groupManager.removeMemberFromGroup(user, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasRole(final User user, final String roleName) {
|
||||||
|
return user
|
||||||
|
.getRoleMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getMember().getName())
|
||||||
|
.anyMatch(name -> name.equals(roleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNewRole(final User user, final String newRoleName) {
|
||||||
|
final Optional<Role> result = roleRepository.findByName(newRoleName);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Role role = result.get();
|
||||||
|
roleManager.assignRoleToParty(role, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRole(final User user, final String removedRoleName) {
|
||||||
|
final Optional<Role> result = roleRepository.findByName(
|
||||||
|
removedRoleName
|
||||||
|
);
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final Role role = result.get();
|
||||||
|
roleManager.removeRoleFromParty(role, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -39,9 +39,11 @@ public class UsersGroupsRolesPage implements AdminPage {
|
||||||
classes.add(UsersGroupsRolesController.class);
|
classes.add(UsersGroupsRolesController.class);
|
||||||
classes.add(GroupsController.class);
|
classes.add(GroupsController.class);
|
||||||
classes.add(GroupFormController.class);
|
classes.add(GroupFormController.class);
|
||||||
|
classes.add(GroupMembersRolesController.class);
|
||||||
classes.add(RolesController.class);
|
classes.add(RolesController.class);
|
||||||
classes.add(UsersController.class);
|
classes.add(UsersController.class);
|
||||||
classes.add(UserFormController.class);
|
classes.add(UserFormController.class);
|
||||||
|
classes.add(UserGroupsRolesController.class);
|
||||||
classes.add(EmailFormController.class);
|
classes.add(EmailFormController.class);
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
id="group-members-dialog"
|
id="group-members-dialog"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<form action="#{mvc.uri('GroupFormController#updateGroupMemberships', {'groupIdentifier': GroupDetailsModel.groupName})}"
|
<form action="#{mvc.uri('GroupMembersRolesController#updateGroupMemberships', {'groupIdentifier': GroupDetailsModel.groupName})}"
|
||||||
class="modal-content"
|
class="modal-content"
|
||||||
method="post">
|
method="post">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
<input class="form-check-input"
|
<input class="form-check-input"
|
||||||
checked="#{entry.member ? 'checked' : ''}"
|
checked="#{entry.member ? 'checked' : ''}"
|
||||||
id="group-#{entry.userName}"
|
id="group-#{entry.userName}"
|
||||||
name="groupMembers[]"
|
name="groupMembers"
|
||||||
value="#{entry.userName}"
|
value="#{entry.userName}"
|
||||||
type="checkbox" />
|
type="checkbox" />
|
||||||
<label class="form-check-label"
|
<label class="form-check-label"
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
<c:forEach items="#{GroupDetailsModel.members}"
|
<c:forEach items="#{GroupDetailsModel.members}"
|
||||||
var="member">
|
var="member">
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<a href="#">
|
<a href="#{mvc.uri('UsersController#getUserDetails', { 'userIdentifier': member.userName })}">
|
||||||
#{member.userName}
|
#{member.userName}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -143,7 +143,7 @@
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
|
|
||||||
<div class="d-flex mb-1">
|
<div class="d-flex mt-4 mb-1">
|
||||||
<h2 class="mr-2">
|
<h2 class="mr-2">
|
||||||
#{AdminMessages['usersgroupsroles.groups.groups_details.roles.heading']}
|
#{AdminMessages['usersgroupsroles.groups.groups_details.roles.heading']}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -166,7 +166,7 @@
|
||||||
id="group-roles-dialog"
|
id="group-roles-dialog"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<form action="#{mvc.uri('GroupFormController#updateRoleMemberships', {'groupIdentifier': GroupDetailsModel.groupName })}"
|
<form action="#{mvc.uri('GroupMembersRolesController#updateRoleMemberships', {'groupIdentifier': GroupDetailsModel.groupName })}"
|
||||||
class="modal-content"
|
class="modal-content"
|
||||||
method="post">
|
method="post">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -188,7 +188,7 @@
|
||||||
<input class="form-check-input"
|
<input class="form-check-input"
|
||||||
checked="#{entry.member ? 'checked' : ''}"
|
checked="#{entry.member ? 'checked' : ''}"
|
||||||
id="role-#{entry.roleName}"
|
id="role-#{entry.roleName}"
|
||||||
name="groupRoles[]"
|
name="groupRoles"
|
||||||
value="#{entry.roleName}"
|
value="#{entry.roleName}"
|
||||||
type="checkbox" />
|
type="checkbox" />
|
||||||
<label for="role#{entry.roleName}">
|
<label for="role#{entry.roleName}">
|
||||||
|
|
@ -217,9 +217,11 @@
|
||||||
<ul class="list-group mt-1 mb-4">
|
<ul class="list-group mt-1 mb-4">
|
||||||
<c:forEach items="#{GroupDetailsModel.roles}"
|
<c:forEach items="#{GroupDetailsModel.roles}"
|
||||||
var="role">
|
var="role">
|
||||||
<a href="#">
|
<li class="list-group-item">
|
||||||
|
<a href="#{mvc.uri('RolesController#getRoleDetails', {'roleIdentifier': role.roleName})}">
|
||||||
#{role.roleName}
|
#{role.roleName}
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</ul>
|
</ul>
|
||||||
</c:when>
|
</c:when>
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@
|
||||||
id="user-groups-dialog"
|
id="user-groups-dialog"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<form action="#{mvc.uri('UserFormController#updateGroupMemberships', {'userIdentifier': UserDetailsModel.name})}"
|
<form action="#{mvc.uri('UserGroupsRolesController#updateGroupMemberships', {'userIdentifier': UserDetailsModel.name})}"
|
||||||
class="modal-content"
|
class="modal-content"
|
||||||
method="post">
|
method="post">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -318,7 +318,7 @@
|
||||||
<input class="form-check-input"
|
<input class="form-check-input"
|
||||||
checked="#{entry.member ? 'checked' : ''}"
|
checked="#{entry.member ? 'checked' : ''}"
|
||||||
id="group-#{entry.groupName}"
|
id="group-#{entry.groupName}"
|
||||||
name="userGroups[]"
|
name="userGroups"
|
||||||
value="#{entry.groupName}"
|
value="#{entry.groupName}"
|
||||||
type="checkbox" />
|
type="checkbox" />
|
||||||
<label class="form-check-label"
|
<label class="form-check-label"
|
||||||
|
|
@ -345,9 +345,10 @@
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="#{UserDetailsModel.groupMemberships.size() > 0}">
|
<c:when test="#{UserDetailsModel.groupMemberships.size() > 0}">
|
||||||
<ul class="list-group mt-1">
|
<ul class="list-group mt-1">
|
||||||
<c:forEach items="#{UserDetailsModel.groupMemberships}">
|
<c:forEach items="#{UserDetailsModel.groupMemberships}"
|
||||||
|
var="group">
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<a href="#">
|
<a href="#{mvc.uri('GroupsController#getGroupDetails', {'groupIdentifier': group.groupName})}">
|
||||||
#{group.groupName}
|
#{group.groupName}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -361,7 +362,7 @@
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
|
|
||||||
<div class="d-flex mb-1">
|
<div class="d-flex mt-4 mb-1">
|
||||||
<h2 class="mr-2">
|
<h2 class="mr-2">
|
||||||
#{AdminMessages['usersgroupsroles.users.user_details.roles.heading']}
|
#{AdminMessages['usersgroupsroles.users.user_details.roles.heading']}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -384,7 +385,7 @@
|
||||||
id="user-roles-dialog"
|
id="user-roles-dialog"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<form action="#{mvc.uri('UserFormController#updateRoleMemberships', {'userIdentifier': UserDetailsModel.name })}"
|
<form action="#{mvc.uri('UserGroupsRolesController#updateRoleMemberships', {'userIdentifier': UserDetailsModel.name })}"
|
||||||
class="modal-content"
|
class="modal-content"
|
||||||
method="post">
|
method="post">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -406,7 +407,7 @@
|
||||||
<input class="form-check-input"
|
<input class="form-check-input"
|
||||||
checked="#{entry.member ? 'checked' : ''}"
|
checked="#{entry.member ? 'checked' : ''}"
|
||||||
id="role-#{entry.roleName}"
|
id="role-#{entry.roleName}"
|
||||||
name="userRoles[]"
|
name="userRoles"
|
||||||
value="#{entry.roleName}"
|
value="#{entry.roleName}"
|
||||||
type="checkbox" />
|
type="checkbox" />
|
||||||
<label for="role#{entry.roleName}">
|
<label for="role#{entry.roleName}">
|
||||||
|
|
@ -435,7 +436,7 @@
|
||||||
<ul class="list-group mt-1 mb-4">
|
<ul class="list-group mt-1 mb-4">
|
||||||
<c:forEach items="#{UserDetailsModel.roles}" var="role">
|
<c:forEach items="#{UserDetailsModel.roles}" var="role">
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<a href="#">
|
<a href="#{mvc.uri('RolesController#getRoleDetails', {'roleIdentifier': role.roleName })}">
|
||||||
#{role.roleName}
|
#{role.roleName}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ applications.description=Verwalten der Anwendungsinstanzen
|
||||||
imexport.label=Import/Export
|
imexport.label=Import/Export
|
||||||
categories.label=Kategorien
|
categories.label=Kategorien
|
||||||
categories.description=Verwaltung der Kategorien
|
categories.description=Verwaltung der Kategorien
|
||||||
configuration.label=Konfguration
|
configuration.label=Konfiguration
|
||||||
configuration.description=Bearbeiten der Konfiguration
|
configuration.description=Bearbeiten der Konfiguration
|
||||||
dashboard.label=Dashboard
|
dashboard.label=Dashboard
|
||||||
dashboard.description=Provides access to all applications
|
dashboard.description=Provides access to all applications
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue