gov.nih.nci.cabig.caaers.domain.repository.UserRepositoryImpl.java Source code

Java tutorial

Introduction

Here is the source code for gov.nih.nci.cabig.caaers.domain.repository.UserRepositoryImpl.java

Source

/*******************************************************************************
 * Copyright SemanticBits, Northwestern University and Akaza Research
 * 
 * Distributed under the OSI-approved BSD 3-Clause License.
 * See http://ncip.github.com/caaers/LICENSE.txt for details.
 ******************************************************************************/
package gov.nih.nci.cabig.caaers.domain.repository;

import edu.nwu.bioinformatics.commons.CollectionUtils;
import gov.nih.nci.cabig.caaers.CaaersSystemException;
import gov.nih.nci.cabig.caaers.RoleMembership;
import gov.nih.nci.cabig.caaers.dao.UserDao;
import gov.nih.nci.cabig.caaers.dao.query.UserQuery;
import gov.nih.nci.cabig.caaers.domain.User;
import gov.nih.nci.cabig.caaers.domain.UserGroupType;
import gov.nih.nci.cabig.caaers.security.CSMCacheManager;
import gov.nih.nci.cabig.caaers.tools.configuration.Configuration;
import gov.nih.nci.cabig.ctms.suite.authorization.ProvisioningSession;
import gov.nih.nci.cabig.ctms.suite.authorization.ProvisioningSessionFactory;
import gov.nih.nci.cabig.ctms.suite.authorization.SuiteRole;
import gov.nih.nci.cabig.ctms.suite.authorization.SuiteRoleMembership;
import gov.nih.nci.security.UserProvisioningManager;
import gov.nih.nci.security.authorization.domainobjects.Group;
import gov.nih.nci.security.dao.UserSearchCriteria;
import gov.nih.nci.security.exceptions.CSObjectNotFoundException;
import gov.nih.nci.security.exceptions.CSTransactionException;
import gov.nih.nci.security.util.StringEncrypter;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

/**
 * The Class UserRepositoryImpl.
 */
public class UserRepositoryImpl implements UserRepository {

    /** The logger. */
    private Logger logger = Logger.getLogger(UserRepositoryImpl.class);

    /** The user dao. */
    private UserDao userDao;

    /** The user provisioning manager. */
    private UserProvisioningManager userProvisioningManager;

    /** The provisioning session factory. */
    private ProvisioningSessionFactory provisioningSessionFactory;

    /** The mail sender. */
    private MailSender mailSender;

    /** The authentication mode. */
    private String authenticationMode;

    /** The message source. */
    private MessageSource messageSource;

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#searchCsmUser(java.lang.String, java.lang.String, java.lang.String)
     */
    @SuppressWarnings("unchecked")
    public List searchCsmUser(String firstName, String lastName, String userName) {
        if (StringUtils.isEmpty(firstName) && StringUtils.isEmpty(lastName) && StringUtils.isEmpty(userName))
            firstName = "%";
        gov.nih.nci.security.authorization.domainobjects.User example = new gov.nih.nci.security.authorization.domainobjects.User();
        if (StringUtils.isNotEmpty(firstName))
            example.setFirstName("%" + firstName + "%");
        if (StringUtils.isNotEmpty(lastName))
            example.setLastName("%" + lastName + "%");
        if (StringUtils.isNotEmpty(userName))
            example.setLoginName("%" + userName + "%");
        UserSearchCriteria userSearchCriteria = new UserSearchCriteria(example);
        return userProvisioningManager.getObjects(userSearchCriteria);
    }

