easycare.web.user.UserController.java Source code

Java tutorial

Introduction

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

Source

package easycare.web.user;

import easycare.common.ApplicationMessageSource;
import easycare.common.Clock;
import easycare.model.Country;
import easycare.model.Location;
import easycare.model.State;
import easycare.model.User;
import easycare.model.security.AuthorityEnum;
import easycare.model.security.Role;
import easycare.model.security.RoleEnum;
import easycare.service.CountryStateService;
import easycare.service.RoleService;
import easycare.service.SessionSecurityService;
import easycare.service.UserService;
import easycare.service.ids.IdsServiceException;
import easycare.service.springsecurity.EasyCareUserDetails;
import easycare.web.audit.event.CreateUserFailedDuplicateEmailEvent;
import easycare.web.audit.event.CreateUserFailedDuplicateUsernameEvent;
import easycare.web.audit.event.CreateUserFailedValidationEvent;
import easycare.web.audit.event.CreateUserSuccessfulEvent;
import easycare.web.editor.CountryEditor;
import easycare.web.editor.StateEditor;
import easycare.web.filter.FlashScope;
import easycare.web.password.PasswordMethodManual;
import easycare.web.user.ids.IdsControllerSupport;
import easycare.web.validation.FormValidator;
import easycare.web.view.ContactModelMaker;
import easycare.web.view.helper.PaginationHelper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
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.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Set;

import static easycare.web.view.helper.PaginationHelper.getQueryStringWithPageNumberFromSession;
import static easycare.web.view.helper.PaginationHelper.removeQueryStringAndPageNumberFromSession;

@Controller
@RequestMapping("/admin/users")
public class UserController {
    private static Logger log = LoggerFactory.getLogger(UserController.class);

    public static final String USER_FORM = "userform";
    public static final String USER = "user";
    public static final String ROLES = "roles";
    public static final String LOCATIONS = "locations";

    public static final String CAN_EDIT_ACCOUNT_STATUS = "canEditAccountStatus";

    public static final String NEW_USER_FORM = "newuser";
    public static final String NEW_USER_CREATION_SUCCESS_MESSAGE = "user.new.success";
    public static final String NEW_USER_CREATION_IDS_ERROR_MESSAGE = "user.new.idsError";

    public static final String EMAIL_FIELD = "email";
    public static final String DEFAULT_EMAIL_EXISTS_MESSAGE = "Email exists";
    public static final String EMAIL_ALREADY_EXISTS = "user.create.error.emailExists";

    private static final String REDIRECT_TO_USERS = "redirect:/admin/users";
    public static final String REDIRECT_TO_IDS_CERT_DETAILS = "redirect:/admin/users/%s/idscert";

    private static final String REQUEST_MAPPING_FOR_NEW_USER_CREATION = "/new";
    static final String NEW_USER_CREATION_FAILURE_MESSAGE = "user.create.error";
    static final String NEW_USER_CREATION_INTERPRETING_PHYSICIAN_FAILURE_MESSAGE = "user.create.error.interpreting.physician";
    private static final String USER_NAME_ALREADY_EXISTS = "user.create.error.usernameExists";
    private static final String SESSION_KEY_PREFIX = UserController.class.getName() + "_";

    @Autowired
    private Clock clock;

    @Autowired
    protected ApplicationMessageSource messageSource;

    @Autowired
    private FlashScope flashScope;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private SessionSecurityService securityService;

    @Autowired
    private CountryStateService regionCountryStateService;

    @Autowired
    private ContactModelMaker contactModelMaker;

    @Autowired
    private FormValidator formValidator;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    private IdsControllerSupport idsControllerSupport;

    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {
        CountryEditor countryEditor = new CountryEditor(this.regionCountryStateService);
        dataBinder.registerCustomEditor(Country.class, countryEditor);
        dataBinder.registerCustomEditor(State.class,
                new StateEditor(this.regionCountryStateService, countryEditor));
        // bind empty strings as null
        dataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }

