package org.ngbw.web.controllers; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.util.Calendar; import java.util.Set; import java.util.UUID; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ngbw.sdk.UserAuthenticationException; import org.ngbw.sdk.Workbench; import org.ngbw.sdk.WorkbenchException; import org.ngbw.sdk.WorkbenchSession; import org.ngbw.sdk.common.util.StringUtils; import org.ngbw.sdk.common.util.ValidationResult; import org.ngbw.sdk.core.shared.UserRole; import org.ngbw.sdk.database.Group; import org.ngbw.sdk.database.SSO; import org.ngbw.sdk.database.User; import org.ngbw.sdk.database.UserSuAllocationService; import org.ngbw.sdk.phoenix.CipresPhoenixUserAccountManager; import org.ngbw.sdk.tool.RegistrationManager; /** * Controller class to handle NGBW web application user session management. * Parent class of all NGBW web controller classes. * * @author Jeremy Carver * @author Tony Chen */ public class SessionController { private static final Log logger = LogFactory.getLog(SessionController.class.getName()); // folder description preference key public static final String DESCRIPTION = "description"; // default guest folder properties public static final String GUEST_FOLDER_LABEL = "Guest Folder"; public static final String GUEST_FOLDER_DESCRIPTION = "This folder organizes all of your workbench data and tasks."; // current WorkbenchSession private WorkbenchSession workbenchSession = null; /** * Default constructor. A SessionController object should only be * instantiated with this constructor if it represents a WorkbenchSession * in which the user is not yet authenticated. */ public SessionController () { workbenchSession = null; } /** * Constructor taking an authenticated WorkbenchSession argument. * The argument must be a valid WorkbenchSession object in order to * establish the proper connection with the model layer that is required to * interact with the workbench. * * @param workbenchSession The WorkbenchSession object representing the * current authenticated user's WorkbenchSession. * * @throws IllegalArgumentException if the provided WorkbenchSession * object is null. */ public SessionController ( WorkbenchSession workbenchSession ) throws IllegalArgumentException { if (workbenchSession == null) { throw new IllegalArgumentException("The provided WorkbenchSession is null."); } else { this.workbenchSession = workbenchSession; } } /** * Retrieves the current authenticated user's WorkbenchSession. * * @return The WorkbenchSession object representing the current * authenticated user's WorkbenchSession. */ public WorkbenchSession getWorkbenchSession () { return workbenchSession; } /** * Retrieves the currently active workbench interface. * * @return The Workbench object associated with the current user session. * Returns null if an error occurs. */ public Workbench getWorkbench () { try { WorkbenchSession session = getWorkbenchSession(); if (session == null) { return Workbench.getInstance(); } else { return session.getWorkbench(); } } catch ( Throwable error ) { logger.error("Error retrieving Workbench", error); return null; } } /** * Determines whether an authenticated user is currently logged in. * * @return true if a user is currently logged in to the application, false otherwise. */ public boolean isAuthenticated () { return (getWorkbenchSession() != null); } /** * Retrieves the current authenticated user. * * @return The User object representing the current authenticated user. Returns null if no * authenticated WorkbenchSession is present, or if an error occurs. */ public User getAuthenticatedUser () { WorkbenchSession session = getWorkbenchSession(); if (session == null) { logger.error("The current user could not be retrieved because the WorkbenchSession is null."); return null; } else { try { User user = session.getUser(); if (null != user) { user = new User(user.getUserId()); } return user; } catch ( Throwable error ) { logger.error("Error retrieving authenticated user", error); return null; } } } /** * Retrieves the current authenticated user's username. * * @return The current authenticated user's username. Returns null if no authenticated workbench * session is present, or if an error occurs. */ public String getAuthenticatedUsername () { WorkbenchSession session = getWorkbenchSession(); if (session == null) { logger.error("The current user's username could not be retrieved because the WorkbenchSession is null."); return null; } else { try { return session.getUsername(); } catch ( Throwable error ) { logger.error("Error retrieving authenticated user's username", error); return null; } } } /** * Retrieves the current authenticated user's (encrypted) password. * * @return The current authenticated user's encrypted password. Returns null if no authenticated * WorkbenchSession is present, or if an error occurs. */ public String getAuthenticatedPassword () { User user = getAuthenticatedUser(); if (user == null) { return null; } else { return user.getPassword(); } } /** * Retrieves the current authenticated user's role. This is used to determine the user's web * application permissions and functionality. * * @return The UserRole object representing the current authenticated user's role in the * application. Returns null if no authenticated WorkbenchSession is present, or if an * error occurs. */ public UserRole getAuthenticatedUserRole () { WorkbenchSession session = getWorkbenchSession(); if (session == null) { logger.error("The current user's role could not be retrieved because the WorkbenchSession is null."); return null; } else { try { return session.getUserRole(); } catch ( Throwable error ) { logger.error("Error retrieving authenticated user's role", error); return null; } } } /** * Retrieves the set of groups to which the current authenticated user belongs. * * @return The Set of all NGBW user Groups that the current authenticated user is a member of. * Returns null if no authenticated WorkbenchSession is present, or if an error occurs. */ public Set getAuthenticatedUserGroups () { WorkbenchSession session = getWorkbenchSession(); if (session == null) { logger.error("The current user's set of groups could not be retrieved because the WorkbenchSession is null."); return null; } else { try { return session.getGroups(); } catch ( Throwable error ) { logger.error("Error retrieving authenticated user's role", error); return null; } } } /** * Determines whether the current user is registered. Registered users have access to a greater * variety of features and functionality than guest users. * * @return true if the current user is registered, false otherwise. */ public boolean isRegistered () { UserRole role = getAuthenticatedUserRole(); if (role == null || role.equals(UserRole.GUEST)) { return false; } else { return true; } } /** * Retrieves the specified user preference for the current authenticated user. * * @param preference The key or label of the preference to be retrieved. * * @return The value of the specified user preference. Returns null if no authenticated user is * logged in, if the argument preference key is null, or an error occurs. */ public String getUserPreference ( String preference ) { User user = getAuthenticatedUser(); if (user == null) { logger.error("User preference could not be retrieved because no authenticated user is present."); return null; } else if (preference == null) { logger.error("User preference could not be retrieved because the provided preference key is null."); return null; } else { try { user.load(); return user.preferences().get(preference); } catch ( Throwable error ) { logger.error("Error retrieving user preference \"" + preference + "\"", error); return null; } } } /** * Saves the specified preference value to the currently authenticated user's stored map of user * preferences. * * @param preference The key or label of the preference to be saved. * @param value The value of the preference to be saved. * * @return true if the user preference was successfully saved, false otherwise */ public boolean setUserPreference ( String preference, String value ) { if (value == null) { return clearUserPreference(preference); } User user = getAuthenticatedUser(); if (user == null) { logger.error("User preference could not be written because no authenticated user is present."); return false; } else if (preference == null) { logger.error("User preference could not be written because the provided preference key is null."); return false; } else { try { user.preferences().put(preference, value); getWorkbenchSession().updateUser(user); logger.debug("User preference \"" + preference + "\" -> \"" + value + "\" successfully written."); return true; } catch ( Throwable error ) { logger.error("Error writing user preference \"" + preference + "\" -> \"" + value + "\"", error); return false; } } } /** * Removes the specified preference value from the currently authenticated user's stored map of * user preferences. * * @param preference the key or label of the preference to be cleared. * @param value the value of the preference to be cleared. * * @return true if the user preference was successfully cleared, false otherwise */ public boolean clearUserPreference ( String preference ) { User user = getAuthenticatedUser(); if (user == null) { logger.error("User preference could not be removed because no authenticated user is present."); return false; } else if (preference == null) { logger.error("User preference could not be removed because the provided preference key is null."); return false; } else { try { user.preferences().remove(preference); getWorkbenchSession().updateUser(user); logger.debug("User preference \"" + preference + "\" successfully removed."); return true; } catch ( Throwable error ) { logger.error("Error removing user preference \"" + preference + "\"", error); return false; } } } /** * Retrieves the registered User with the specified username. * * @param username The username of the user to be retrieved. * * @return The user with the specified username, if present. Returns null if no user exists with * this username, if the argument username is null, or an error occurs. */ public User getUserByUsername ( String username ) { if (username == null) { logger.error("User could not be retrieved because the provided username is null."); return null; } else { try { return User.findUser(username); } catch ( Throwable error ) { logger.error("Error retrieving user with username \"" + username + "\"", error); return null; } } } /** * Retrieves the registered User with the specified email address. * * @param email The email address of the user to be retrieved. * * @return The user with the specified email address, if present. Returns null if no user exists * with this email address, if the argument email address is null, or an error occurs. */ public User getUserByEmail ( String email ) { if (email == null) { logger.error("User could not be retrieved because the provided email address is null."); return null; } else { try { //return User.findUserByEmailAndRole(email, UserRole.STANDARD.toString()); return User.findUserByEmail(email); } catch ( Throwable error ) { logger.error("Error retrieving user with email address \"" + email + "\" and standard role.", error); return null; } } } /** * Determine whether the current has missing required profile information. The only thing * currently required is that STANDARD users must have institution and country information. * Other types of users will be ignored; including GUEST users who are NOT allowed to update * their profile information. * * @author Mona Wong * * @return true if user has missing info; FALSE otherwise. */ public boolean needProfileInfo () { User user = getAuthenticatedUser(); if (user == null) { return true; } else { String inst = user.getInstitution(); String country = user.getCountry(); //UserRole role = user.getRole(); return inst == null || inst.trim().isEmpty() || country == null || country.trim().isEmpty(); } } public boolean isAdminUser () { User user = getAuthenticatedUser(); UserRole role = (null == user)? null : user.getRole(); return (null != role && UserRole.ADMIN.equals(role)); } /** * Creates and registers a fully populated workbench User object for the * user with the specified information.It is assumed that the argument values have already been properly validated according to the client's particular business rules. * * @param username the username of the user attempting to register * @param firstName the first name of the user attempting to register * @param lastName the last name of the user attempting to register * @param email the email address of the user attempting to register * @param country the country * @param institution the primary institution with which the user * attempting to register is affiliated * @param httpSession * * @return the ValidationResult object representing the outcome * of the user account registration; null if an error * occurs * * @throws java.security.NoSuchAlgorithmException */ // This is called for iplant users. public ValidationResult registerUser ( String username, String email, String firstName, String lastName, String institution, String country, HttpSession httpSession ) throws NoSuchAlgorithmException { // Make up a random password. String password = "iPlant" + username + Calendar.getInstance().getTimeInMillis(); return doRegisterUser( username, password, email, firstName, lastName, institution, country, UserRole.STANDARD, null, httpSession); } public ValidationResult registerUser ( String username, String password, String email, String firstName, String lastName, String institution, String country, HttpSession httpSession ) throws NoSuchAlgorithmException { return doRegisterUser( username, password, email, firstName, lastName, institution, country, UserRole.STANDARD, null, httpSession); } public ValidationResult registerUser ( String username, String password, String email, String firstName, String lastName, String institution, String country, String comment, HttpSession httpSession ) throws NoSuchAlgorithmException { return doRegisterUser( username, password, email, firstName, lastName, institution, country, UserRole.STANDARD, comment, httpSession); } public ValidationResult registerUser ( String username, String password, String email, String firstName, String lastName, String institution, String country, UserRole role, HttpSession httpSession ) throws NoSuchAlgorithmException { return doRegisterUser( username, password, email, firstName, lastName, institution, country, role, null, httpSession); } private ValidationResult doRegisterUser ( String username, String password, String email, String firstName, String lastName, String institution, String country, UserRole role, String comment, HttpSession httpSession ) throws NoSuchAlgorithmException { if (StringUtils.isNullOrEmpty(username, true)) { logger.error("User account could not be created because the provided username is null."); return null; } else if (StringUtils.isNullOrEmpty(password, true)) { logger.error("User account could not be created because the provided password is null."); return null; } else if (StringUtils.isNullOrEmpty(country, true)) { logger.error("User account could not be created because the country is not specified."); return null; } try { User user = new User(); user.setUUID(UUID.randomUUID().toString()); user.setUsername(username.trim().toLowerCase()); user.setPassword(Workbench.getInstance().secureUserPassword(password.trim(), null)); user.setEmail(email.trim()); user.setFirstName(firstName.trim()); user.setLastName(lastName.trim()); user.setCountry(country.trim()); user.setRole(role); logger.info("doRegisterUser() comment = " + comment); if (comment != null) user.setComment(comment); // Instituion field is now required but we'll leave this test if (!StringUtils.isNullOrEmpty(institution, true)) { user.setInstitution(institution); } // register user Workbench workbench = getWorkbench(); ValidationResult result = workbench.registerNewUser(user); // log in newly registered user if (result.isValid()) { logger.debug("User account \"" + username + "\" (role \"" + role.toString() + "\") successfully created."); login(username, password, httpSession); } return result; } catch ( IOException | SQLException | UserAuthenticationException error ) { logger.error("Error creating account for user \"" + username + "\"", error); } return null; } public User getCorrespondingCipresUser ( String iplantName ) throws Exception { SSO sso = SSO.findBySsoUsername(iplantName); return (sso == null)? null : sso.getUser(); } /** * Creates and registers a fully populated workbench User object with a * randomized username, representing a guest user account. * * @deprecated *
     * NOTE:
     * CIPRES does not allow creating of Guest acccounts.  Thus, this method 
     * will be removed from future versions.
     * 
* * @param httpSession * * @return The ValidationResult object representing the outcome of the * guest account registration. Returns null if an error occurs. */ public ValidationResult registerGuestUser ( HttpSession httpSession ) { final String msg = "This method, registerGuestUser(HttpSession):ValidationResult, has been deprecated."; logger.error(msg); // logger.trace("BEGIN: registerGuestUser(HttpSession)::ValidationResult"); // // String guestName = "guest-" + Calendar.getInstance().getTimeInMillis(); // logger.trace("Guest name: " + guestName); // // // set password and email to numerical portion of guest username // String guestNumber = guestName.replaceAll("\\D*", ""); // // ValidationResult result = registerUser(guestName, guestNumber, guestNumber, // "Guest", "User", null, "US", // UserRole.GUEST, httpSession); // // WorkbenchSession wbSession = getWorkbenchSession(); // // if (result != null && result.isValid() && wbSession != null) // { // try // { // Folder guestFolder = wbSession.getFolderInstance(); // guestFolder.setLabel(GUEST_FOLDER_LABEL); // guestFolder.preferences().put(DESCRIPTION, GUEST_FOLDER_DESCRIPTION); // wbSession.saveFolder(guestFolder); // logger.trace("Default folder successfully created for guest user \"" + guestName + "\"."); // } // catch ( Throwable error ) // { // logger.error("Error creating default folder for guest user \"" + guestName + "\"", error); // } // } // // logger.trace("END: registerGuestUser(HttpSession)::ValidationResult"); // // return result; throw new RuntimeException(msg); } /** * Logs the specified user into the NGBW web application. * * @deprecated *
     * NOTE:
     * Logging in without a valid password is no longer allowed. This method 
     * will be removed from future versions.
     * 
* * @param username The username of the user attempting to log in. * * @return The WorkbenchSession object representing the newly activated * user session, if the user successfully passes authentication. * Returns null if an error occurs. * * @throws UserAuthenticationException if the user supplies an invalid * username and/or password. */ public WorkbenchSession login ( String username ) throws UserAuthenticationException { final String msg = "This method, SessionController.login(String):WorkbenchSession, has been deprecated."; logger.error(msg); //return doLogin(username, null, null, null); throw new RuntimeException(msg); } /** * Logs the specified user into the NGBW web application. * * @deprecated *
     * NOTE:
     * As of 2020/12/01, authenticating users with CyVerse is no longer supported. This method 
     * will be removed from future versions.
     * 
* * @param username the username of the user attempting to log in * @param cyverseUsername the iPlant/CyVerse username * @param httpSession the HttpSession associated with the user * * @return the WorkbenchSession object representing the newly activated * user session, if the user successfully passes authentication * * @throws UserAuthenticationException if the user supplies an invalid * username and/or password. */ public WorkbenchSession loginWithCyVerseCredential ( String username, String cyverseUsername, HttpSession httpSession ) throws UserAuthenticationException { // logger.debug("BEGIN: loginWithCyVerseCredential(String, String, HttpSession)::WorkbenchSession"); // WorkbenchSession ws = doLogin( // username, // username // null, // email // null, // password // httpSession, // HTTP Session // cyverseUsername); // CyVerse username // logger.debug("END: loginWithCyVerseCredential(String, String, HttpSession)::WorkbenchSession"); // return ws; final String msg = "This method, SessionController.loginWithCyVerseCredential(String):WorkbenchSession, has been deprecated."; logger.error(msg); throw new RuntimeException(msg); } public WorkbenchSession loginUserMasquerade ( String originalUserName, String targetUserName, HttpSession httpSession ) throws UserAuthenticationException { logger.debug("BEGIN: loginUserMasquerade(String, String, HttpSession)::WorkbenchSession"); logger.debug( String.format( "From username=[%s], To username=[%s]", originalUserName, targetUserName)); if (StringUtils.isNullOrEmpty(originalUserName, true) || StringUtils.isNullOrEmpty(targetUserName, true)) { logger.error("Could not masquerade a user."); return null; } else { try { User original = User.findUser(originalUserName); User target = User.findUser(targetUserName); if (original == null) { throw new WorkbenchException( String.format( "User '%s' not found.", originalUserName)); } else if (!original.isAdmin()) { return null; } if (target == null) { throw new WorkbenchException( String.format( "User '%s' not found.", targetUserName)); } // If the user has logged in with different browser or computer, // suspend that session (the session with other browser or computer). Workbench workbench = getWorkbench(); if (workbench.hasActiveSession(targetUserName)) { workbench.suspendSession(targetUserName); } workbenchSession = workbench.getSessionForMasqueradeUser(targetUserName); if (workbenchSession == null) { logger.error("The WorkbenchSession retrieved when attempting to authenticate " + "user \"" + targetUserName + "\" is null."); } else { workbenchSession.setHttpSession(httpSession); } logger.trace("BEGIN: loginUserMasquerade(String, String, HttpSession)::WorkbenchSession"); return workbenchSession; } catch ( Throwable t ) { logger.error(t.getMessage(), t); throw new UserAuthenticationException( "Sorry, there was a problem with login " + "process. Please try again.", t); } } } /** * Logs the specified user into the NGBW web application. * * @param username the username of the user attempting to log in * @param password the un-hashed password of the user attempting to log in * * @return The WorkbenchSession object representing the newly activated * user session, if the user successfully passes authentication. * Returns null if an error occurs. * * @throws UserAuthenticationException */ public WorkbenchSession login ( final String username, final String password ) throws UserAuthenticationException { if (StringUtils.isNullOrEmpty(password, true)) { logger.error("User could not be logged in because the provided password is null."); return null; } return doLogin(username, null, password, null, null); // username, email, password, http session, cyverse username } /** * Logs the specified user into the NGBW web application. * * @param username the username of the user attempting to log in * @param password the un-hashed password of the user attempting to log in * @param httpSession the HttpSession associated with the user * * @return The WorkbenchSession object representing the newly activated * user session, if the user successfully passes authentication. * Returns null if an error occurs. * * @throws UserAuthenticationException */ public WorkbenchSession login ( final String username, final String password, final HttpSession httpSession ) throws UserAuthenticationException { if (StringUtils.isNullOrEmpty(password, true)) { logger.error("User could not be logged in because the provided password is null."); return null; } return doLogin(username, null, password, httpSession, null); } /** * Logs the specified user into the NGBW web application. * * @param email the email of the user attempting to log in * @param password the un-hashed password of the user attempting to log in * @param httpSession the HttpSession associated with the user * * @return The WorkbenchSession object representing the newly activated * user session, if the user successfully passes authentication. * Returns null if an error occurs. * * @throws UserAuthenticationException */ public WorkbenchSession loginWithEmail ( final String email, final String password, final HttpSession httpSession ) throws UserAuthenticationException { if (StringUtils.isNullOrEmpty(password, true)) { logger.error("User could not be logged in because the provided password is null."); return null; } return doLogin(null, email, password, httpSession, null); // username, email, password, http session, cyverse username } /** * Authenticates user by using either the username or email address. * * @param username username * @param email user's email * @param password user's un-hashed password * @param httpSession the HttpSession * @param cyverseLogin {@code true} if the user is logging in with * iPlant (CyVerse) credentials, {@code false} * otherwise * * @return WorkbenchSession if the user is authenticated * successfully * * @throws UserAuthenticationException */ private WorkbenchSession doLogin ( String username, String email, String password, // un-hashed HttpSession httpSession, String cyverseUsername ) throws UserAuthenticationException { logger.debug("BEGIN: doLogin(String, String, String, HttpSession, String)::WorkbenchSession"); if (StringUtils.isNullOrEmpty(username, true) && StringUtils.isNullOrEmpty(email, true)) { logger.error("User could not be logged in because both provided username and email are null."); return null; } else { try { User user = User.findUser(username, email, true, true); // Generate UUID for the user if there is none. if (user != null) { if (StringUtils.isNullOrEmpty(username, true)) { username = user.getUsername(); } if (StringUtils.isNullOrEmpty(user.getUUID(), Boolean.TRUE)) { user.setUUID(UUID.randomUUID().toString()); user.save(); } logger.debug( String.format( "User found: ID=[%d] Username=[%s] Email=[%s]", user.getUserId(), user.getUsername(), user.getEmail())); } // If the user has logged in with different browser or computer, // suspend that session (the session with other browser or computer). Workbench workbench = getWorkbench(); //logger.debug("Checking for other active sessions ..."); if (workbench.hasActiveSession(username)) { logger.error("User \"" + username + "\" is attempting to log in, but " + "an active session already exists for this user. This session " + "is being suspended."); workbench.suspendSession(username); } // Authenticate the user with Workbench.getSession(). // if (cyverseUsername != null && !cyverseUsername.trim().isEmpty()) // { // workbenchSession = workbench.getSessionForCyVerseAuth( // username, // cyverseUsername); // } // else // { // workbenchSession = // (StringUtils.isNullOrEmpty(password, true))? // null : workbench.getSession(username, password); // } logger.debug("Authenticating the user by retrieving info from WorkbenchSession ..."); workbenchSession = (cyverseUsername != null && !cyverseUsername.trim().isEmpty())? workbench.getSessionForCyVerseAuth(username, cyverseUsername) : workbench.getSession(username, password); if (workbenchSession == null) { logger.error("The WorkbenchSession retrieved when attempting to authenticate " + "user \"" + username + "\" is null."); } else { logger.trace("This is where CIPRES can update user's password hashing algorithm."); workbenchSession.setHttpSession(httpSession); user = User.findUser(username, email, true, true); // if (Workbench.getInstance().isPhoenixApiModuleEnabled(Boolean.FALSE)) // { // try { // // Sync with Phoenix Bioinformatics if necessary. // CipresPhoenixUserAccountManager syncManager = new CipresPhoenixUserAccountManager(user, password); // syncManager.sync(Boolean.FALSE); // } catch ( Throwable t ) { // logger.error(t.getMessage(), t); // } // } // Award 1,000 CPU Hrs to non-US user (if necessary). try { if (!user.isUsUser()) { UserSuAllocationService.awardSu(user, user); } } catch ( Throwable t ) { logger.error( String.format( "Error awarding free %d SU to user [%d - %s]", Workbench.getInstance().getNonUsAnnualFreeAllocations(1_000), user.getUserId(), user.getUsername()), t); } } logger.debug("END: doLogin(String, String, String, HttpSession, String)::WorkbenchSession"); return workbenchSession; } catch ( UserAuthenticationException error ) { logger.error("Error authenticating user \"" + username + "\"", error); throw new UserAuthenticationException("Sorry, the information you entered " + "did not match our records! Please try again.", error); } catch ( IOException | SQLException error ) { logger.error("Error authenticating user \"" + username + "\"", error); throw new UserAuthenticationException("Sorry, there was a problem with login " + "process. Please try again.", error); } catch ( Throwable t ) { logger.error(t.getMessage(), t); throw new UserAuthenticationException("Sorry, there was a problem with login " + "process. Please try again.", t); } } } /** * Retrieves the active WorkbenchSession owned by the specified user, if * the user is currently logged into the NGBW web application. * * @param username The username of the user whose active * session is to be retrieved. * @param hashedPassword The hashed password of the user whose * active session is to be retrieved. * * @return The WorkbenchSession object representing the currently active * user session, if the user successfully passes authentication. * Returns null if an error occurs. * * @throws UserAuthenticationException if the user supplies hashedPassword invalid * username and/or (encrypted) password */ public WorkbenchSession getActiveSession ( String username, String hashedPassword ) throws UserAuthenticationException { if (username == null) { logger.error("User's active session could not be retrieved " + "because the provided username is null."); return null; } else if (hashedPassword == null) { logger.error("User's active session could not be retrieved " + "because the provided password is null."); return null; } else { try { WorkbenchSession session = getWorkbench().getActiveSession(username, hashedPassword); if (session == null) { logger.error("No active WorkbenchSession currently exists for " + "user \"" + username + "\"."); return null; } else { workbenchSession = session; logger.debug("Currently active session successfully retrieved for user \"" + username + "\"."); return workbenchSession; } } catch ( UserAuthenticationException error ) { logger.error("Error retrieving active session for user \"" + username + "\"", error); throw new UserAuthenticationException("Sorry, the information you entered " + "did not match our records. Please try again.", error); } catch ( Throwable error ) { logger.error("Error retrieving active session for user \"" + username + "\"", error); return null; } } } /** * Logs the current authenticated user out of the NGBW web application. * Any remaining WorkbenchSession reference must still be cleaned up, * however. * * @return true if the user is successfully logged out, false otherwise. */ public boolean logout () { logger.trace("BEGIN: logout()::boolean"); boolean status = Boolean.FALSE; String username = getAuthenticatedUsername(); if (StringUtils.isNullOrEmpty(username, true)) { logger.error("The current user could not be logged out because the user's username is null."); status = Boolean.FALSE; } else { try { Workbench workbench = getWorkbench(); if (workbench.hasActiveSession(username)) { //logger.trace(String.format("User [%s] has active session.", username)); workbench.suspendSession(username); workbenchSession = null; status = Boolean.TRUE; logger.debug(String.format("User [%s] successfully logged out.", username)); } else { logger.error("The current user could not be logged out because " + "the user has no active session."); workbenchSession = null; status = Boolean.FALSE; } } catch ( Throwable error ) { logger.error("Error logging out user \"" + username + "\"", error); status = Boolean.FALSE; } } logger.trace("END: logout()::boolean"); return status; } /** * Changes the specified user's password to the specified new value. * * @param username The username of the user whose password is to be * changed. * @param newPassword The new password to change to. * * @return true if the user's password is successfully changed, false * otherwise. */ public boolean changePassword ( final String username, final String newPassword ) { if (username == null) { logger.error("The specified user's password could not be changed because the provided username is null."); return false; } else if (newPassword == null) { logger.error("The specified user's password could not be changed because the provided new password is null."); return false; } else { try { User user = getWorkbench().resetPasswordAdmin(username, newPassword); if (Workbench.getInstance().isPhoenixApiModuleEnabled(Boolean.FALSE)) { try { CipresPhoenixUserAccountManager syncManager = new CipresPhoenixUserAccountManager(user, newPassword); syncManager.sync(Boolean.TRUE); } catch ( Throwable t ) { logger.error(t.getMessage(), t); } } return true; } catch ( Throwable error ) { logger.error("Error changing user \"" + username + "\"'s password", error); return false; } } } /** * Updates an existing user's password with the specified new password. * * It is assumed that the argument values have already been properly * validated according to the client's particular business rules. * * @param oldPassword The user's current password. * @param newPassword The user's new password. * * @return true if the user's password was successfully updated, * false otherwise * * @throws UserAuthenticationException if the user supplies an invalid * current password. */ public boolean editPassword ( final String oldPassword, final String newPassword ) throws UserAuthenticationException { User user = getAuthenticatedUser(); if (user == null) { logger.error("User's password could not be updated because no " + "authenticated user is present."); return false; } else if (StringUtils.isNullOrEmpty(oldPassword, true)) { logger.error("User\"" + user.getUsername() + "\"'s password could not " + "be updated because the provided old password is null."); return false; } else if (StringUtils.isNullOrEmpty(newPassword, true)) { logger.error("User\"" + user.getUsername() + "\"'s password could not " + "be updated because the provided new password is null."); return false; } else if (Workbench.getInstance().hasInvalidChars(newPassword, false)) { logger.error("User\"" + user.getUsername() + "\"'s password contains " + "one or more unsupported characters."); return false; } else { try { // Actually rehash the new password and save it to database. getWorkbenchSession().resetPassword(oldPassword, newPassword); logger.debug("User \"" + user.getUsername() + "\"'s password successfully updated."); return true; } catch (UserAuthenticationException error) { logger.error("Error updating user \"" + user.getUsername() + "\"'s password", error); throw new UserAuthenticationException("Sorry, the information you entered " + "did not match our records. Please try again.", error); } catch (Throwable error) { logger.error("Error updating user \"" + user.getUsername() + "\"'s password", error); return false; } } } /** * Updates an existing user with the specified information. It is assumed * that the argument values have already been properly validated according * to the client's particular business rules. * * @param firstName The first name of the user to be edited. * @param lastName The last name of the user to be edited. * @param email The email address of the user to be edited. * @param institution The primary institution with which the user to be * edited is affiliated. * @param country * @param account * * @return true if the user was successfully updated, false otherwise */ public ValidationResult editUser ( String email, String firstName, String lastName, String institution, String country, String account ) { User user = getAuthenticatedUser(); ValidationResult result = new ValidationResult(); if (user == null) { logger.error("User could not be edited because no authenticated user is present."); result.addError("User could not be edited because no authenticated user is present."); return result; } else if (user.getRole() == UserRole.GUEST) { result.addError("Guest accounts can't be modified. Please logout and register for a regular account."); return result; } try { user = User.findUser(user.getUsername()); String oldEmail = user.getEmail(); user.setEmail(email); user.setFirstName(firstName); user.setLastName(lastName); if (!StringUtils.isNullOrEmpty(institution, true)) { user.setInstitution(institution); } else { user.setInstitution(null); } if (!StringUtils.isNullOrEmpty(country, true)) { user.setCountry(country); } else { user.setCountry(null); } // if (user.getRole() == UserRole.GUEST) // { // result.addError("Guest accounts can't be modified. Please logout and register for a regular account."); // return result; // } /* * Commented out following code because we now allow admin to change their own account * info also. if (user.getRole() != UserRole.STANDARD) { result.addError("Only * 'standard' Cipres web site accounts can be modified here. Your account has role " + * user.getRole().toString()); return result; } */ // Make sure email isn't changed to email address already in use by another STANDARD user. User userFromEmail = User.findUserByEmail(user.getEmail(), user.getRole()); if (userFromEmail != null && userFromEmail.getUserId() != user.getUserId()) { result.addError("A user with this email: " + user.getEmail() + " already exists!"); return result; } // TODO: took this out. We aren't letting users set their own tg account. user.setAccount("teragrid", account); // update user getWorkbenchSession().updateUser(user); logger.debug("User \"" + user.getUsername() + "\" successfully edited."); if (!oldEmail.equals(user.getEmail())) RegistrationManager.getRegistrationBlacklistManager().addToTheList(oldEmail); return result; } catch ( Throwable error ) { logger.error("Error editing user \"" + user.getUsername() + "\"", error); result.addError("Error editing user \"" + user.getUsername() + "\""); return result; } } protected String getUsernameString () { String username = null; try { if (workbenchSession != null) { username = workbenchSession.getUsername(); } } catch ( IOException | SQLException error ) { logger.error(error.getMessage(), error); } return (username == null)? "" : (username + " - "); } protected String buildMessage ( Throwable error, String message ) { return String.format("%s%s: %s", getUsernameString(), message, error.getMessage()); } }