Package eu.planets_project.ifr.core.users.gui

Source Code of eu.planets_project.ifr.core.users.gui.UserBackingBean

package eu.planets_project.ifr.core.users.gui;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import eu.planets_project.ifr.core.security.api.model.Role;
import eu.planets_project.ifr.core.security.api.model.User;
import eu.planets_project.ifr.core.security.api.services.RoleManager;
import eu.planets_project.ifr.core.security.api.services.UserManager;
import eu.planets_project.ifr.core.security.api.services.RoleManager.RoleNotFoundException;
import eu.planets_project.ifr.core.security.api.services.UserManager.UserNotFoundException;
import eu.planets_project.ifr.core.security.api.services.UserManager.UserNotValidException;
import eu.planets_project.ifr.core.security.impl.model.AddressImpl;
import eu.planets_project.ifr.core.security.impl.model.UserImpl;
import eu.planets_project.ifr.core.security.impl.services.RoleManagerImpl;
import eu.planets_project.ifr.core.security.impl.services.UserManagerImpl;

/**
* This is the controller class for the rewritten User Administration JSF web application.
*
* @author <a href="mailto:carl.wilson@bl.uk">Carl Wilson</a>
*
*/
public class UserBackingBean {
  private static Logger log = Logger.getLogger(UserBackingBean.class.getName());
  private enum Context { MYPROFILE, OTHERPROFILE, NEWUSER, LIST };

  private Context _context;
  // The name of the currently logged in user, taken from session
  private String username;
  // The user profile to edit
  private User user = null;
  // A list of all if users used by the admin list page
  private List<User> allUsers = null;
  private List<Role> allRoles = new ArrayList<Role>();

  private String originalPassword = null;
  private String userPassword = null;
  private String confirmPassword = null;
 
  private List<SelectItem> availableRoles = new ArrayList<SelectItem>();
  private String[] userRoles = null;

  private RoleManager roleManager = RoleManagerImpl.getPlanetsRoleManager();
  private UserManager userManager = UserManagerImpl.getPlanetsUserManager();;

  /**
   * Constructor for the UseBackingBean, this populates the user manager and user members
   */
  public UserBackingBean() {
    // Assume context is editing own profile
    this._context = UserBackingBean.Context.MYPROFILE;
   
    // We'll get the remote username, this doesn't change and we assume
    // it remains the same for the session
    if (null != this.getExternalContext().getRemoteUser()) {
      // Get the username
      this.username = this.getExternalContext().getRemoteUser();
      this.loadUser(username);
      // If it's an admin user we may need all of the roles
      if (this.getIsAdmin()) {
        this.allRoles = roleManager.getAllRoles();
        this.availableRoles.clear();
        for (Role role : this.allRoles) {
          this.availableRoles.add(new SelectItem(role.getName(), role.getName()));
        }
      }
    } else {
      log.info("getRemoteUser returned null, user not logged in");
    }
  }

  /**
   * Returns the user object.
   *
   * @return The currently loaded user object
   */
  public User getUser() {
    return this.user;
  }

  /**
   * Setter for the user object.
   *
   * @param value A User ref
   */
  public void setUser(User value) {
    this.user = value;
  }

  /**
   *
   * @return all users as a List of User interface refs
   */
  public List<User> getAllUsers() {
    return this.allUsers;
  }
  /**
   *
   * @param value A new List of User refs
   */
  public void setAllUsers(List<User> value) {
    this.allUsers = value;
  }

  /**
   * The cancel method simply handles the pressing of the cancel button by the user
   * when editing a profile.  We simply reload the user and redisplay.
   * @return the canceledit JSF outcome
   *
   * @throws UserNotFoundException When the user cannot be found in the database
   */
  public String cancelEdit() throws UserNotFoundException {
    log.info("CANCEL EDIT");
    this.loadUser(this.user.getUsername());
    String retVal = "canceledit";
    log.info("Outcome " + retVal);
    return retVal;
  }

  /**
   *
   * @return the cancelnewuser status
   */
//  public String cancelNewUser() {
//    log.info("CANCEL NEW USER");
//    this.loadUser(username);
//    String retVal = "cancelnewuser";
//    log.info("Outcome " + retVal);
//    return retVal;
//  }

  /**
   * Getter for the original password.
   *
   * @return  The original password from the user loaded at construction
   */
  public String getOriginalPassword() {
    return this.originalPassword;
  }

  /**
   *
   * @param password the original password to set
   */
  public void setOriginalPassword(String password) {
    this.originalPassword = password;
  }

  /**
   * Getter for the confirm password member (used to handle the hashing).
   *
   * @return the confirm password value from the web form
   */
  public String getConfirmPassword() {
    return this.confirmPassword;
  }

  /**
   * Setter for the confirm password.
   *
   * @param password the confirm password to set
   */
  public void setConfirmPassword(String password) {
    this.confirmPassword = password;
  }

  /**
   * Getter for the confirm password member (used to handle the hashing).
   *
   * @return the confirm password value from the web form
   */
  public String getUserPassword() {
    return this.userPassword;
  }