    @PreAuthorize("hasAnyAuthority('CREATE_RESMED_USERS', 'CREATE_ORG_USERS')")
    @RequestMapping(REQUEST_MAPPING_FOR_NEW_USER_CREATION)
    public ModelAndView newUser(HttpServletRequest request) {
        return showNewUserForm(request, new ModelAndView(), new NewUserForm(getCurrentUsersCountry()));
    }

    @PreAuthorize("hasAnyAuthority('CREATE_RESMED_USERS', 'CREATE_ORG_USERS')")
    @RequestMapping(value = REQUEST_MAPPING_FOR_NEW_USER_CREATION, method = RequestMethod.POST)
    public ModelAndView createUser(HttpServletRequest request,
            @ModelAttribute(USER_FORM) @Valid NewUserForm newUserForm, BindingResult result) {
        if (!isProvidedDataValidToProceedUserCreation(newUserForm, result)) {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("displayContactInformation", result.hasFieldErrors("contactInformation.*"));
            modelAndView.addObject("displayIdentification", result.hasFieldErrors("licenseNumber"));
            return showNewUserForm(request, modelAndView, newUserForm);
        }

        User newUser = newUserForm.createUser(securityService, roleService, clock.getCurrentLocalDate());

        try {
            if (securityService.hasCurrentUserGotAuthority(AuthorityEnum.CAN_AUTHENTICATE_AGAINST_IDS)) {
                newUser = userService.createUserWithIdsCertificate(newUser);
            } else if (newUserForm.isPasswordMethodAuto()) {
                newUser = userService.createUserWithEmailActivationToken(newUser);
            } else {
                newUser = userService.createUserWithManualPassword(newUser);
            }
        } catch (IdsServiceException e) {
            log.error("Unable to create user", e);
            ModelAndView modelAndView = new ModelAndView(NEW_USER_FORM);
            modelAndView.addObject("message", messageSource.getMessage(NEW_USER_CREATION_IDS_ERROR_MESSAGE));
            return modelAndView;
        }

        fireCreateSuccessEvent(newUserForm);
        flashScope.addMessage(NEW_USER_CREATION_SUCCESS_MESSAGE);

        String redirect;
        if (securityService.hasCurrentUserGotAuthority(AuthorityEnum.CAN_AUTHENTICATE_AGAINST_IDS)) {
            idsControllerSupport
                    .addCertificateRetrievalDetailsToFlashScope(newUser.getCertificateRetrievalPassword());
            redirect = String.format(REDIRECT_TO_IDS_CERT_DETAILS, newUser.getId());
        } else {
            String searchAndPaginationParameters = getQueryStringWithPageNumberFromSession(request,
                    SESSION_KEY_PREFIX);
            removeQueryStringAndPageNumberFromSession(request, SESSION_KEY_PREFIX);

            redirect = REDIRECT_TO_USERS + searchAndPaginationParameters;
        }

        return new ModelAndView(redirect);
    }

    private void fireCreateUserFailedDuplicateUsernameEvent(NewUserForm newUserForm) {
        Authentication authentication = securityService.getAuthentication();
        applicationEventPublisher
                .publishEvent(new CreateUserFailedDuplicateUsernameEvent(authentication, newUserForm));
    }

    private void fireCreateUserFailedDuplicateEmailEvent(NewUserForm newUserForm) {
        Authentication authentication = securityService.getAuthentication();
        applicationEventPublisher
                .publishEvent(new CreateUserFailedDuplicateEmailEvent(authentication, newUserForm));
    }

    private void fireCreateUserFailedValidationEvent(NewUserForm newUserForm, Errors errors) {
        Authentication authentication = securityService.getAuthentication();
        applicationEventPublisher
                .publishEvent(new CreateUserFailedValidationEvent(authentication, newUserForm, errors));
    }

    private void fireCreateSuccessEvent(NewUserForm newUserForm) {
        Authentication authentication = securityService.getAuthentication();
        applicationEventPublisher.publishEvent(new CreateUserSuccessfulEvent(authentication, newUserForm));
    }

