package edu.asu.spring.quadriga.service.impl; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCrypt; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import edu.asu.spring.quadriga.dao.IUserDAO; import edu.asu.spring.quadriga.domain.IQuadrigaRole; import edu.asu.spring.quadriga.domain.IUser; import edu.asu.spring.quadriga.domain.factories.IUserFactory; import edu.asu.spring.quadriga.domain.impl.User; import edu.asu.spring.quadriga.dto.QuadrigaUserDTO; import edu.asu.spring.quadriga.dto.QuadrigaUserDeniedDTO; import edu.asu.spring.quadriga.dto.QuadrigaUserRequestsDTO; import edu.asu.spring.quadriga.email.IEmailNotificationManager; import edu.asu.spring.quadriga.email.impl.EmailNotificationManager; import edu.asu.spring.quadriga.exceptions.QuadrigaNotificationException; import edu.asu.spring.quadriga.exceptions.QuadrigaStorageException; import edu.asu.spring.quadriga.exceptions.UserOwnsOrCollaboratesDeletionException; import edu.asu.spring.quadriga.exceptions.UsernameExistsException; import edu.asu.spring.quadriga.service.IQuadrigaRoleManager; import edu.asu.spring.quadriga.service.IUserManager; import edu.asu.spring.quadriga.service.user.mapper.IUserDeepMapper; import edu.asu.spring.quadriga.web.login.RoleNames; import edu.asu.spring.quadriga.web.manageusers.beans.AccountRequest; /** * @description UserManager class implementing the User functionality * * @author Kiran Kumar Batna * @author Ram Kumar Kumaresan * */ @Service public class UserManager implements IUserManager { private static final Logger logger = LoggerFactory.getLogger(UserManager.class); @Autowired private IQuadrigaRoleManager rolemanager; @Autowired private IUserDeepMapper userDeepMapper; @Autowired private IUserFactory userFactory; @Autowired private IEmailNotificationManager emailManager; @Autowired private IUserDAO usermanagerDAO; /** * @description : retrieve the user details from DBConectionManager and * retrieve the associate roles from the quadriga-roles.xml * * @param : userId - the userid for which the details are obtained. * * @return : IUser - User object with full details of user if he is present * in the Quadriga DB. - User object assigned to 'No Account' role' * if he is not present in Quadriga DB. * @author : Kiran * @throws QuadrigaStorageException * */ @Override @Transactional public IUser getUser(String sUserId) throws QuadrigaStorageException { return userDeepMapper.getUser(sUserId); } /** * List all active users in the Quadriga database * * @return List of all active user objects * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException */ @Override @Transactional public List<IUser> getAllActiveUsers() throws QuadrigaStorageException { List<IUser> listUsers = userDeepMapper.getAllActiveUsers(); return listUsers; } /** * List all inactive users in the quadriga database * * @return List of all inactive user objects * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException */ @Override @Transactional public List<IUser> getAllInActiveUsers() throws QuadrigaStorageException { List<IUser> listUsers = userDeepMapper.getAllInActiveUsers(); return listUsers; } /** * List all the open user requests available in the quadriga database * * @return List all open user requests * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException */ @Override @Transactional public List<IUser> getUserRequests() throws QuadrigaStorageException { List<IUser> listUsers = userDeepMapper.getUserRequests(); return listUsers; } /** * Deactivate a user account so that the particular user cannot access * quadriga anymore. * * @param sUserId * The userid of the user whose account is to be deactivated. * @param sAdminId * The userid of the admin who is changing the user setting. * @return Return the status of the operation. 1- Success and 0 - Failure. * * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException */ @Override @Transactional public int deactivateUser(String sUserId, String sAdminId) throws QuadrigaStorageException { // Find the ROLEDBID for Deactivated account String sDeactiveRoleDBId = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_DEACTIVATED); // Add the new role to the user. int iResult = usermanagerDAO.deactivateUser(sUserId, sDeactiveRoleDBId, sAdminId); if (iResult == SUCCESS) { logger.info("The admin " + sAdminId + " deactivated the account of " + sUserId); IUser user = this.getUser(sUserId); if (user.getEmail() != null && !user.getEmail().equals("")) emailManager.sendAccountDeactivationEmail(user, sAdminId); else logger.info("The user " + sUserId + " did not have an email address to send account deactivation email"); } return iResult; } /** * Method to delete Quadriga user by admin * * @param sUserId * @param sAdminId * @throws QuadrigaStorageException * @throws UserOwnsOrCollaboratesDeletionException */ @Override @Transactional public void deleteUser(String deleteUser, String adminUser) throws QuadrigaStorageException, UserOwnsOrCollaboratesDeletionException { // Find the ROLEDBID for Deactivated account String sDeactiveRoleDBId = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_DEACTIVATED); usermanagerDAO.deleteUser(deleteUser, sDeactiveRoleDBId); } /** * Approve a user request to access quadriga. * * @param sUserId * The userid of the user whose account has been approved. * @param sRoles * The set of roles that are assigned to the user. * @param sAdminId * The userid of the admin who is changing the user setting * @return Return the status of the operation. 1- Success and 0 - Failure. * * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException * @throws QuadrigaNotificationException */ @Override @Transactional public int approveUserRequest(String sUserId, String sRoles, String sAdminId) throws QuadrigaStorageException, QuadrigaNotificationException { int iResult = usermanagerDAO.approveUserRequest(sUserId, sRoles, sAdminId); if (iResult == IUserDAO.SUCCESS) { IUser user = getUser(sUserId); emailManager.sendAccountProcessedEmail(user, true); } return iResult; } /** * Deny a user request to access the quadriga. * * @param sUserId * The userid of the user whose account has been denied. * @param sAdminId * The userid of the admin who is changing the user setting. * @return Return the status of the operation. 1- Success and 0 - Failure. * * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException * @throws QuadrigaNotificationException */ @Override @Transactional public int denyUserRequest(String sUserId, String sAdminId) throws QuadrigaStorageException, QuadrigaNotificationException { QuadrigaUserRequestsDTO user = usermanagerDAO.getUserRequestDTO(sUserId); IUser deniedUser = new User(); deniedUser.setName(user.getFullname()); deniedUser.setEmail(user.getEmail()); deniedUser.setUserName(user.getUsername()); int iResult = usermanagerDAO.denyUserRequest(sUserId, sAdminId); if (iResult == IUserDAO.SUCCESS) { emailManager.sendAccountProcessedEmail(deniedUser, false); } return iResult; } /** * Activate an already existing user so that the user can access quadriga. * * @param sUserId * The userid of the user whose account has been activated. * @param sAdminId * The userid of the admin who is changing the user setting. * @return Return the status of the operation. 1- Success and 0 - Failure. * * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException */ @Override @Transactional public int activateUser(String sUserId, String sAdminId) throws QuadrigaStorageException { int iResult = 0; // Find the deactivated role id and create a QuadrigaRole Object String sDeactiveRoleDBId = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_DEACTIVATED); // Find all the roles of the user IUser user = null; user = userDeepMapper.getUser(sUserId); // Remove the deactivated role from user roles if (user != null) { IQuadrigaRole quadrigaRole = null; List<IQuadrigaRole> rolesList = new ArrayList<IQuadrigaRole>(); List<IQuadrigaRole> userRoles = user.getQuadrigaRoles(); for (IQuadrigaRole role : userRoles) { if (!role.getDBid().equals(sDeactiveRoleDBId)) { quadrigaRole = rolemanager.getQuadrigaRoleByDbId(IQuadrigaRoleManager.MAIN_ROLES, role.getDBid()); rolesList.add(quadrigaRole); } } user.setQuadrigaRoles(rolesList); // Convert the user roles to one string with DBROLEIDs // Update the role in the Quadriga Database. // TODO: Change the method to update the user roles. iResult = usermanagerDAO.updateUserRoles(sUserId, user.getQuadrigaRolesAsString(), sAdminId); if (iResult == SUCCESS) { logger.info("The admin " + sAdminId + " activated the account of " + sUserId); if (user.getEmail() != null && !user.getEmail().equals("")) emailManager.sendAccountActivationEmail(user, sAdminId); else { logger.info("The user " + sUserId + " did not have an email address to send account activation email"); } } } return iResult; } /** * This method adds a new user account request to the database. it encrypts * the user's password using the BCrypt algorithm. * * @param request * The {@link AccountRequest} encapsulating the user's data. * @return true if request was successfully added; otherwise false * @author jdamerow * @throws QuadrigaStorageException * @throws UsernameExistsException * @throws QuadrigaNotificationException */ @Override @Transactional public boolean addNewUser(AccountRequest request) throws QuadrigaStorageException, UsernameExistsException { QuadrigaUserDTO userDTO = usermanagerDAO.getUserDTO(request.getUsername()); // Check if username is already in use if (userDTO != null) throw new UsernameExistsException("Username already in use."); QuadrigaUserRequestsDTO userRequest = usermanagerDAO.getUserRequestDTO(request.getUsername()); if (userRequest != null) throw new UsernameExistsException("Username already in use."); String plainPassword = request.getPassword(); boolean success = usermanagerDAO.addNewUserAccountRequest(request.getUsername(), encryptPassword(plainPassword), request.getName(), request.getEmail()); if (success) { IQuadrigaRole role = rolemanager.getQuadrigaRoleById(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_ADMIN); List<QuadrigaUserDTO> admins = usermanagerDAO.getUserDTOList(role.getDBid()); for (QuadrigaUserDTO admin : admins) { try { emailManager.sendAccountCreatedEmail(request.getName(), request.getUsername(), admin.getFullname(), admin.getEmail()); } catch (QuadrigaNotificationException e) { // let's log error but keep on going logger.error("Email to " + admin.getUsername() + " could not be sent.", e); } } } return success; } private String encryptPassword(String password) { return BCrypt.hashpw(password, BCrypt.gensalt()); } /** * Add a new user request to access quadriga. * * @param userId * The user id of the user who needs access to quadriga * @return Integer value that specifies the status of the operation. 1 - * Successfully place the request. 0 - An open request is already * placed for the userid. * * @author Ram Kumar Kumaresan * @throws QuadrigaStorageException */ @Override @Transactional public int addAccountRequest(String userId) throws QuadrigaStorageException { int iUserStatus; // Get all open user requests List<IUser> listUsers = userDeepMapper.getUserRequests(); // Check if an open request is already placed for the userid for (IUser user : listUsers) { if (user.getUserName().equalsIgnoreCase(userId)) { return FAILURE; } } // Place a new access request iUserStatus = usermanagerDAO.addAccountRequest(userId); // Check the status of the request if (iUserStatus == SUCCESS) { String sAdminRoleDBId = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_ADMIN); List<IUser> listAdminUsers = userDeepMapper.getUsersByRoleId(sAdminRoleDBId); // Ignore the user if the account is deactivated adminlabel: for (IUser admin : listAdminUsers) { List<IQuadrigaRole> roles = admin.getQuadrigaRoles(); IQuadrigaRole quadrigaRole = null; for (IQuadrigaRole role : roles) { quadrigaRole = rolemanager.getQuadrigaRoleByDbId(IQuadrigaRoleManager.MAIN_ROLES, role.getDBid()); if (quadrigaRole.getId().equals(RoleNames.ROLE_QUADRIGA_DEACTIVATED)) { // Continue to the next user as this user account is // deactivated continue adminlabel; } } if (admin.getEmail() != null && !admin.getEmail().equals("")) { emailManager.sendNewAccountRequestPlacementEmail(admin, userId); } else logger.info("The system tried to send email to the admin " + admin.getUserName() + " but the admin did not have an email setup"); } } return iUserStatus; } /** * {@inheritDoc} */ @Override @Transactional public void updateUserQuadrigaRoles(String userName, String quadrigaRoles, String loggedInUser) throws QuadrigaStorageException { try { usermanagerDAO.updateUserRoles(userName, quadrigaRoles, loggedInUser); } catch (Exception ex) { throw new QuadrigaStorageException(); } } /** * This method calls the DAO layer method to insert Quadriga Admin user * record into the daabase. * * @param userName * - Quadriga admin user name. * @param sRoles * - quadriga Roles possed by the admin. * @throws QuadrigaStorageException * - represents any database exception. * @author kiran batna */ @Override @Transactional public void insertQuadrigaAdminUser(String userName) throws QuadrigaStorageException { try { // retreive the db names of the quadriga admin roles StringBuilder quadrigaRoles = new StringBuilder(); String role = null; role = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_ADMIN); quadrigaRoles.append(role); role = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_USER_STANDARD); quadrigaRoles.append(","); quadrigaRoles.append(role); role = rolemanager.getQuadrigaRoleDBId(IQuadrigaRoleManager.MAIN_ROLES, RoleNames.ROLE_QUADRIGA_USER_COLLABORATOR); quadrigaRoles.append(","); quadrigaRoles.append(role); usermanagerDAO.insertQuadrigaAdminUser(userName, quadrigaRoles.toString()); } catch (Exception ex) { throw new QuadrigaStorageException(ex.getMessage()); } } public IUserFactory getUserFactory() { return userFactory; } public void setUserFactory(IUserFactory userFactory) { this.userFactory = userFactory; } }