    public List searchCsmUser(String name) {
        Set users = new HashSet();
        if (StringUtils.isEmpty(name))
            name = "%";
        gov.nih.nci.security.authorization.domainobjects.User user1 = new gov.nih.nci.security.authorization.domainobjects.User();
        gov.nih.nci.security.authorization.domainobjects.User user2 = new gov.nih.nci.security.authorization.domainobjects.User();
        for (String nameStr : name.split(" ")) {
            user1.setFirstName("%" + nameStr + "%");
            UserSearchCriteria userSearchCriteria = new UserSearchCriteria(user1);
            users.addAll(userProvisioningManager.getObjects(userSearchCriteria));
            user2.setLastName("%" + nameStr + "%");
            UserSearchCriteria userSearchCriteria2 = new UserSearchCriteria(user2);
            users.addAll(userProvisioningManager.getObjects(userSearchCriteria2));
        }
        return new ArrayList(users);
    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#save(gov.nih.nci.cabig.caaers.domain.User)
     */
    @Transactional(readOnly = false)
    public void save(User user) {
        userDao.save(user);
    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#createOrUpdateUser(gov.nih.nci.cabig.caaers.domain.User, java.lang.String)
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, noRollbackFor = MailException.class)
    public void createOrUpdateUser(User user, String changeURL) {
        if (user.getCsmUser().getUserId() == null) {
            createCSMUser(user);
            save(user);
            sendCreateAccountEmail(user, changeURL);
        } else {
            updateCSMUser(user, true);
            if (user.getId() == null) {
                save(user);
            }
            sendUpdateAccountEmail(user);
        }
    }

    /*
     * (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.security.CaaersSecurityFacade#provisionRoleMemberships(gov.nih.nci.security.authorization.domainobjects.User, java.util.List)
     */
    public void provisionRoleMemberships(gov.nih.nci.security.authorization.domainobjects.User csmUser,
            List<SuiteRoleMembership> roleMemberships) {

        //Fetch all the existing groups of the Given User.
        List<UserGroupType> userGroups = getUserGroups(csmUser.getUserId().toString());

        //Erase all the existing SuiteRoleMemberships of the User
        ProvisioningSession session = provisioningSessionFactory.createSession(csmUser.getUserId());
        for (UserGroupType group : userGroups) {
            session.deleteRole(SuiteRole.getByCsmName(group.getCsmName()));
        }
        //Provision the newly provided SuiteRoleMemberships for the User in CSM.
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(roleMemberships)) {
            for (SuiteRoleMembership roleMembership : roleMemberships) {
                session.replaceRole(roleMembership);
            }
        }

        //user information got updated, so remove from cache.
        CSMCacheManager.removeUserFromCache(csmUser.getLoginName());
    }

    /**
     * Will fetch the user from the DB, along with the CSM related information properly populated.
     *
     * @param loginName the login name
     * @return the user by login name
     */
    @Transactional(readOnly = true)
    public User getUserByLoginName(String loginName) {

        //fetch the fresh user. 
        User _user = userDao.getByLoginName(loginName);

        //fetch the CSM related details from Cache if the user is present there.
        User userFromCache = CSMCacheManager.getUserFromCache(loginName);
        if (_user != null && userFromCache != null) {
            //obtain csm information from cache. 
            _user.setCsmUser(userFromCache.getCsmUser());
            _user.getRoleMembershipMap().putAll(userFromCache.getRoleMembershipMap());

        } else {
            //fetch CSM information
            gov.nih.nci.security.authorization.domainobjects.User csmUser = userProvisioningManager
                    .getUser(loginName);
            if (_user == null && csmUser == null)
                return null; // may be login-id supplied is incorrect.
            if (csmUser == null) {
                logger.error("CSM User with loginName [" + loginName
                        + "] don't exist, a data integrity issue as user exist in caAERS");
                throw new CaaersSystemException("caAERS user [" + loginName
                        + "] exists and relevant CSM user does not exist : Data Integrity issue");
            }
            if (_user == null) {
                _user = new User(csmUser);
                _user.setPasswordLastSet(new Timestamp(Calendar.getInstance().getTimeInMillis()));
            } else {
                _user.setCsmUser(csmUser);
            }

            //populate the role membership
            List<UserGroupType> groups = getUserGroups(csmUser.getUserId().toString());
            if (!CollectionUtils.isEmpty(groups)) {
                ProvisioningSession session = provisioningSessionFactory.createSession(csmUser.getUserId());
                for (UserGroupType role : groups) {
                    SuiteRole suiteRole = SuiteRole.getByCsmName(role.getCsmName());
                    if (!suiteRole.isScoped()) {
                        _user.findRoleMembership(role);
                    } else {
                        SuiteRoleMembership suiteRoleMembership = session.getProvisionableRoleMembership(suiteRole);
                        RoleMembership roleMembership = _user.findRoleMembership(role);
                        if (suiteRoleMembership.isAllSites()) {
                            roleMembership.setAllSite(suiteRoleMembership.isAllSites());
                        } else {
                            roleMembership.getOrganizationNCICodes()
                                    .addAll(suiteRoleMembership.getSiteIdentifiers());
                        }
                        if (suiteRole.isStudyScoped()) {
                            if (suiteRoleMembership.isAllStudies()) {
                                roleMembership.setAllStudy(suiteRoleMembership.isAllStudies());
                            } else {
                                roleMembership.getStudyIdentifiers()
                                        .addAll(suiteRoleMembership.getStudyIdentifiers());
                            }
                        }

                    }
                }
            }

            //add the user into the cache.
            CSMCacheManager.addUserToCache(loginName, _user);

        }

        return _user;
    }