  /**
   * Setter for the confirm password.
   *
   * @param password the user password to set
   */
  public void setUserPassword(String password) {
    this.userPassword = password;
  }

  /**
   *
   * @return true if loaded user is in the admin role
   */
  public boolean getIsAdmin() {
    return this.getExternalContext().isUserInRole("admin");
  }

  /**
   * @return true if user name editing is disabled
   */
  public boolean getDisableEditName() {
    return !(this._context == UserBackingBean.Context.NEWUSER);
  }
  /**
   * Method to save the user details.
   *
   * @return  An outcome string for use in navigation
   *       saved - user was successfully saved
   *
   * @throws  NoSuchAlgorithmException
   * @throws  UserNotFoundException
   */
  public String saveUser() throws NoSuchAlgorithmException, UserNotFoundException {
    log.info("SAVE USER");
    // The user has changed the password so we need to change the user bean
    // password with the hashed password value
    if (this.passwordChanged()) {
      // the user has changed the password, need to check the confirmed version
      if (!this.passwordConfirmed()) {
        log.info("Password not properly confirmed so getting out");
        // If it's not confirmed properly then go to confirm outcome
        return "badpassword";
      }
      // We're confirmed so let's populate the user bean with the hash
      this.user.hashPassword(userPassword);
      this.userPassword = this.user.getPassword();
      this.confirmPassword = this.userPassword;
      this.originalPassword = this.userPassword;
    }

    try {
     
    } catch (Exception e) {
      log.info("SaveUser Exception caught");
      e.printStackTrace();
    }
    this.arrangeUserRoles();
    userManager.saveUser(this.user);
    String retVal = this.isEditingSelf() ? "savedownprofile" : "savedotherprofile";
    this.loadUser(this.username);
    return retVal;
  }

  /**
   *
   * @return the jsf outcome
   * @throws UserNotValidException
   * @throws UserNotFoundException
   * @throws NoSuchAlgorithmException
   */
  public String addUser() throws UserNotValidException, UserNotFoundException, NoSuchAlgorithmException {
    // The user has changed the password so we need to change the user bean
    // password with the hashed password value
    if (!this.passwordConfirmed()) {
      log.info("Password not confirmed properly so bailing");
      // If it's not confirmed properly then go to confirm outcome
      return "badpassword";
    }

    // We're confirmed so let's populate the user bean with the hash
    this.user.hashPassword(userPassword);
    this.userPassword = this.user.getPassword();
    this.confirmPassword = this.userPassword;
    this.originalPassword = this.userPassword;
    // Check user name is still available
    if (!userManager.isUsernameAvailable(user.getUsername())) {
      log.info("UserManager says name " + user.getUsername() + " is not available so bailing");
      return "usernamenotavailable";
    }
    //log.info("Arranging roles for new user");
    //this.arrangeUserRoles();
    userManager.addUser(this.user);
    // A bit convoluted because of Role persistence problems
    // first copy the user roles
    String[] roleCopy = this.userRoles.clone();
    // Now load the user
    this.loadUser(this.user.getUsername());
    // Now copy back and return the roles then save the user
    this.userRoles = roleCopy.clone();
    String retVal = this.saveUser();
    log.info("Outcome " + retVal);
    return retVal;
  }

