Commit 467aa40a authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Refactoring of the business layer; Removed Basic-Auth web service

parent c5de9aa2
Loading
Loading
Loading
Loading
+0 −118
Original line number Diff line number Diff line
package it.inaf.ia2.gms.controller;

import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.model.request.AddMemberWsRequest;
import it.inaf.ia2.gms.model.request.AddPermissionWsRequest;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.gms.service.MembersService;
import it.inaf.ia2.gms.service.PermissionsService;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Controller for programmatic access using registered clients.
 */
@RestController
@RequestMapping("/ws/basic")
public class BasicAuthWebServiceController {

    @Autowired
    private GroupsService groupsService;

    @Autowired
    private MembersService membersService;

    @Autowired
    private PermissionsService permissionsService;

    /**
     * Creates a group and its ancestors if they are missing. It doesn't fail if
     * the last group already exists.
     */
    @PostMapping(value = "/group", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<GroupEntity> createGroup(@RequestBody List<String> names) {

        GroupEntity group = groupsService.getRoot();

        for (String name : names) {
            Optional<GroupEntity> optGroup = groupsService.findGroupByParentAndName(group, name);
            if (optGroup.isPresent()) {
                group = optGroup.get();
            } else {
                group = groupsService.addGroup(group, name, false);
            }
        }

        return new ResponseEntity<>(group, HttpStatus.CREATED);
    }

    @DeleteMapping("/group")
    public ResponseEntity<?> deleteGroupByPath(@RequestParam("names") String[] names) {

        GroupEntity groupToDelete = getGroupByNames(Arrays.asList(names));

        groupsService.deleteGroup(groupToDelete);

        return ResponseEntity.noContent().build();
    }

    @PostMapping(value = "/member", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<MembershipEntity> addMember(@RequestBody AddMemberWsRequest request) {

        GroupEntity group = getGroupByNames(request.getNames());

        MembershipEntity membership = membersService.addMember(group.getId(), request.getUserId());

        return new ResponseEntity<>(membership, HttpStatus.CREATED);
    }

    @DeleteMapping("/member")
    public ResponseEntity<?> removeMember(@RequestParam("names") String[] names, @RequestParam("userId") String userId) {

        GroupEntity group = getGroupByNames(Arrays.asList(names));

        membersService.removeMember(group.getId(), userId);

        return ResponseEntity.noContent().build();
    }

    @PostMapping(value = "/permission", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<PermissionEntity> addPermission(@Valid @RequestBody AddPermissionWsRequest request) {

        GroupEntity group = getGroupByNames(request.getNames());

        PermissionEntity newPermission = permissionsService.addPermission(group, request.getUserId(), request.getPermission());

        return new ResponseEntity<>(newPermission, HttpStatus.CREATED);
    }

    @DeleteMapping("/permission")
    public ResponseEntity<?> deletePermission(@RequestParam("names") String[] names, @RequestParam("userId") String userId) {

        GroupEntity group = getGroupByNames(Arrays.asList(names));

        permissionsService.removePermission(group, userId);

        return ResponseEntity.noContent().build();
    }

    private GroupEntity getGroupByNames(List<String> names) {
        return groupsService.findGroupByNames(names)
                .orElseThrow(() -> new BadRequestException("Unable to find requested group"));
    }
}
+7 −43
Original line number Diff line number Diff line
package it.inaf.ia2.gms.controller;

import it.inaf.ia2.gms.authn.SessionData;
import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.manager.GroupsManager;
import it.inaf.ia2.gms.model.request.AddGroupRequest;
import it.inaf.ia2.gms.model.GroupNode;
import it.inaf.ia2.gms.model.response.PaginatedData;
import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.request.DeleteGroupRequest;
import it.inaf.ia2.gms.model.request.GroupsRequest;
import it.inaf.ia2.gms.model.request.RenameGroupRequest;
import it.inaf.ia2.gms.model.request.SearchFilterRequest;
import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.gms.service.GroupsTreeBuilder;
import it.inaf.ia2.gms.service.PermissionsService;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
@@ -36,10 +32,7 @@ public class GroupsController {
    private SessionData session;

    @Autowired
    private PermissionsService permissionsService;

    @Autowired
    private GroupsService groupsService;
    private GroupsManager groupsManager;

    @Autowired
    private GroupsTreeBuilder groupsTreeBuilder;
@@ -47,14 +40,11 @@ public class GroupsController {
    @Autowired
    private GroupsTabResponseBuilder groupsTabResponseBuilder;

    @Autowired
    private LoggingDAO loggingDAO;

    @GetMapping(value = "/groups", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> getGroupsTab(@Valid GroupsRequest request) {
        if (request.isOnlyPanel()) {
            // Only groupsPanel
            GroupEntity group = groupsService.getGroupById(request.getGroupId());
            GroupEntity group = groupsManager.getGroupById(request.getGroupId());
            return ResponseEntity.ok(getGroupsPanel(group, request));
        } else {
            // Complete GroupsTabResponse
@@ -65,15 +55,7 @@ public class GroupsController {
    @PostMapping(value = "/group", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<PaginatedData<GroupNode>> createGroup(@Valid @RequestBody AddGroupRequest request) {

        GroupEntity parent = groupsService.getGroupById(request.getParentGroupId());

        if (permissionsService.getUserPermissionForGroup(parent, session.getUserId()) != Permission.ADMIN) {
            loggingDAO.logAction("Unauthorized create group request, group_name=" + request.getNewGroupName());
            throw new UnauthorizedException("Missing admin permission");
        }

        groupsService.addGroup(parent, request.getNewGroupName(), request.isLeaf());
        loggingDAO.logAction("Added group: parent_path=" + parent.getPath() + ", group_name=" + request.getNewGroupName());
        GroupEntity parent = groupsManager.createGroup(request.getParentGroupId(), request.getNewGroupName(), request.isLeaf());

        PaginatedData<GroupNode> groupsPanel = getGroupsPanel(parent, request);

@@ -81,19 +63,9 @@ public class GroupsController {
    }

    @PutMapping(value = "/group/{groupId}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<PaginatedData<GroupNode>> renameGroup(@PathVariable("groupId") String groupId, @Valid @RequestBody RenameGroupRequest request) {
    public ResponseEntity<PaginatedData<GroupNode>> updateGroup(@PathVariable("groupId") String groupId, @Valid @RequestBody RenameGroupRequest request) {

        GroupEntity group = groupsService.getGroupById(groupId);

        if (permissionsService.getUserPermissionForGroup(group, session.getUserId()) != Permission.ADMIN) {
            loggingDAO.logAction("Unauthorized rename group request, group_id=" + groupId);
            throw new UnauthorizedException("Missing admin permission");
        }

        GroupEntity renamedGroup = groupsService.renameGroup(group, request.getNewGroupName(), request.isLeaf());
        loggingDAO.logAction("Group renamed, group_id=" + groupId + ", new name: " + request.getNewGroupName());

        GroupEntity parent = groupsService.getGroupByPath(renamedGroup.getParentPath());
        GroupEntity parent = groupsManager.updateGroup(groupId, request.getNewGroupName(), request.isLeaf());

        PaginatedData<GroupNode> groupsPanel = getGroupsPanel(parent, request);

@@ -103,15 +75,7 @@ public class GroupsController {
    @DeleteMapping(value = "/group/{groupId}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> deleteGroup(@PathVariable("groupId") String groupId, DeleteGroupRequest request) {

        GroupEntity group = groupsService.getGroupById(groupId);

        if (permissionsService.getUserPermissionForGroup(group, session.getUserId()) != Permission.ADMIN) {
            loggingDAO.logAction("Unauthorized delete group request, group_id=" + groupId);
            throw new UnauthorizedException("Missing admin permission");
        }

        GroupEntity parent = groupsService.deleteGroup(group);
        loggingDAO.logAction("Group deleted, group_id=" + groupId);
        GroupEntity parent = groupsManager.deleteGroup(groupId);
        PaginatedData<GroupNode> groupsPanel = getGroupsPanel(parent, request);

        return ResponseEntity.ok(groupsPanel);
+9 −4
Original line number Diff line number Diff line
package it.inaf.ia2.gms.controller;

import it.inaf.ia2.gms.authn.SessionData;
import it.inaf.ia2.gms.manager.GroupsManager;
import it.inaf.ia2.gms.manager.PermissionsManager;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.request.GroupsRequest;
import it.inaf.ia2.gms.model.response.GroupsTabResponse;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.gms.service.GroupsTreeBuilder;
import it.inaf.ia2.gms.service.PermissionsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@@ -18,7 +19,10 @@ public class GroupsTabResponseBuilder {
    private SessionData session;

    @Autowired
    private PermissionsService permissionsService;
    private PermissionsManager permissionsManager;

    @Autowired
    private GroupsManager groupsManager;

    @Autowired
    private GroupsService groupsService;
@@ -29,13 +33,14 @@ public class GroupsTabResponseBuilder {
    public GroupsTabResponse getGroupsTab(GroupsRequest request) {

        GroupEntity group = groupsService.getGroupById(request.getGroupId());
        groupsManager.verifyUserCanReadGroup(group);

        GroupsTabResponse response = new GroupsTabResponse();

        response.setBreadcrumbs(groupsService.getBreadcrumbs(group.getPath()));

        Permission currentNodePermissions = permissionsService.getUserPermissionForGroup(group, session.getUserId());
        response.setPermission(currentNodePermissions);
        Permission permission = permissionsManager.getCurrentUserPermission(group);
        response.setPermission(permission);

        response.setGroupsPanel(groupsListBuilder.listSubGroups(group, request, session.getUserId()));

+39 −59
Original line number Diff line number Diff line
@@ -2,19 +2,17 @@ package it.inaf.ia2.gms.controller;

import it.inaf.ia2.gms.authn.RapPrincipal;
import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.manager.GroupsManager;
import it.inaf.ia2.gms.manager.MembershipManager;
import it.inaf.ia2.gms.manager.PermissionsManager;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.GroupsDAO;
import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.MembershipsDAO;
import it.inaf.ia2.gms.persistence.PermissionsDAO;
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.JoinService;
import it.inaf.ia2.gms.service.MembersService;
import it.inaf.ia2.gms.service.PermissionUtils;
import it.inaf.ia2.gms.service.PermissionsService;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.Principal;
@@ -43,9 +41,6 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/ws/jwt")
public class JWTWebServiceController {

    @Autowired
    private MembershipsDAO membershipsDAO;

    @Autowired
    private JoinService joinService;

@@ -53,27 +48,27 @@ public class JWTWebServiceController {
    private GroupsDAO groupsDAO;

    @Autowired
    private GroupsService groupsService;
    private GroupsManager groupsManager;

    @Autowired
    private MembersService membersService;
    private GroupsService groupsService;

    @Autowired
    private PermissionsService permissionsService;
    private MembershipManager membershipManager;

    @Autowired
    private PermissionsDAO permissionsDAO;
    private PermissionsManager permissionsManager;

    @Autowired
    private LoggingDAO loggingDAO;
    private PermissionsDAO permissionsDAO;

    /**
     * This endpoint is compliant with the IVOA GMS standard.
     */
    @GetMapping(value = "/search", produces = MediaType.TEXT_PLAIN_VALUE)
    public void getGroups(Principal principal, HttpServletResponse response) throws IOException {
    public void getGroups(HttpServletResponse response) throws IOException {

        List<GroupEntity> memberships = membershipsDAO.getUserMemberships(principal.getName());
        List<GroupEntity> memberships = membershipManager.getCurrentUserMemberships();

        List<String> names = getGroupsNames(memberships);

@@ -92,13 +87,11 @@ public class JWTWebServiceController {
     * extension (thanks https://stackoverflow.com/a/16333149/771431)
     */
    @GetMapping(value = "/search/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE)
    public void isMemberOf(@PathVariable("group") String group, Principal principal, HttpServletResponse response) throws IOException {

        String userId = principal.getName();
    public void isMemberOf(@PathVariable("group") String group, HttpServletResponse response) throws IOException {

        List<String> groupNames = extractGroupNames(group);

        boolean isMember = membershipsDAO.isMemberOf(userId, "ROOT");
        boolean isMember = membershipManager.isCurrentUserMemberOf("ROOT");
        if (!isMember) {
            String parentPath = ""; // starting from ROOT
            for (String groupName : groupNames) {
@@ -106,7 +99,7 @@ public class JWTWebServiceController {
                if (optionalGroup.isPresent()) {
                    GroupEntity groupEntity = optionalGroup.get();
                    parentPath = groupEntity.getPath();
                    isMember = membershipsDAO.isMemberOf(userId, groupEntity.getId());
                    isMember = membershipManager.isCurrentUserMemberOf(groupEntity.getId());
                    if (isMember) {
                        break;
                    }
@@ -156,57 +149,51 @@ public class JWTWebServiceController {
        }
    }

    /**
     * Creates a group and its ancestors if they are missing. It doesn't fail if
     * the last group already exists.
     */
    @PostMapping(value = "/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE)
    public void createGroup(@PathVariable("group") String group, Principal principal, HttpServletRequest request, HttpServletResponse response) throws IOException {
    public void createGroup(@PathVariable("group") String groupParam, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String userId = principal.getName();

        List<String> groupNames = extractGroupNames(group);
        GroupEntity parent = getParentFromNames(groupNames);

        String newGroupName = groupNames.get(groupNames.size() - 1);

        if (permissionsService.getUserPermissionForGroup(parent, userId) != Permission.ADMIN) {
            loggingDAO.logAction("Unauthorized create group request, group_name=" + newGroupName);
            throw new UnauthorizedException("Missing admin permission");
        }
        List<String> groupNames = extractGroupNames(groupParam);

        String leafParam = request.getParameter("leaf");
        boolean leaf = leafParam == null ? false : Boolean.valueOf(leafParam);

        groupsService.addGroup(parent, newGroupName, leaf);
        loggingDAO.logAction("Added group: parent_path=" + parent.getPath() + ", group_name=" + newGroupName);
        GroupEntity group = groupsManager.getRoot();
        for (int i = 0; i < groupNames.size(); i++) {
            String name = groupNames.get(i);
            Optional<GroupEntity> optGroup = groupsService.findGroupByParentAndName(group, name);
            if (optGroup.isPresent()) {
                group = optGroup.get();
            } else {
                group = groupsManager.createGroup(group, name, i == groupNames.size() - 1 ? leaf : false);
            }
        }

        response.setStatus(HttpServletResponse.SC_CREATED);
        try (PrintWriter pw = new PrintWriter(response.getOutputStream())) {
            pw.println(group);
            pw.println(groupParam);
        }
    }

    @PostMapping(value = {"/membership/{group:.+}", "/membership"}, produces = MediaType.TEXT_PLAIN_VALUE)
    public void addMember(@PathVariable("group") Optional<String> group, Principal principal, HttpServletRequest request, HttpServletResponse response) throws IOException {

        GroupEntity groupEntity = getGroupFromNames(extractGroupNames(group));

        String userId = principal.getName();
        membersService.verifyUserCanManageMembers(groupEntity, userId);

        String targetUserId = request.getParameter("user_id");
        if (targetUserId == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing user_id parameter");
            return;
        }
        membersService.addMember(groupEntity.getId(), targetUserId);
        loggingDAO.logAction("Added member, group_id=" + groupEntity.getId() + ", user_id=" + targetUserId);
    }

    @PostMapping(value = {"/permission/{group:.+}", "/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE)
    public void addPermission(@PathVariable("group") Optional<String> groupNames, Principal principal, HttpServletRequest request, HttpServletResponse response) throws IOException {
        GroupEntity groupEntity = getGroupFromNames(extractGroupNames(group));

        GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames));
        membershipManager.addMember(groupEntity, targetUserId);
    }

        String userId = principal.getName();
        permissionsService.verifyUserCanManagePermissions(groupEntity, userId);
    @PostMapping(value = {"/permission/{group:.+}", "/permission/"}, produces = MediaType.TEXT_PLAIN_VALUE)
    public void addPermission(@PathVariable("group") Optional<String> groupNames, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String targetUserId = request.getParameter("user_id");
        if (targetUserId == null) {
@@ -218,10 +205,10 @@ public class JWTWebServiceController {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing permission parameter");
            return;
        }
        Permission permission = Permission.valueOf(permissionParam);
        permissionsService.addPermission(groupEntity, targetUserId, permission);
        loggingDAO.logAction("Permission added, group_id=" + groupEntity.getId() + ", user_id="
                + targetUserId + ", permission=" + permission);

        GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames));

        permissionsManager.addPermission(groupEntity, targetUserId, Permission.valueOf(permissionParam));
    }

    private GroupEntity getGroupFromNames(List<String> groupNames) {
@@ -231,13 +218,6 @@ public class JWTWebServiceController {
        return getGroupFromNamesAndIndex(groupNames, groupNames.size() - 1);
    }

    private GroupEntity getParentFromNames(List<String> groupNames) {
        if (groupNames.size() == 1) {
            return getRoot();
        }
        return getGroupFromNamesAndIndex(groupNames, groupNames.size() - 2);
    }

    private GroupEntity getGroupFromNamesAndIndex(List<String> groupNames, int index) {
        String parentPath = ""; // starting from ROOT
        GroupEntity group = null;
+20 −37

File changed.

Preview size limit exceeded, changes collapsed.

Loading