    private boolean isProvidedDataValidToProceedUserCreation(final NewUserForm newUserForm,
            final BindingResult result) {
        boolean interpretingPhysicianFieldsValid = areMandatoryFieldsPresentForInterpretingPhysician(newUserForm,
                result);
        if (!isPasswordValid(newUserForm, result) || result.hasErrors()) {
            if (!interpretingPhysicianFieldsValid) {
                result.reject(NEW_USER_CREATION_INTERPRETING_PHYSICIAN_FAILURE_MESSAGE);
            } else {
                result.reject(NEW_USER_CREATION_FAILURE_MESSAGE);
            }
            fireCreateUserFailedValidationEvent(newUserForm, result);
            return false;
        }

        return isUserValidForCreation(newUserForm, result);
    }

    private boolean isUserValidForCreation(final NewUserForm newUserForm, final BindingResult result) {
        // Check Username is unique
        final String username = newUserForm.getUsername();
        if (userService.findByUsernameWithContactInformation(username) != null) {
            result.reject(USER_NAME_ALREADY_EXISTS, new Object[] { username }, null);
            fireCreateUserFailedDuplicateUsernameEvent(newUserForm);
            return false;
        }

        // Check email is unique
        final String email = newUserForm.getEmail();
        if (email != null && userService.findByEmail(email) != null) {
            result.reject(EMAIL_ALREADY_EXISTS, new Object[] { email }, null);
            fireCreateUserFailedDuplicateEmailEvent(newUserForm);
            return false;
        }
        return true;
    }

    private boolean areMandatoryFieldsPresentForInterpretingPhysician(NewUserForm newUserForm,
            BindingResult result) {
        boolean valid = true;

        if (!newUserForm.hasRole(RoleEnum.ROLE_INTERPRETING_PHYSICIAN)) {
            return valid;
        }

        if (StringUtils.isEmpty(newUserForm.getEmail())) {
            // this will already be validated by the user form.  Don't reject email value again as will see duplicate errors...
            valid = false;
        }

        if (newUserForm.hasNoEmail()) {
            result.rejectValue("noEmail", NEW_USER_CREATION_INTERPRETING_PHYSICIAN_FAILURE_MESSAGE);
            valid = false;
        }

        if (StringUtils.isEmpty(newUserForm.getLicenseNumber())) {
            result.rejectValue("licenseNumber", NEW_USER_CREATION_INTERPRETING_PHYSICIAN_FAILURE_MESSAGE);
            valid = false;
        }

        return valid;
    }

    private boolean isPasswordValid(NewUserForm newUserForm, BindingResult result) {
        // Check Password pattern if set manually
        if (newUserForm.isPasswordMethodManual()) {
            formValidator.validate(newUserForm, result, PasswordMethodManual.class);
            return !result.hasErrors();
        }
        return true;
    }

    /** Prepares model for 'new user' page, and return the view name. */
    private ModelAndView showNewUserForm(HttpServletRequest request, ModelAndView modelAndView,
            NewUserForm newUserForm) {
        EasyCareUserDetails currentUserDetails = securityService.getCurrentUserDetails();
        Set<Role> roles = roleService.findUserViewableRolesAndSubRoles(currentUserDetails);

        modelAndView.addObject(ROLES, roles);
        modelAndView.addObject(USER_FORM, newUserForm);
        modelAndView.addObject(LOCATIONS, userLocations());
        modelAndView.setViewName(NEW_USER_FORM);

        contactModelMaker.populateContactModel(modelAndView.getModel(), newUserForm.getContactInformation());

        // Keep pagination parameters
        PaginationHelper.addQueryStringAndPageNumberToSession(request, SESSION_KEY_PREFIX);

        return modelAndView;
    }

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

    private Country getCurrentUsersCountry() {
        return securityService.getCurrentUser().getOrganisation().getCountry();
    }
}