Skip to content
......@@ -136,14 +136,21 @@ public class JWTWebServiceController {
// else: empty response (as defined by GMS standard)
}
@GetMapping(value = {"/ws/jwt/list/{group:.+}", "/ws/jwt/list"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void listGroups(@PathVariable("group") Optional<String> groupNames, Principal principal, HttpServletResponse response) throws IOException {
@GetMapping(value = {"/ws/jwt/list/{group:.+}", "/ws/jwt/list", "/list"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void listGroups(@PathVariable("group") Optional<String> groupNames,
@RequestParam(value = "recursive", defaultValue = "false") boolean recursive,
Principal principal, HttpServletResponse response) throws IOException {
String userId = principal.getName();
GroupEntity parentGroup = groupNameService.getGroupFromNames(groupNames);
List<GroupEntity> allSubGroups = groupsDAO.getDirectSubGroups(parentGroup.getPath());
List<GroupEntity> allSubGroups;
if (recursive) {
allSubGroups = groupsDAO.getAllChildren(parentGroup.getPath());
} else {
allSubGroups = groupsDAO.getDirectSubGroups(parentGroup.getPath());
}
// Select only the groups visible to the user
List<PermissionEntity> permissions = permissionsDAO.findUserPermissions(userId);
......@@ -166,6 +173,8 @@ public class JWTWebServiceController {
* Creates a group and its ancestors if they are missing. It doesn't fail if
* the last group already exists.
*/
// Moved to GroupsController with different parameters
@Deprecated
@PostMapping(value = "/ws/jwt/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE)
public void createGroup(@PathVariable("group") String groupParam, HttpServletRequest request, HttpServletResponse response) throws IOException {
......@@ -191,13 +200,15 @@ public class JWTWebServiceController {
}
}
@Deprecated
@DeleteMapping(value = "/ws/jwt/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE)
public void deleteGroup(@PathVariable("group") String groupParam, HttpServletResponse response) {
GroupEntity group = groupNameService.getGroupFromNames(Optional.of(groupParam));
groupsDAO.deleteGroup(group);
groupsManager.deleteGroup(group.getId());
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
@Deprecated
@GetMapping(value = {"/ws/jwt/membership/{group:.+}", "/ws/jwt/membership"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void getMembership(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String userId, HttpServletResponse response) throws IOException {
......@@ -212,6 +223,7 @@ public class JWTWebServiceController {
}
}
@Deprecated
@PostMapping(value = {"/ws/jwt/membership/{group:.+}", "/ws/jwt/membership"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void addMember(@PathVariable("group") Optional<String> groupNames, HttpServletRequest request, HttpServletResponse response) throws IOException {
......@@ -226,6 +238,7 @@ public class JWTWebServiceController {
membershipManager.addMember(groupEntity, targetUserId);
}
@Deprecated
@DeleteMapping(value = {"/ws/jwt/membership/{group:.+}", "/ws/jwt/membership"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void removeMember(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String userId,
HttpServletRequest request, HttpServletResponse response) throws IOException {
......@@ -236,6 +249,7 @@ public class JWTWebServiceController {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
@Deprecated
@GetMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void getUserPermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") Optional<String> userId, HttpServletRequest request, HttpServletResponse response) throws IOException {
......@@ -256,18 +270,21 @@ public class JWTWebServiceController {
}
}
@Deprecated
@PostMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void addPermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String targetUserId, @RequestParam("permission") Permission permission) throws IOException {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
permissionsManager.addPermission(groupEntity, targetUserId, permission);
}
@Deprecated
@PutMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void setPermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String targetUserId, @RequestParam("permission") Permission permission) throws IOException {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
permissionsManager.createOrUpdatePermission(groupEntity, targetUserId, permission);
}
@Deprecated
@DeleteMapping(value = {"/ws/jwt/permission/{group:.+}", "/ws/jwt/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE)
public void removePermission(@PathVariable("group") Optional<String> groupNames, @RequestParam("user_id") String userId,
HttpServletRequest request, HttpServletResponse response) throws IOException {
......@@ -356,10 +373,10 @@ public class JWTWebServiceController {
throw new BadRequestException("Missing alternative subject");
}
joinService.join(fromUser, toUser);
String mergedId = joinService.join(fromUser, toUser);
Map<String, String> responseBody = new HashMap<>();
responseBody.put("mergedId", fromUser);
responseBody.put("mergedId", mergedId);
return ResponseEntity.ok(responseBody);
}
}
......@@ -27,7 +27,7 @@ public class KeepAliveController {
userManager = ServiceLocator.getInstance().getUserManager();
}
@GetMapping(value = "/keepAlive", produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/ui/keepAlive", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> keepAlive(HttpServletRequest request) {
LOG.trace("Keepalive called");
if (sessionData.getExpiresIn() < 60) {
......
......@@ -8,10 +8,15 @@ import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
import it.inaf.ia2.gms.model.request.RemoveMemberRequest;
import it.inaf.ia2.gms.model.request.TabRequest;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.service.GroupNameService;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.rap.data.RapUser;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
......@@ -21,6 +26,7 @@ import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
......@@ -35,7 +41,10 @@ public class MembersController {
@Autowired
private PermissionsManager permissionsManager;
@GetMapping(value = "/members", produces = MediaType.APPLICATION_JSON_VALUE)
@Autowired
protected GroupNameService groupNameService;
@GetMapping(value = "/ui/members", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUser>> getMembersTab(TabRequest request) {
GroupEntity group = groupsService.getGroupById(request.getGroupId());
......@@ -45,7 +54,7 @@ public class MembersController {
return ResponseEntity.ok(membersPanel);
}
@PostMapping(value = "/member", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@PostMapping(value = "/ui/member", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUser>> addMember(@Valid @RequestBody AddMemberRequest request) {
GroupEntity group = groupsService.getGroupById(request.getGroupId());
......@@ -56,7 +65,7 @@ public class MembersController {
return new ResponseEntity<>(getMembersPanel(group, request), HttpStatus.CREATED);
}
@DeleteMapping(value = "/member", produces = MediaType.APPLICATION_JSON_VALUE)
@DeleteMapping(value = "/ui/member", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUser>> removeMember(@Valid RemoveMemberRequest request) {
GroupEntity group = groupsService.getGroupById(request.getGroupId());
......@@ -77,4 +86,36 @@ public class MembersController {
});
return new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize());
}
@GetMapping(value = "/membership", produces = MediaType.TEXT_PLAIN_VALUE)
public void getMembership(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") String userId, HttpServletResponse response) throws IOException {
GroupEntity parent = groupNameService.getGroupFromNames(groupNames);
List<GroupEntity> groups = membershipManager.getUserGroups(parent, userId);
try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) {
for (String groupName : groupNameService.getGroupsNames(groups)) {
pw.println(groupNameService.getShortGroupName(groupName, groupNames));
}
}
}
@PostMapping(value = "/membership", produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void addMember(@RequestParam("group") Optional<String> groupNames,
@RequestParam("user_id") String targetUserId) {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
membershipManager.addMember(groupEntity, targetUserId);
}
@DeleteMapping(value = "/membership", produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<?> removeMember(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") String userId) {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
membershipManager.removeMember(groupEntity, userId);
return ResponseEntity.noContent().build();
}
}
package it.inaf.ia2.gms.controller;
import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.manager.GroupsManager;
import it.inaf.ia2.gms.manager.PermissionsManager;
import it.inaf.ia2.gms.model.request.AddPermissionRequest;
......@@ -15,13 +14,16 @@ import it.inaf.ia2.gms.model.response.UserPermission;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.GroupNameService;
import it.inaf.ia2.gms.service.SearchService;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
......@@ -44,7 +46,13 @@ public class PermissionsController {
@Autowired
private PermissionsManager permissionsManager;
@GetMapping(value = "/permissions", produces = MediaType.APPLICATION_JSON_VALUE)
@Autowired
protected GroupNameService groupNameService;
@Autowired
private SearchService searchService;
@GetMapping(value = "/ui/permissions", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUserPermission>> getPermissionsTab(TabRequest request) {
GroupEntity group = groupsManager.getGroupById(request.getGroupId());
......@@ -53,7 +61,7 @@ public class PermissionsController {
return ResponseEntity.ok(permissionsPanel);
}
@GetMapping(value = "/permission", produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/ui/permission", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Permission>> getUserPermission(@RequestParam("groupId") String groupId, @RequestParam("userId") String userId) {
GroupEntity group = groupsManager.getGroupById(groupId);
......@@ -68,7 +76,7 @@ public class PermissionsController {
}
}
@PostMapping(value = "/permission", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@PostMapping(value = "/ui/permission", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUserPermission>> addPermission(@Valid @RequestBody AddPermissionRequest request) {
GroupEntity group = groupsManager.getGroupById(request.getGroupId());
......@@ -81,7 +89,7 @@ public class PermissionsController {
return new ResponseEntity<>(getPermissionsPanel(group, request), HttpStatus.CREATED);
}
@PutMapping(value = "/permission", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@PutMapping(value = "/ui/permission", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, String>> updatePermission(@Valid @RequestBody UpdatePermissionRequest request) {
GroupEntity group = groupsManager.getGroupById(request.getGroupId());
......@@ -93,7 +101,7 @@ public class PermissionsController {
return ResponseEntity.ok(response);
}
@DeleteMapping(value = "/permission", produces = MediaType.APPLICATION_JSON_VALUE)
@DeleteMapping(value = "/ui/permission", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUserPermission>> deletePermission(@Valid MemberRequest request) {
GroupEntity group = groupsManager.getGroupById(request.getGroupId());
......@@ -109,4 +117,45 @@ public class PermissionsController {
});
return new PaginatedData<>(permissions, request.getPaginatorPage(), request.getPaginatorPageSize());
}
@GetMapping(value = "/permission", produces = MediaType.TEXT_PLAIN_VALUE)
public void getUserPermission(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") Optional<String> userId, HttpServletRequest request, HttpServletResponse response) throws IOException {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
if (userId.isPresent()) {
try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) {
for (UserPermission userPermission : searchService.getUserPermission(groupEntity, userId.get(), permissionsManager.getCurrentUserPermissions(groupEntity))) {
String group = String.join(".", userPermission.getGroupCompleteName());
pw.println(group + " " + userPermission.getPermission());
}
}
} else {
try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) {
for (it.inaf.ia2.gms.model.RapUserPermission up : permissionsManager.getAllPermissions(groupEntity)) {
pw.println(up.getUser().getId() + " " + up.getPermission());
}
}
}
}
@PostMapping(value = "/permission", produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void addPermission(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") String targetUserId, @RequestParam("permission") Permission permission) throws IOException {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
permissionsManager.addPermission(groupEntity, targetUserId, permission);
}
@PutMapping(value = "/permission", produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void setPermission(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") String targetUserId, @RequestParam("permission") Permission permission) throws IOException {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
permissionsManager.createOrUpdatePermission(groupEntity, targetUserId, permission);
}
@DeleteMapping(value = "/permission", produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<?> removePermission(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") String userId) {
GroupEntity groupEntity = groupNameService.getGroupFromNames(groupNames);
permissionsManager.removePermission(groupEntity, userId);
return ResponseEntity.noContent().build();
}
}
package it.inaf.ia2.gms.controller;
import it.inaf.ia2.gms.model.request.GenericSearchRequest;
import it.inaf.ia2.gms.model.response.PaginatedData;
import it.inaf.ia2.gms.model.response.SearchResponseItem;
import it.inaf.ia2.gms.model.response.UserSearchResponse;
import it.inaf.ia2.gms.service.SearchService;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
......@@ -22,15 +23,13 @@ public class SearchController {
@Autowired
private SearchService searchService;
@GetMapping(value = "/search", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<SearchResponseItem>> getSearchResults(@RequestParam("query") String query,
@RequestParam("page") int page, @RequestParam("pageSize") int pageSize) {
PaginatedData<SearchResponseItem> response = searchService.search(query, servletRequest.getUserPrincipal().getName(), page, pageSize);
@GetMapping(value = "/ui/search", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<SearchResponseItem>> getSearchResults(@Valid GenericSearchRequest searchRequest) {
PaginatedData<SearchResponseItem> response = searchService.search(searchRequest, servletRequest.getUserPrincipal().getName());
return ResponseEntity.ok(response);
}
@GetMapping(value = "/search/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/ui/search/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<UserSearchResponse> getSearchResultUser(@PathVariable("userId") String userId) {
UserSearchResponse response = searchService.getUserSearchResult(servletRequest.getUserPrincipal().getName(), userId);
......
......@@ -16,7 +16,7 @@ public class UsersController {
@Autowired
private RapClient rapClient;
@GetMapping(value = "users", produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/ui/users", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<RapUser>> searchUsers(@RequestParam("search") String searchText) {
return ResponseEntity.ok(rapClient.getUsers(searchText));
}
......
......@@ -4,12 +4,17 @@ import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.model.ActionType;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.gms.service.PermissionUtils;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class GroupsManager {
public class GroupsManager extends UserAwareComponent {
private final GroupsService groupsService;
private final PermissionsManager permissionsManager;
......@@ -37,6 +42,22 @@ public class GroupsManager {
return group;
}
public List<GroupEntity> getChildGroups(GroupEntity parentGroup, boolean recursive) {
List<GroupEntity> allSubGroups = groupsService.getChildGroups(parentGroup, recursive);
// Select only the groups visible to the user
List<PermissionEntity> permissions = permissionsManager.getCurrentUserPermissions();
List<GroupEntity> visibleSubgroups = new ArrayList<>();
for (GroupEntity subgroup : allSubGroups) {
PermissionUtils.getGroupPermission(subgroup, permissions).ifPresent(permission -> {
visibleSubgroups.add(subgroup);
});
}
return visibleSubgroups;
}
public GroupEntity createGroup(GroupEntity parent, String childGroupName, boolean leaf) {
if (parent.isLeaf()) {
......@@ -45,7 +66,7 @@ public class GroupsManager {
verifyUserCanManageGroup(parent);
return groupsService.addGroup(parent, childGroupName, leaf);
return groupsService.addGroup(parent, childGroupName, leaf, getCurrentUserId());
}
public GroupEntity updateGroup(String groupId, String newGroupName, boolean leaf) {
......@@ -63,15 +84,19 @@ public class GroupsManager {
}
public void verifyUserCanReadGroup(GroupEntity group) {
if (GroupsService.ROOT.equals(group.getId())) {
// Everybody can read the root
return;
}
if (permissionsManager.getCurrentUserPermission(group) == null) {
loggingDAO.logAction("Unauthorized group management request, group_id=" + group.getId());
loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized group management request, group_id=" + group.getId());
throw new UnauthorizedException("Missing permission to see this group");
}
}
private void verifyUserCanManageGroup(GroupEntity group) {
if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) {
loggingDAO.logAction("Unauthorized group management request, group_id=" + group.getId());
loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized group management request, group_id=" + group.getId());
throw new UnauthorizedException("Missing admin permission");
}
}
......
......@@ -14,6 +14,7 @@ import it.inaf.ia2.gms.persistence.model.InvitedRegistration;
import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.service.PermissionsService;
import it.inaf.ia2.gms.authn.RapClient;
import static it.inaf.ia2.gms.persistence.model.ActionType.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
......@@ -68,6 +69,7 @@ public class InvitedRegistrationManager extends UserAwareComponent {
for (Map.Entry<GroupEntity, Permission> entry : groupsPermissions.entrySet()) {
GroupEntity group = entry.getKey();
if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) {
loggingDAO.logAction(UNAUTHORIZED_ACCESS_ATTEMPT, "Attempt to add invited registration for group " + group.getId());
throw new UnauthorizedException("You don't have the permission to perform invited registrations");
}
groupIdsPermissions.put(group.getId(), entry.getValue());
......@@ -80,6 +82,8 @@ public class InvitedRegistrationManager extends UserAwareComponent {
.setGroupsPermissions(groupIdsPermissions);
invitedRegistrationDAO.addInvitedRegistration(invitedRegistration);
loggingDAO.logAction(INVITED_REGISTRATION_ADDED, "Email=" + email);
}
public InvitedRegistration getInvitedRegistrationFromToken(String token) {
......@@ -94,7 +98,7 @@ public class InvitedRegistrationManager extends UserAwareComponent {
httpSession.setAttribute(INVITED_REGISTRATION, invitedRegistration);
loggingDAO.logAction("Started invited registration for email " + invitedRegistration.getEmail());
loggingDAO.logAction(INVITED_REGISTRATION_OPENED, "Started invited registration for email " + invitedRegistration.getEmail());
return invitedRegistration;
} catch (NoSuchAlgorithmException ex) {
......@@ -144,24 +148,28 @@ public class InvitedRegistrationManager extends UserAwareComponent {
}
private void completeInvitedRegistration(InvitedRegistration invitedRegistration) {
String userId = getCurrentUserId();
for (Map.Entry<String, Permission> entry : invitedRegistration.getGroupsPermissions().entrySet()) {
String groupId = entry.getKey();
String userId = getCurrentUserId();
GroupEntity groupEntity = groupsDAO.findGroupById(groupId).get();
MembershipEntity membershipEntity = new MembershipEntity();
membershipEntity.setUserId(userId);
membershipEntity.setGroupId(groupId);
membershipEntity.setCreatedBy(getCurrentUserId());
membershipsDAO.addMember(membershipEntity);
permissionsService.addPermission(groupEntity, userId, entry.getValue());
permissionsService.addPermission(groupEntity, userId, entry.getValue(), userId);
}
invitedRegistration.setUserId(getCurrentUserId());
// FIXME (workaround): separated update for user and done in order to use triggers
invitedRegistrationDAO.setRegistrationUser(invitedRegistration);
invitedRegistration.setUserId(userId);
invitedRegistrationDAO.setRegistrationDone(invitedRegistration);
loggingDAO.logAction(INVITED_REGISTRATION_COMPLETED, "user_id=" + userId + " groups=["
+ String.join(",", invitedRegistration.getGroupsPermissions().keySet()) + "]");
}
public List<InvitedRegistrationItem> getInvitedRegistrationsForGroup(GroupEntity group) {
......@@ -202,7 +210,7 @@ public class InvitedRegistrationManager extends UserAwareComponent {
invitedRegistrationDAO.deleteInvitedRegistrationRequest(registrationId, groupId);
loggingDAO.logAction("Deleted invited registration request. "
loggingDAO.logAction(INVITED_REGISTRATION_DELETED, "Deleted invited registration request. "
+ "[request_id=" + registrationId + ", group_id=" + groupId
+ ", group_name=" + group.getName() + "]");
}
......
......@@ -10,6 +10,7 @@ import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.PermissionUtils;
import it.inaf.ia2.gms.authn.RapClient;
import static it.inaf.ia2.gms.persistence.model.ActionType.*;
import it.inaf.ia2.rap.data.RapUser;
import java.util.HashSet;
import java.util.List;
......@@ -49,6 +50,7 @@ public class MembershipManager extends UserAwareComponent {
Permission groupPermission = permissionsManager.getCurrentUserPermission(group);
if (!Permission.includes(groupPermission, Permission.VIEW_MEMBERS)) {
loggingDAO.logAction(UNAUTHORIZED_ACCESS_ATTEMPT, "Attempted to view members of group " + group.getId());
throw new UnauthorizedException("You don't have the permission to view members");
}
......@@ -83,9 +85,10 @@ public class MembershipManager extends UserAwareComponent {
MembershipEntity membership = new MembershipEntity();
membership.setGroupId(group.getId());
membership.setUserId(userId);
membership.setCreatedBy(getCurrentUserId());
membership = membershipsDAO.addMember(membership);
loggingDAO.logAction("Added member, group_id=" + group.getId() + ", user_id=" + userId);
loggingDAO.logAction(MEMBER_ADDED, "Added member, group_id=" + group.getId() + ", user_id=" + userId);
return membership;
}
......@@ -93,12 +96,13 @@ public class MembershipManager extends UserAwareComponent {
public void removeMember(GroupEntity group, String userId) {
verifyUserCanManageMembers(group);
membershipsDAO.removeMembership(group.getId(), userId);
loggingDAO.logAction("Member removed, group_id=" + group.getId() + ", user_id=" + userId);
loggingDAO.logAction(MEMBER_REMOVED, "Member removed, group_id=" + group.getId() + ", user_id=" + userId);
}
private Permission verifyUserCanManageMembers(GroupEntity group) {
Permission permission = permissionsManager.getCurrentUserPermission(group);
if (!Permission.includes(permission, Permission.MANAGE_MEMBERS)) {
loggingDAO.logAction(UNAUTHORIZED_ACCESS_ATTEMPT, "Attempted to manage members of group " + group.getId());
throw new UnauthorizedException("Missing manage members permissions");
}
return permission;
......
......@@ -9,6 +9,8 @@ import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.PermissionUtils;
import it.inaf.ia2.gms.service.PermissionsService;
import it.inaf.ia2.gms.authn.RapClient;
import it.inaf.ia2.gms.persistence.model.ActionType;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.rap.data.RapUser;
import java.util.ArrayList;
import java.util.List;
......@@ -81,22 +83,22 @@ public class PermissionsManager extends UserAwareComponent {
if (currentUserPermission == Permission.MANAGE_MEMBERS && permission == Permission.VIEW_MEMBERS) {
// Automatically assign the VIEW_MEMBERS permission ("Add collaborator" feature)
return permissionsService.addPermission(group, userId, Permission.VIEW_MEMBERS);
return permissionsService.addPermission(group, userId, Permission.VIEW_MEMBERS, getCurrentUserId());
} else if (currentUserPermission == Permission.ADMIN) {
// Admin users can specify a permission
return permissionsService.addPermission(group, userId, permission);
return permissionsService.addPermission(group, userId, permission, getCurrentUserId());
}
throw unauthorizedExceptionSupplier(group).get();
}
public PermissionEntity createOrUpdatePermission(GroupEntity group, String userId, Permission permission) {
verifyUserCanManagePermissions(group);
return permissionsService.createOrUpdatePermission(group, userId, permission);
return permissionsService.createOrUpdatePermission(group, userId, permission, getCurrentUserId());
}
public PermissionEntity updatePermission(GroupEntity group, String userId, Permission permission) {
verifyUserCanManagePermissions(group);
return permissionsService.updatePermission(group, userId, permission);
return permissionsService.updatePermission(group, userId, permission, getCurrentUserId());
}
public void removePermission(GroupEntity group, String userId) {
......@@ -144,16 +146,22 @@ public class PermissionsManager extends UserAwareComponent {
}
private Supplier<UnauthorizedException> unauthorizedExceptionSupplier(GroupEntity group) {
loggingDAO.logAction("Unauthorized attempt to manage permissions [group_id=" + group.getId() + "]");
loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized attempt to manage permissions [group_id=" + group.getId() + "]");
return () -> new UnauthorizedException("You don't have the privileges for managing the requested permission");
}
public List<PermissionEntity> getCurrentUserPermissions() {
return permissionsService.findUserPermissions(getCurrentUserId());
}
public List<PermissionEntity> getCurrentUserPermissions(GroupEntity group) {
return permissionsService.findUserPermissions(group, getCurrentUserId());
}
public Permission getCurrentUserPermission(GroupEntity group) {
List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, getCurrentUserId());
return PermissionUtils.getGroupPermission(group, permissions).orElse(null);
return PermissionUtils.getGroupPermission(group, permissions).orElse(
GroupsService.ROOT.equals(group.getId()) ? Permission.TRAVERSE : null
);
}
}
package it.inaf.ia2.gms.model;
import java.util.Date;
public class GroupNode {
private String groupId;
......@@ -8,6 +10,8 @@ public class GroupNode {
private boolean hasChildren;
private boolean leaf;
private boolean locked;
private Date creationTime;
private String createdBy;
public String getGroupId() {
return groupId;
......@@ -56,4 +60,20 @@ public class GroupNode {
public void setLocked(boolean locked) {
this.locked = locked;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getCreationTime() {
return creationTime;
}
public void setCreationTime(Date creationTime) {
this.creationTime = creationTime;
}
}
package it.inaf.ia2.gms.model.request;
public class GenericSearchRequest extends PaginatedModelRequest {
private String query;
private boolean users;
private boolean groups;
public GenericSearchRequest() {
this.users = true;
this.groups = true;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public boolean isUsers() {
return users;
}
public void setUsers(boolean users) {
this.users = users;
}
public boolean isGroups() {
return groups;
}
public void setGroups(boolean groups) {
this.groups = groups;
}
}
......@@ -8,6 +8,11 @@ public class PaginatedModelRequest {
private int paginatorPage;
private int paginatorPageSize;
public PaginatedModelRequest() {
this.paginatorPage = 1;
this.paginatorPageSize = 20;
}
public int getPaginatorPage() {
return paginatorPage;
}
......
......@@ -9,6 +9,7 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -23,6 +24,8 @@ import org.springframework.stereotype.Component;
@Component
public class GroupsDAO {
private static final String GROUP_COLUMNS = "id, name, path, is_leaf, locked, creation_time, created_by";
@Autowired(required = false)
protected GroupsHook groupsHook;
......@@ -39,14 +42,17 @@ public class GroupsDAO {
groupsHook.beforeCreate(group);
}
String sql = "INSERT INTO gms_group (id, name, path, is_leaf) VALUES (?, ?, ?, ?)";
String sql = "INSERT INTO gms_group (id, name, path, is_leaf, locked, created_by) VALUES (?, ?, ?, ?, ?, ?)";
jdbcTemplate.update(conn -> {
int i = 0;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, group.getId());
ps.setString(2, group.getName());
ps.setObject(3, group.getPath(), Types.OTHER);
ps.setBoolean(4, group.isLeaf());
ps.setString(++i, group.getId());
ps.setString(++i, group.getName());
ps.setObject(++i, group.getPath(), Types.OTHER);
ps.setBoolean(++i, group.isLeaf());
ps.setBoolean(++i, group.isLocked());
ps.setString(++i, group.getCreatedBy());
return ps;
});
......@@ -59,14 +65,16 @@ public class GroupsDAO {
groupsHook.beforeUpdate(group);
}
String sql = "UPDATE gms_group SET name = ?, path = ?, is_leaf = ? WHERE id = ?";
String sql = "UPDATE gms_group SET name = ?, path = ?, is_leaf = ?, locked = ? WHERE id = ?";
jdbcTemplate.update(conn -> {
int i = 0;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, group.getName());
ps.setObject(2, group.getPath(), Types.OTHER);
ps.setBoolean(3, group.isLeaf());
ps.setString(4, group.getId());
ps.setString(++i, group.getName());
ps.setObject(++i, group.getPath(), Types.OTHER);
ps.setBoolean(++i, group.isLeaf());
ps.setBoolean(++i, group.isLocked());
ps.setString(++i, group.getId());
return ps;
});
......@@ -85,7 +93,7 @@ public class GroupsDAO {
public Optional<GroupEntity> findGroupById(String groupId) {
String sql = "SELECT id, name, path, is_leaf, locked from gms_group WHERE id = ?";
String sql = "SELECT " + GROUP_COLUMNS + " from gms_group WHERE id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......@@ -93,12 +101,7 @@ public class GroupsDAO {
return ps;
}, resultSet -> {
if (resultSet.next()) {
GroupEntity group = new GroupEntity();
group.setId(resultSet.getString("id"));
group.setName(resultSet.getString("name"));
group.setPath(resultSet.getString("path"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setLocked(resultSet.getBoolean("locked"));
GroupEntity group = getGroupFromResultSet(resultSet);
return Optional.of(group);
}
return Optional.empty();
......@@ -107,7 +110,7 @@ public class GroupsDAO {
public Optional<GroupEntity> findGroupByPath(String path) {
String sql = "SELECT id, name, is_leaf, locked from gms_group WHERE path = ?";
String sql = "SELECT " + GROUP_COLUMNS + " from gms_group WHERE path = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......@@ -115,12 +118,7 @@ public class GroupsDAO {
return ps;
}, resultSet -> {
if (resultSet.next()) {
GroupEntity group = new GroupEntity();
group.setId(resultSet.getString("id"));
group.setName(resultSet.getString("name"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setLocked(resultSet.getBoolean("locked"));
group.setPath(path);
GroupEntity group = getGroupFromResultSet(resultSet);
return Optional.of(group);
}
return Optional.empty();
......@@ -135,7 +133,7 @@ public class GroupsDAO {
return jdbcTemplate.query(conn -> {
String sql = "SELECT id, name, path, is_leaf, locked from gms_group WHERE id IN (";
String sql = "SELECT " + GROUP_COLUMNS + " from gms_group WHERE id IN (";
sql += String.join(",", identifiers.stream().map(p -> "?").collect(Collectors.toList()));
sql += ")";
......@@ -146,17 +144,7 @@ public class GroupsDAO {
}
return ps;
}, resultSet -> {
List<GroupEntity> groups = new ArrayList<>();
while (resultSet.next()) {
GroupEntity group = new GroupEntity();
group.setId(resultSet.getString("id"));
group.setName(resultSet.getString("name"));
group.setPath(resultSet.getString("path"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setLocked(resultSet.getBoolean("locked"));
groups.add(group);
}
return groups;
return getGroupsFromResultSet(resultSet);
});
}
......@@ -192,7 +180,7 @@ public class GroupsDAO {
public Optional<GroupEntity> findGroupByParentAndName(String parentPath, String childName) {
String sql = "SELECT id, path, is_leaf, locked from gms_group WHERE name = ? AND path ~ ?";
String sql = "SELECT " + GROUP_COLUMNS + " from gms_group WHERE name = ? AND path ~ ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......@@ -201,12 +189,7 @@ public class GroupsDAO {
return ps;
}, resultSet -> {
if (resultSet.next()) {
GroupEntity group = new GroupEntity();
group.setId(resultSet.getString("id"));
group.setName(childName);
group.setPath(resultSet.getString("path"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setLocked(resultSet.getBoolean("locked"));
GroupEntity group = getGroupFromResultSet(resultSet);
return Optional.of(group);
}
return Optional.empty();
......@@ -226,9 +209,9 @@ public class GroupsDAO {
String sql;
if (hasSearchFilter) {
sql = "SELECT id, name, path, is_leaf, locked FROM gms_group WHERE path ~ ? AND name ILIKE ? ORDER BY name";
sql = "SELECT " + GROUP_COLUMNS + " FROM gms_group WHERE path ~ ? AND name ILIKE ? ORDER BY name";
} else {
sql = "SELECT id, name, path, is_leaf, locked FROM gms_group WHERE path ~ ? ORDER BY name";
sql = "SELECT " + GROUP_COLUMNS + " FROM gms_group WHERE path ~ ? ORDER BY name";
}
return jdbcTemplate.query(conn -> {
......@@ -253,7 +236,7 @@ public class GroupsDAO {
public List<GroupEntity> getAllChildren(String path) {
String sql = "SELECT id, name, path, is_leaf, locked FROM gms_group WHERE path <@ ? AND path <> ? ORDER BY nlevel(path) DESC";
String sql = "SELECT " + GROUP_COLUMNS + " FROM gms_group WHERE path <@ ? AND path <> ? ORDER BY nlevel(path) DESC";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......@@ -267,7 +250,7 @@ public class GroupsDAO {
public List<GroupEntity> findGroupsByNames(List<String> names) {
String sql = "SELECT id, name, path, is_leaf, locked from gms_group WHERE name IN ("
String sql = "SELECT " + GROUP_COLUMNS + " from gms_group WHERE name IN ("
+ String.join(",", names.stream().map(g -> "?").collect(Collectors.toList()))
+ ")";
......@@ -286,17 +269,23 @@ public class GroupsDAO {
private List<GroupEntity> getGroupsFromResultSet(ResultSet resultSet) throws SQLException {
List<GroupEntity> groups = new ArrayList<>();
while (resultSet.next()) {
GroupEntity group = new GroupEntity();
group.setId(resultSet.getString("id"));
group.setName(resultSet.getString("name"));
group.setPath(resultSet.getString("path"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setLocked(resultSet.getBoolean("locked"));
groups.add(group);
groups.add(getGroupFromResultSet(resultSet));
}
return groups;
}
private GroupEntity getGroupFromResultSet(ResultSet resultSet) throws SQLException {
GroupEntity group = new GroupEntity();
group.setId(resultSet.getString("id"));
group.setName(resultSet.getString("name"));
group.setPath(resultSet.getString("path"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setLocked(resultSet.getBoolean("locked"));
group.setCreationTime(new Date(resultSet.getDate("creation_time").getTime()));
group.setCreatedBy(resultSet.getString("created_by"));
return group;
}
public Map<String, Boolean> getHasChildrenMap(Set<String> groupIds) {
if (groupIds.isEmpty()) {
......@@ -362,7 +351,7 @@ public class GroupsDAO {
public List<GroupEntity> searchGroups(String searchText) {
String sql = "SELECT id, name, path, is_leaf, locked from gms_group WHERE name ILIKE ?";
String sql = "SELECT " + GROUP_COLUMNS + " from gms_group WHERE name ILIKE ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......
......@@ -100,9 +100,9 @@ public class InvitedRegistrationDAO {
return Optional.ofNullable(registration);
}
public void setRegistrationUser(InvitedRegistration invitedRegistration) {
public void setRegistrationDone(InvitedRegistration invitedRegistration) {
String sql = "UPDATE invited_registration_request SET \"user\" = ? WHERE id = ?";
String sql = "UPDATE invited_registration_request SET \"user\" = ?, done = true WHERE id = ?";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......@@ -112,17 +112,6 @@ public class InvitedRegistrationDAO {
});
}
public void setRegistrationDone(InvitedRegistration invitedRegistration) {
String sql = "UPDATE invited_registration_request SET done = true WHERE id = ?";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, invitedRegistration.getId());
return ps;
});
}
/**
* Called before deleting a group.
*/
......
......@@ -59,10 +59,10 @@ public class JoinDAO {
private void addPermissions(Set<PermissionEntity> permissionsToAdd) {
String sql = "INSERT INTO gms_permission (group_id, user_id, permission, group_path) VALUES "
+ String.join(", ", Collections.nCopies(permissionsToAdd.size(), "(?, ?, ?, ?)")) + "\n"
String sql = "INSERT INTO gms_permission (group_id, user_id, permission, group_path, set_by) VALUES "
+ String.join(", ", Collections.nCopies(permissionsToAdd.size(), "(?, ?, ?, ?, ?)")) + "\n"
+ "ON CONFLICT (group_id, user_id) DO UPDATE\n"
+ "SET permission = EXCLUDED.permission";
+ "SET permission = EXCLUDED.permission, set_by = EXCLUDED.set_by, update_time = NOW()";
LOG.trace("Executing {}", sql);
......@@ -74,6 +74,7 @@ public class JoinDAO {
ps.setString(++i, permission.getUserId());
ps.setObject(++i, permission.getPermission().toString(), Types.OTHER);
ps.setObject(++i, permission.getGroupPath(), Types.OTHER);
ps.setString(++i, permission.getSetBy());
}
return ps;
});
......
package it.inaf.ia2.gms.persistence;
import it.inaf.ia2.gms.persistence.model.ActionType;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.PreparedStatement;
......@@ -52,19 +53,20 @@ public class LoggingDAO {
return sw.toString();
}
public void logAction(String action) {
logAction(action, request);
public void logAction(ActionType type, String action) {
logAction(type, action, request);
}
public void logAction(String action, HttpServletRequest request) {
public void logAction(ActionType type, String description, HttpServletRequest request) {
try {
String sql = "INSERT INTO audit_log (\"user\", action, ip_address) VALUES (?, ?, ?)";
String sql = "INSERT INTO audit_log (\"user\", action_type, description, ip_address) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
int i = 0;
ps.setString(++i, getUser(request));
ps.setString(++i, action);
ps.setString(++i, type.toString());
ps.setString(++i, description);
ps.setString(++i, getIPAddress(request));
return ps;
});
......
......@@ -3,9 +3,12 @@ package it.inaf.ia2.gms.persistence;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.sql.DataSource;
......@@ -25,27 +28,24 @@ public class MembershipsDAO {
public List<MembershipEntity> findByGroup(String groupId) {
String sql = "SELECT user_id FROM gms_membership WHERE group_id = ?";
String sql = "SELECT user_id, group_id, created_by, creation_time FROM gms_membership WHERE group_id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, groupId);
return ps;
}, resultSet -> {
List<MembershipEntity> members = new ArrayList<>();
while (resultSet.next()) {
MembershipEntity membership = new MembershipEntity();
membership.setGroupId(groupId);
membership.setUserId(resultSet.getString("user_id"));
members.add(membership);
}
return members;
return getMembershipsFromResultSet(resultSet);
});
}
public List<MembershipEntity> findByGroups(List<String> groupIds) {
String sql = "SELECT user_id, group_id FROM gms_membership WHERE group_id IN ("
if (groupIds.isEmpty()) {
return new ArrayList<>();
}
String sql = "SELECT user_id, group_id, created_by, creation_time FROM gms_membership WHERE group_id IN ("
+ String.join(",", Collections.nCopies(groupIds.size(), "?")) + ")";
return jdbcTemplate.query(conn -> {
......@@ -56,25 +56,36 @@ public class MembershipsDAO {
}
return ps;
}, resultSet -> {
List<MembershipEntity> members = new ArrayList<>();
while (resultSet.next()) {
MembershipEntity membership = new MembershipEntity();
membership.setGroupId(resultSet.getString("group_id"));
membership.setUserId(resultSet.getString("user_id"));
members.add(membership);
}
return members;
return getMembershipsFromResultSet(resultSet);
});
}
private List<MembershipEntity> getMembershipsFromResultSet(ResultSet resultSet) throws SQLException {
List<MembershipEntity> members = new ArrayList<>();
while (resultSet.next()) {
members.add(getMembershipEntityFromResultSet(resultSet));
}
return members;
}
private MembershipEntity getMembershipEntityFromResultSet(ResultSet resultSet) throws SQLException {
MembershipEntity membership = new MembershipEntity();
membership.setGroupId(resultSet.getString("group_id"));
membership.setUserId(resultSet.getString("user_id"));
membership.setUserId(resultSet.getString("user_id"));
membership.setCreatedBy(resultSet.getString("created_by"));
membership.setCreationTime(new Date(resultSet.getDate("creation_time").getTime()));
return membership;
}
public List<GroupEntity> getUserMemberships(String userId) {
return getUserMemberships(userId, null);
}
public List<GroupEntity> getUserMemberships(String userId, String parentPath) {
String sql = "SELECT g.id, g.name, g.path, g.is_leaf FROM "
+ " gms_membership m "
String sql = "SELECT g.id, g.name, g.path, g.is_leaf, g.creation_time, g.created_by "
+ " FROM gms_membership m "
+ " JOIN gms_group g ON g.id = m.group_id"
+ " WHERE m.user_id = ?";
if (parentPath != null) {
......@@ -99,6 +110,8 @@ public class MembershipsDAO {
group.setName(resultSet.getString("name"));
group.setPath(resultSet.getString("path"));
group.setLeaf(resultSet.getBoolean("is_leaf"));
group.setCreationTime(new Date(resultSet.getDate("creation_time").getTime()));
group.setCreatedBy(resultSet.getString("created_by"));
memberships.add(group);
}
return memberships;
......@@ -124,13 +137,14 @@ public class MembershipsDAO {
public MembershipEntity addMember(MembershipEntity membership) {
String sql = "INSERT INTO gms_membership (group_id, user_id) VALUES (?, ?)\n"
String sql = "INSERT INTO gms_membership (group_id, user_id, created_by) VALUES (?, ?, ?)\n"
+ "ON CONFLICT (group_id, user_id) DO NOTHING";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, membership.getGroupId());
ps.setString(2, membership.getUserId());
ps.setString(3, membership.getCreatedBy());
return ps;
});
......
......@@ -3,8 +3,11 @@ package it.inaf.ia2.gms.persistence;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -16,6 +19,8 @@ import org.springframework.stereotype.Component;
@Component
public class PermissionsDAO {
private static final String PERMISSION_COLUMNS = "group_id, user_id, permission, group_path, update_time, set_by";
private final JdbcTemplate jdbcTemplate;
@Autowired
......@@ -25,34 +30,37 @@ public class PermissionsDAO {
public PermissionEntity createOrUpdatePermission(PermissionEntity userPermission) {
String sql = "INSERT INTO gms_permission(group_id, user_id, permission, group_path) VALUES(?, ?, ?, ?)\n"
String sql = "INSERT INTO gms_permission(group_id, user_id, permission, group_path, set_by) VALUES(?, ?, ?, ?, ?)\n"
+ "ON CONFLICT (group_id, user_id) DO UPDATE\n"
+ "SET permission = EXCLUDED.permission";
+ "SET permission = EXCLUDED.permission, set_by = EXCLUDED.set_by, update_time = NOW()";
jdbcTemplate.update(conn -> {
int i = 0;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userPermission.getGroupId());
ps.setString(2, userPermission.getUserId());
ps.setObject(3, userPermission.getPermission().toString(), Types.OTHER);
ps.setObject(4, userPermission.getGroupPath(), Types.OTHER);
ps.setString(++i, userPermission.getGroupId());
ps.setString(++i, userPermission.getUserId());
ps.setObject(++i, userPermission.getPermission().toString(), Types.OTHER);
ps.setObject(++i, userPermission.getGroupPath(), Types.OTHER);
ps.setString(++i, userPermission.getSetBy());
return ps;
});
return userPermission;
}
public PermissionEntity updatePermission(PermissionEntity userPermission, Permission newPermission) {
String sql = "UPDATE gms_permission SET permission = ? WHERE group_id = ? AND user_id = ? AND group_path = ?";
public PermissionEntity updatePermission(PermissionEntity userPermission) {
userPermission.setPermission(newPermission);
String sql = "UPDATE gms_permission SET permission = ?, set_by = ?, update_time = NOW() "
+ " WHERE group_id = ? AND user_id = ? AND group_path = ?";
jdbcTemplate.update(conn -> {
int i = 0;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, userPermission.getPermission().toString(), Types.OTHER);
ps.setString(2, userPermission.getGroupId());
ps.setString(3, userPermission.getUserId());
ps.setObject(4, userPermission.getGroupPath(), Types.OTHER);
ps.setObject(++i, userPermission.getPermission().toString(), Types.OTHER);
ps.setString(++i, userPermission.getSetBy());
ps.setString(++i, userPermission.getGroupId());
ps.setString(++i, userPermission.getUserId());
ps.setObject(++i, userPermission.getGroupPath(), Types.OTHER);
return ps;
});
......@@ -61,23 +69,14 @@ public class PermissionsDAO {
public List<PermissionEntity> findUserPermissions(String userId) {
String sql = "SELECT group_id, permission, group_path FROM gms_permission WHERE user_id = ?";
String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE user_id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userId);
return ps;
}, resultSet -> {
List<PermissionEntity> permissions = new ArrayList<>();
while (resultSet.next()) {
PermissionEntity permission = new PermissionEntity();
permission.setGroupId(resultSet.getString("group_id"));
permission.setUserId(userId);
permission.setPermission(Permission.valueOf(resultSet.getString("permission")));
permission.setGroupPath(resultSet.getString("group_path"));
permissions.add(permission);
}
return permissions;
return getPermissionsFromResultSet(resultSet);
});
}
......@@ -87,7 +86,7 @@ public class PermissionsDAO {
*/
public List<PermissionEntity> findUserPermissions(String userId, String path) {
String sql = "SELECT group_id, permission, group_path FROM gms_permission WHERE user_id = ?\n"
String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE user_id = ?\n"
+ "AND (group_path <@ ? OR group_path @> ?)";
return jdbcTemplate.query(conn -> {
......@@ -97,22 +96,13 @@ public class PermissionsDAO {
ps.setObject(3, path, Types.OTHER);
return ps;
}, resultSet -> {
List<PermissionEntity> permissions = new ArrayList<>();
while (resultSet.next()) {
PermissionEntity permission = new PermissionEntity();
permission.setGroupId(resultSet.getString("group_id"));
permission.setUserId(userId);
permission.setPermission(Permission.valueOf(resultSet.getString("permission")));
permission.setGroupPath(resultSet.getString("group_path"));
permissions.add(permission);
}
return permissions;
return getPermissionsFromResultSet(resultSet);
});
}
public Optional<PermissionEntity> findPermissionEntity(String groupId, String userId) {
String sql = "SELECT group_path, permission FROM gms_permission WHERE group_id = ? AND user_id = ?";
String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE group_id = ? AND user_id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
......@@ -121,12 +111,7 @@ public class PermissionsDAO {
return ps;
}, resultSet -> {
if (resultSet.next()) {
PermissionEntity permissionEntity = new PermissionEntity();
permissionEntity.setGroupId(groupId);
permissionEntity.setUserId(userId);
permissionEntity.setPermission(Permission.valueOf(resultSet.getString("permission")));
permissionEntity.setGroupPath(resultSet.getString("group_path"));
return Optional.of(permissionEntity);
return Optional.of(getPermissionEntityFromResultSet(resultSet));
}
return Optional.empty();
});
......@@ -134,26 +119,36 @@ public class PermissionsDAO {
public List<PermissionEntity> getGroupsPermissions(String groupId) {
String sql = "SELECT user_id, permission, group_path FROM gms_permission WHERE group_id = ?";
String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE group_id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, groupId);
return ps;
}, resultSet -> {
List<PermissionEntity> permissions = new ArrayList<>();
while (resultSet.next()) {
PermissionEntity permission = new PermissionEntity();
permission.setGroupId(groupId);
permission.setUserId(resultSet.getString("user_id"));
permission.setPermission(Permission.valueOf(resultSet.getString("permission")));
permission.setGroupPath(resultSet.getString("group_path"));
permissions.add(permission);
}
return permissions;
return getPermissionsFromResultSet(resultSet);
});
}
private List<PermissionEntity> getPermissionsFromResultSet(ResultSet resultSet) throws SQLException {
List<PermissionEntity> permissions = new ArrayList<>();
while (resultSet.next()) {
permissions.add(getPermissionEntityFromResultSet(resultSet));
}
return permissions;
}
private PermissionEntity getPermissionEntityFromResultSet(ResultSet resultSet) throws SQLException {
PermissionEntity permission = new PermissionEntity();
permission.setGroupId(resultSet.getString("group_id"));
permission.setUserId(resultSet.getString("user_id"));
permission.setPermission(Permission.valueOf(resultSet.getString("permission")));
permission.setGroupPath(resultSet.getString("group_path"));
permission.setSetBy(resultSet.getString("set_by"));
permission.setUpdateTime(new Date(resultSet.getDate("update_time").getTime()));
return permission;
}
public void deletePermission(String groupId, String userId) {
String sql = "DELETE FROM gms_permission WHERE group_id = ? AND user_id = ?";
......
package it.inaf.ia2.gms.persistence.model;
public enum ActionType {
GROUP_CREATED,
GROUP_DELETED,
GROUP_UPDATED,
MEMBER_ADDED,
MEMBER_REMOVED,
PERMISSION_ADDED,
PERMISSION_UPDATED,
PERMISSION_REMOVED,
JOIN,
INVITED_REGISTRATION_ADDED,
INVITED_REGISTRATION_OPENED,
INVITED_REGISTRATION_DELETED,
INVITED_REGISTRATION_COMPLETED,
API_CALL,
UNAUTHORIZED_ACCESS_ATTEMPT
}