easycare.web.user.UsersPermissionsController.java Source code

Java tutorial

Introduction

Here is the source code for easycare.web.user.UsersPermissionsController.java

Source

package easycare.web.user;

import easycare.model.Location;
import easycare.model.User;
import easycare.model.UserLocationAccess;
import easycare.model.security.Role;
import easycare.model.security.RoleEnum;
import easycare.service.RoleService;
import easycare.service.SessionSecurityService;
import easycare.service.UserService;
import easycare.service.springsecurity.EasyCareUserDetails;
import easycare.web.audit.event.EditUserFailedValidationEvent;
import easycare.web.filter.FlashScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.List;
import java.util.Set;

import static org.apache.commons.lang.StringUtils.isBlank;

@Controller
@PreAuthorize("hasAuthority('CAN_MANAGE_ORGANISATION_USERS')")
@RequestMapping("/admin/users/{user}/permissions")
public class UsersPermissionsController {

    private static final String CAN_REMOVE_ADMIN_ROLE = "canRemoveAdminRole";

    public static final String CAN_ASSIGN_SPECIFIC_LOCATION = "canAssignSpecificLocation";
    public static final String USER_PERMISSIONS_VIEW = "user-view-permissions";
    public static final String USER_PERMISSIONS_EDIT = "user-edit-permissions";
    public static final String INTERPRETING_PHYSICIAN_ERROR = "user.permissions.edit.error.interpreting.physician";
    public static final String USER_ROLES = "userRoles";

    @Autowired
    private FlashScope flashScope;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private SessionSecurityService sessionSecurityService;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @PreAuthorize("hasPermission(#user, 'MANAGE')")
    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView showUserPermissions(@PathVariable("user") User user) {
        Set<Role> roles = roleService.findUserViewableRolesAndSubRoles(user);

        ModelAndView mav = new ModelAndView(USER_PERMISSIONS_VIEW, "user", user);
        mav.addObject(USER_ROLES, roles);
        return mav;
    }

    @PreAuthorize("hasPermission(#user, 'MANAGE')")
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView showEditUserPermissionsForm(@PathVariable("user") User user) {
        ModelAndView mav = new ModelAndView(USER_PERMISSIONS_EDIT);
        populateFormValues(mav, user);
        mav.addObject(UserController.USER_FORM, new UserPermissionsForm(user));
        return mav;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @PreAuthorize("hasPermission(#user, 'MANAGE')")
    public ModelAndView editUserPermissions(@PathVariable("user") User user,
            @ModelAttribute(UserController.USER_FORM) @Valid UserPermissionsForm form, BindingResult result) {

        validateInterpretingPhysicianFields(user, form, result);

        if (result.hasErrors()) {
            fireEditUserFailedValidationEvent(user.getUsername(), result);
            ModelAndView mav = new ModelAndView(USER_PERMISSIONS_EDIT, UserController.USER_FORM, form);
            populateFormValues(mav, user);
            return mav;
        }

        checkInvalidRolesAndLocations(form);

        userService.updatePermissions(user.getId(), form.getLocations(), form.getUserRoles());
        flashScope.addMessage(UserBasicDetailsController.EDIT_USER_SUCCESS);
        return new ModelAndView("redirect:/admin/users/" + user.getId() + "/permissions");
    }

    private void fireEditUserFailedValidationEvent(String username, Errors errors) {
        Authentication authentication = sessionSecurityService.getAuthentication();
        applicationEventPublisher.publishEvent(new EditUserFailedValidationEvent(authentication, username, errors));
    }

    private void checkInvalidRolesAndLocations(UserPermissionsForm form) {
        if (form.getUserRoles().contains(RoleEnum.ROLE_ADMIN)
                && form.getUserLocationAccess() == UserLocationAccess.SPECIFIC) {
            throw new IllegalArgumentException("admins cannot be assigned to specific locations");
        }
        User currentUser = sessionSecurityService.getCurrentUser();
        form.validateEachRoleAndLocation(userRoles(), currentUser.getAssignedLocations());
    }

    private void populateFormValues(ModelAndView mav, User user) {
        EasyCareUserDetails currentUserDetails = sessionSecurityService.getCurrentUserDetails();
        Set<Role> roles = roleService.findUserViewableRolesAndSubRoles(currentUserDetails);
        mav.addObject(UserController.ROLES, roles);
        mav.addObject(UserController.LOCATIONS, userLocations());
        mav.addObject(CAN_REMOVE_ADMIN_ROLE, canRemoveAdminRole(user));
        mav.addObject(CAN_ASSIGN_SPECIFIC_LOCATION, canAssignSpecificLocation(user));
    }

    private boolean canAssignSpecificLocation(User user) {
        return !user.isAdmin();
    }

    private List<RoleEnum> userRoles() {
        return sessionSecurityService.getCurrentUserDetails().getAssignableRoles();
    }

    private List<Location> userLocations() {
        return sessionSecurityService.getCurrentUser().getAssignedLocations();
    }

    private boolean canRemoveAdminRole(User user) {
        return !sessionSecurityService.getCurrentUser().equals(user);
    }

    private void validateInterpretingPhysicianFields(User user, UserPermissionsForm form, BindingResult result) {
        if (form.isInterpretingPhysician() && (isBlank(user.getEmail()) || isBlank(user.getLicenseNumber()))) {
            result.rejectValue(USER_ROLES, INTERPRETING_PHYSICIAN_ERROR);
        }
    }

}