  private boolean passwordChanged() {
      // Check the password field has been filled in:
//        if( this.userPassword.trim().equals("") ) return false;
//        if( this.confirmPassword.trim().equals("") ) return false;
    // Check that all of the password fields are the same
    //(the user hasn't changed either password field on the form
    return !(this.originalPassword.equals(this.confirmPassword&& this.originalPassword.equals(this.userPassword));
  }

  /**
   * Tests whether the user's password and confirm password are equal
   *
   * @return true if password == confirm password, otherwise false
   */
  public boolean passwordConfirmed() {
    return (this.confirmPassword.equals(this.userPassword));
  }

  private void loadUser(String name) {
    try {
      this.user = userManager.getUserByUsername(name);
    } catch (UserNotFoundException e) {
      log.info("user " + this.username + " tried to load user " + name);
      log.info("No record for " + name + "found in if user database");
      e.printStackTrace();
      return;
    }
//        this.userPassword = this.confirmPassword = "";
        this.userPassword = this.confirmPassword = this.originalPassword = this.user.getPassword();
    this.userRoles = this.user.rolesAsStrings();
  }
 
  /**
   * @return true if list to be refreshed
   */
  public boolean getRefreshUserList() {
    this._context = UserBackingBean.Context.LIST;
    this.loadAllUsers();
    return true;
  }
  /**
   * @param refresh the desired refresh state
   */
  public void setRefreshUserList(boolean refresh) {
  }

  private void loadAllUsers() {
    this.allUsers = userManager.getUsers();
  }

  /**
   *
   * @return the jsf outcome
   */
  public String prepareNewUser() {
    this._context = UserBackingBean.Context.NEWUSER;
    this.user = new UserImpl("");
    this.user.setAddress(new AddressImpl());
    this.user.setAccountEnabled(true);
    this.userRoles = new String[1];
    this.userRoles[0] = "user";
    return "newuser";
  }

  /**
   *
   * @return the jsf outcome
   * @throws UserNotFoundException
   */
  public String editUserByName() throws UserNotFoundException {
    this._context = UserBackingBean.Context.OTHERPROFILE;
    Object value = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("userToEdit");
    String userToEdit = value.toString();
    this.loadUser(userToEdit);
    return "editexistinguser";
  }

  private ExternalContext getExternalContext() {
    log.info("UserBackingBean::getExternalContext()");
    return FacesContext.getCurrentInstance().getExternalContext();
  }

  /**
   *
   * @param context the context
   * @param toValidate the component to validate
   * @param value the value
   */
  public void validateUsername(FacesContext context,
      UIComponent toValidate,
      Object value) {
    String username = (String) value;
    boolean avail =  userManager.isUsernameAvailable(username);
    if (avail != true) {
      ((UIInput)toValidate).setValid(false);
      FacesMessage message = new FacesMessage("Username not available.");
      context.addMessage(toValidate.getClientId(context), message);
    }
  }

  /**
   *
   * @param context the context
   * @param toValidate the component to validate
   * @param value the value
   */
  public void validateEmail(FacesContext context,
      UIComponent toValidate,
      Object value) {
    String email = (String) value;
    Pattern patt = Pattern.compile("^[A-Za-z0-9](([_\\.\\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\\.\\-]?[a-zA-Z0-9]+)*)\\.([A-Za-z]{2,})$");
    Matcher match = patt.matcher(email);
    if(!match.find()) {
      ((UIInput)toValidate).setValid(false);
      FacesMessage message = new FacesMessage("Invalid email address.");
      context.addMessage(toValidate.getClientId(context), message);
    }
  }

  /**
   * @param roles the roles to set
   */
  public void setUserRoles(String[] roles) {
    this.userRoles = Arrays.asList(roles).toArray(new String[]{});
  }

  private void arrangeUserRoles() {
    // TODO: Look at improving this method
    // Now this is convoluted and their must be a better way of doing it
    // BUT I ran into consistent persistence problems (transaction based) when I tried to do
    // it any other way SO
    try {
      // We take a copy of the hash set (can't edit it and work on it at the same time)
      Set<Role> oldUserRoles = new HashSet<Role>();
      for (Role role : this.user.getRoles()) {
        oldUserRoles.add(role);
      }

      // Now cycle through the users roles
      for (Role userRole : oldUserRoles) {
        boolean roleFound = false;
        // And the role names from the profile edit page
        for (String roleName : this.userRoles) {
          // Do a case insensitive check and set the roleFound flag
          if (userRole.getName().compareToIgnoreCase(roleName) == 0) {
            roleFound = true;
            break;
          }
        }
        // If the role was NOT found then remove it from the user
        if (!roleFound) {
          this.user.removeRole(userRole);
        }
      }
     
      // Now copy the remaining user Roles again
      Set<Role> newUserRoles = new HashSet<Role>();
      for (Role role :this.user.getRoles()) {
        newUserRoles.add(role);
      }
     
      // Then go through the String array from the edit profile page control
      for (String newRole : this.userRoles) {
        boolean roleFound = false;
          // Cycle through the remaining user roles
          for (Role userRole : newUserRoles) {
            // If role found set flag and break
            if (userRole.getName().compareToIgnoreCase(newRole) == 0) {
              log.info("ROLE FOUND");
              roleFound = true;
              break;
            }
          }
          // If the role wasn't found then add it to the user
          if (!roleFound) {
            Role userRole = roleManager.getRoleByName(newRole);
            this.user.addRole(userRole);
          }
      }
    } catch (RuntimeException e) {
      // Catch for Runtime Exceptions from the roleManager
      log.info("Caught exception " + e.getMessage());
      e.printStackTrace();
    } catch (RoleNotFoundException e) {
      log.info("Couldn't load Role from db");
    }
  }
  /**
   * @return the roles
   */
  public String[] getUserRoles() {
    return Arrays.asList(userRoles).toArray(new String[]{});
  }

  /**
   * @param allRoles the allRoles to set
   */
  public void setAllRoles(List<Role> allRoles) {
    this.allRoles = allRoles;
  }

  /**
   * @return the allRoles
   */
  public List<Role> getAllRoles() {
    return allRoles;
  }

  /**
   * @param availableRoles the availableRoles to set
   */
  public void setAvailableRoles(List<SelectItem> availableRoles) {
    this.availableRoles = availableRoles;
  }

  /**
   * @return the availableRoles
   */
  public List<SelectItem> getAvailableRoles() {
    return availableRoles;
  }

  /**
   *
   * @return jsf outcome
   */
  public String deleteUser() {
    // first check that the user is not trying to delete their own account
    if (this.isEditingSelf()) {
      log.info("user " + this.username + " tried to delete their own account");
      return "deleteself";
    }
    // OK lets use the user manager to remove this user
    userManager.removeUser(this.user.getId());

    this.loadUser(username);
    log.info("deleteuser");
    return "deleteuser";
  }
 
  private boolean isEditingSelf() {
    return (this._context == UserBackingBean.Context.MYPROFILE);
  }
}
TOP

Related Classes of eu.planets_project.ifr.core.users.gui.UserBackingBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.