    /**
     * Fetches the groups associated to users.
     *
     * @param csmUserId  - The csm Id of the user
     * @return the user groups
     */
    public List<UserGroupType> getUserGroups(String csmUserId) {
        List<UserGroupType> userGroups = new ArrayList<UserGroupType>();
        try {
            Set groups = userProvisioningManager.getGroups(csmUserId);
            if (groups != null) {
                for (Object obj : groups) {
                    Group group = (Group) obj;
                    UserGroupType userGroupType = UserGroupType.valueOf(group.getGroupName());
                    if (userGroupType != null)
                        userGroups.add(userGroupType);
                }
            }
        } catch (CSObjectNotFoundException e) {
            logger.warn("unable to fetch groups for CSM user (" + csmUserId + "), something is wrong", e);
        }
        return userGroups;
    }

    /**
     * Update csm user.
     *
     * @param user the user
     */
    @Transactional(readOnly = false)
    protected void updateCSMUser(User user, boolean updatingDetails) {

        if (updatingDetails) {
            String ds = null;
            try {
                ds = decryptString(user.getCsmUser().getPassword());
            } catch (CaaersSystemException cse) {
                logger.error(" no need to decrypt , as string is not encrypted");
            }
            if (ds != null) {
                user.getCsmUser().setPassword(ds);
            }
        }

        try {
            userProvisioningManager.modifyUser(user.getCsmUser());
        } catch (CSTransactionException e) {
            throw new CaaersSystemException("Couldn't update CSM user: ", e);
        }
    }

