package org.gbif.ipt.action.admin; import org.gbif.ipt.action.POSTAction; import org.gbif.ipt.config.AppConfig; import org.gbif.ipt.model.User; import org.gbif.ipt.model.User.Role; import org.gbif.ipt.service.AlreadyExistingException; import org.gbif.ipt.service.DeletionNotAllowedException; import org.gbif.ipt.service.DeletionNotAllowedException.Reason; import org.gbif.ipt.service.admin.RegistrationManager; import org.gbif.ipt.service.admin.UserAccountManager; import org.gbif.ipt.struts2.SimpleTextProvider; import org.gbif.ipt.validation.UserValidator; import java.io.IOException; import java.util.List; import com.google.inject.Inject; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; /** * The Action responsible for all user input relating to the user accounts in the IPT. */ public class UserAccountsAction extends POSTAction { // logging private static final Logger LOG = Logger.getLogger(UserAccountsAction.class); private static final long serialVersionUID = 8892204508303815998L; private static final int PASSWORD_LENGTH = 8; private final UserAccountManager userManager; private final UserValidator validator = new UserValidator(); private User user; private String password2; private boolean resetPassword; private boolean newUser; private List<User> users; @Inject public UserAccountsAction(SimpleTextProvider textProvider, AppConfig cfg, RegistrationManager registrationManager, UserAccountManager userManager) { super(textProvider, cfg, registrationManager); this.userManager = userManager; } @Override public String delete() { if (getCurrentUser().getEmail().equalsIgnoreCase(id)) { // cant remove logged in user addActionError(getText("admin.user.deleted.current")); } else { try { User removedUser = userManager.delete(id); if (removedUser == null) { return NOT_FOUND; } userManager.save(); addActionMessage(getText("admin.user.deleted")); return SUCCESS; } catch (DeletionNotAllowedException e) { if (Reason.LAST_ADMIN == e.getReason()) { addActionError(getText("admin.user.deleted.lastadmin")); } else if (Reason.LAST_RESOURCE_MANAGER == e.getReason()) { addActionError(getText("admin.user.deleted.lastmanager", new String[] {e.getMessage()})); } else if (Reason.IS_RESOURCE_CREATOR == e.getReason()) { // TODO i18n addActionError("The User cannot be deleted as it is the creator for the following resources: " + e.getMessage() + " Consider downgrading the User's role, as an alternative action."); } else { addActionError(getText("admin.user.deleted.error")); } } catch (IOException e) { addActionError(getText("admin.user.cantSave") + ": " + e.getMessage()); } } return INPUT; } public String getPassword2() { return password2; } public String getNewUser() { return newUser ? "yes" : "no"; } // Getters / Setters follow public User getUser() { return user; } public List<User> getUsers() { return users; } public String list() { users = userManager.list(); return SUCCESS; } @Override public void prepare() { super.prepare(); if (id == null) { newUser = true; } else { // modify copy of existing user - otherwise we even change the proper instances when canceling the request or // submitting non validating data user = userManager.get(id); } // if no id was submitted we wanted to create a new account // if an invalid email was entered, it gets stored in the id field and obviously userManager above cant find a // matching user. // in that case again provide a new, empty user instance if (user == null) { // reset id id = null; // create new user user = new User(); newUser = true; } else { try { user = (User) user.clone(); } catch (CloneNotSupportedException e) { LOG.error("An exception occurred while retrieving user: " + e.getMessage(), e); } } } @Override public String save() { try { if (id == null) { userManager.create(user); addActionMessage(getText("admin.user.added")); } else if (resetPassword) { String newPassword = RandomStringUtils.random(PASSWORD_LENGTH, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); user.setPassword(newPassword); userManager.save(user); addActionMessage(getText("admin.user.passwordChanged", new String[] {user.getEmail(), newPassword})); } else { if (userManager.get(user.getEmail()).getRole() == Role.Admin && user.getRole() != Role.Admin && userManager.list(Role.Admin).size() < 2) { addActionError(getText("admin.user.changed.current")); return INPUT; } if (user.getEmail().equals(getCurrentUser().getEmail())) { getCurrentUser().setRole(user.getRole()); } userManager.save(user); if (getCurrentUser().getRole() != Role.Admin) { return HOME; } addActionMessage(getText("admin.user.changed")); } return SUCCESS; } catch (IOException e) { LOG.error("The user change couldnt be saved: " + e.getMessage(), e); addActionError(getText("admin.user.saveError")); addActionError(e.getMessage()); return INPUT; } catch (AlreadyExistingException e) { addActionError(getText("admin.user.exists", new String[] {user.getEmail()})); // resetting user user = new User(); return INPUT; } } public void setPassword2(String password2) { this.password2 = password2; } public void setResetPassword(String pass) { this.resetPassword = StringUtils.trimToNull(pass) != null; } public void setUser(User user) { this.user = user; } public void setUsers(List<User> users) { this.users = users; } @Override public void validateHttpPostOnly() { // only validate on form submit ignoring list views // && users == null validator.validate(this, user); // check 2nd password if (newUser && StringUtils.trimToNull(user.getPassword()) != null && !user.getPassword().equals(password2)) { addFieldError("password2", getText("validation.password2.wrong")); password2 = null; user.setPassword(null); } } }