    /**
     * Creates the csm user.
     *
     * @param user the user
     */
    @Transactional(readOnly = false)
    protected void createCSMUser(User user) {
        gov.nih.nci.security.authorization.domainobjects.User dbCsmUser = userProvisioningManager
                .getUser(user.getLoginName());
        if (dbCsmUser != null)
            throw new CaaersSystemException("Couldn't add user: " + user.getLoginName() + ": already exists.");
        try {
            user.getCsmUser().setPassword(
                    encryptString((StringUtils.isEmpty(user.getSalt()) ? "" : user.getSalt()) + "obscurity"));
            user.generateNewToken();
            userProvisioningManager.createUser(user.getCsmUser());
        } catch (CSTransactionException e2) {
            logger.error("Error creating csm user", e2);
            throw new CaaersSystemException("Could not create user", e2);
        }
    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#unlockUser(gov.nih.nci.cabig.caaers.domain.User)
     */
    public void unlockUserPassword(User user) {
        user.unlockPassword();
        save(user);
    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#userChangePassword(gov.nih.nci.cabig.caaers.domain.User, java.lang.String, int)
     */
    public void userChangePassword(User user, String password, int maxHistorySize) {
        user.resetToken();
        user.setPasswordLastSet(new Timestamp(new Date().getTime()));
        user.addPasswordToHistory(DigestUtils.shaHex(password), maxHistorySize);
        user.getCsmUser().setPassword((StringUtils.isEmpty(user.getSalt()) ? "" : user.getSalt()) + password);
        updateCSMUser(user, false);
        save(user);
    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#loginIDInUse(java.lang.String)
     */
    public boolean loginIDInUse(String loginId) {
        if (userProvisioningManager.getUser(loginId) != null)
            return true;
        return false;
    }

    /**
     * Encrypt string.
     *
     * @param string the string
     * @return the string
     */
    public String encryptString(String string) {
        try {
            return new StringEncrypter().encrypt(string);
        } catch (StringEncrypter.EncryptionException enX) {
            throw new CaaersSystemException("Could not encrypt string", enX);
        }
    }

    /**
     * Decrypt string.
     *
     * @param string the string
     * @return the string
     */
    public String decryptString(String encryptedString) {
        try {
            return new StringEncrypter().decrypt(encryptedString);
        } catch (StringEncrypter.EncryptionException enX) {
            throw new CaaersSystemException("Could not decrypt string", enX);
        }
    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#sendUserEmail(java.lang.String, java.lang.String, java.lang.String)
     */
    public void sendUserEmail(String emailAddress, String subject, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(emailAddress);
        message.setSubject(subject);
        message.setText(text);
        mailSender.send(message);

    }

    /**
     * Send create account email.
     *
     * @param user the user
     * @param changeURL the change url
     */
    protected void sendCreateAccountEmail(User user, String changeURL) {
        String caAERSBaseUrl = Configuration.LAST_LOADED_CONFIGURATION.get(Configuration.CAAERS_BASE_URL);
        String EMAIL_SUBJECT = getMessageSource().getMessage("createAccountEmail.subject", null,
                "Your new caAERS account", Locale.getDefault());
        String EMAIL_TEXT = getMessageSource().getMessage("createAccountEmail.text",
                new Object[] { user.getCsmUser().getLoginName(), changeURL + "&token=" + user.getToken(),
                        caAERSBaseUrl },
                "An account has been created for you in the caAERS Adverse Event Reporting System.\n \nYour username is: {0}.\n \nYou must create your password to login to caAERS. \n"
                        + "  You can do so by clicking on the URL below:\n{1}\n \nThe above link will expire after a preset period of time and can only be used once. Should you have difficulty with logging in, \n"
                        + "  please go to {2} and click \"Forgot password?\" to generate a new set password link.\n \nThis message was sent by caAERS. Please do not reply to this message.",
                Locale.getDefault());
        ;

        //send out an email
        if ("local".equals(getAuthenticationMode())) {
            sendUserEmail(user.getCsmUser().getEmailId(), EMAIL_SUBJECT, EMAIL_TEXT);
        }
    }

    /**
     * Send update account email.
     *
     * @param user the user
     */
    protected void sendUpdateAccountEmail(User user) {
        if ("local".equals(getAuthenticationMode())) {
            String userName = user.getCsmUser().getLoginName();
            String sysName = Configuration.LAST_LOADED_CONFIGURATION.get(Configuration.SYSTEM_NAME);
            String emailSubject = getMessageSource().getMessage("updateAccountEmail.subject", null,
                    "Your updated caAERS account", Locale.getDefault());
            String emailText = getMessageSource().getMessage("updateAccountEmail.text",
                    new String[] { userName, sysName }, "Your caAERS account has been updated",
                    Locale.getDefault());

            sendUserEmail(user.getCsmUser().getEmailId(), emailSubject, emailText); // annoying for development
        }
    }

    /**
     * Will provision in SuiteCSM all the roles.
     *
     * @param user the user
     */
    public void provisionUser(User user) {

        ProvisioningSession session = provisioningSessionFactory.createSession(user.getCsmUser().getUserId());

        //delete all the roles
        for (SuiteRole suiteRole : SuiteRole.values()) {
            logger.debug("Deleting suite role " + suiteRole.name());
            session.deleteRole(suiteRole);
        }

        //add selected roles
        for (Map.Entry<UserGroupType, RoleMembership> membershipEntry : user.getRoleMembershipMap().entrySet()) {
            UserGroupType userRole = membershipEntry.getKey();
            RoleMembership userMembership = membershipEntry.getValue();

            //find the SuiteRoleMembership
            SuiteRole suiteRole = SuiteRole.getByCsmName(userRole.getCsmName());
            SuiteRoleMembership suiteRoleMembership = session.getProvisionableRoleMembership(suiteRole);
            if (suiteRole.isScoped()) {

                //add new entries
                if (suiteRole.isStudyScoped()) {
                    //study scoped roles only can provision study information
                    if (userMembership.isAllStudy()) {
                        suiteRoleMembership.forAllStudies();
                    } else {
                        suiteRoleMembership.forStudies(userMembership.getStudyIdentifiers());
                    }
                }
                //both site and study scoped roles, can provision organizations information 
                if (userMembership.isAllSite()) {
                    suiteRoleMembership.forAllSites();
                } else {
                    suiteRoleMembership.forSites(userMembership.getOrganizationNCICodes());
                }

            }

            //replace the old role membership with new one. 
            session.replaceRole(suiteRoleMembership);
            logger.debug("provisioned suite role " + suiteRole.name());

        }

    }

    /* (non-Javadoc)
     * @see gov.nih.nci.cabig.caaers.domain.repository.UserRepository#search(gov.nih.nci.cabig.caaers.dao.query.UserQuery)
     */
    public List<User> search(UserQuery query) {
        return (List<User>) userDao.search(query);
    }

    /**
     * Sets the user dao.
     *
     * @param userDao the new user dao
     */
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * Sets the user provisioning manager.
     *
     * @param userProvisioningManager the new user provisioning manager
     */
    public void setUserProvisioningManager(UserProvisioningManager userProvisioningManager) {
        this.userProvisioningManager = userProvisioningManager;
    }

    /**
     * Sets the mail sender.
     *
     * @param mailSender the new mail sender
     */
    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    /**
     * Gets the authentication mode.
     *
     * @return the authentication mode
     */
    public String getAuthenticationMode() {
        return authenticationMode;
    }

    /**
     * Sets the authentication mode.
     *
     * @param authenticationMode the new authentication mode
     */
    public void setAuthenticationMode(String authenticationMode) {
        this.authenticationMode = authenticationMode;
    }

    /**
     * Gets the message source.
     *
     * @return the message source
     */
    public MessageSource getMessageSource() {
        return messageSource;
    }

    /**
     * Sets the message source.
     *
     * @param messageSource the new message source
     */
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    /**
     * Gets the mail sender.
     *
     * @return the mail sender
     */
    public MailSender getMailSender() {
        return mailSender;
    }

    /**
     * Gets the provisioning session factory.
     *
     * @return the provisioning session factory
     */
    public ProvisioningSessionFactory getProvisioningSessionFactory() {
        return provisioningSessionFactory;
    }

    /**
     * Sets the provisioning session factory.
     *
     * @param provisioningSessionFactory the new provisioning session factory
     */
    public void setProvisioningSessionFactory(ProvisioningSessionFactory provisioningSessionFactory) {
        this.provisioningSessionFactory = provisioningSessionFactory;
    }

    public void unlockUser(User user) {
        user.unLock();
    }

    public void lockUser(User user) {
        user.lock();
    }
}