NIHVIVO-2279 Implement account editing and password change.
This commit is contained in:
parent
d6bacf0c95
commit
a1915c8398
22 changed files with 1006 additions and 223 deletions
|
@ -3,8 +3,10 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.controller.accounts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -18,6 +20,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
|
@ -32,6 +35,12 @@ import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
|||
public abstract class UserAccountsPage {
|
||||
private static final Log log = LogFactory.getLog(UserAccountsPage.class);
|
||||
|
||||
/**
|
||||
* After the account is created, or the password is reset, the user has this
|
||||
* many days to repond to the email.
|
||||
*/
|
||||
protected static final int DAYS_TO_USE_PASSWORD_LINK = 90;
|
||||
|
||||
protected final VitroRequest vreq;
|
||||
protected final ServletContext ctx;
|
||||
protected final OntModel userAccountsModel;
|
||||
|
@ -82,6 +91,17 @@ public abstract class UserAccountsPage {
|
|||
return (value != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Treat the presence of a certain parameter, with a desired value, as a
|
||||
* boolean flag.
|
||||
*
|
||||
* An example would be radio buttons with values of "yes" and
|
||||
* "no". The expected value would be "yes".
|
||||
*/
|
||||
protected boolean isParameterAsExpected(String key, String expected) {
|
||||
return expected.equals(getStringParameter(key, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of all known PermissionSets.
|
||||
*/
|
||||
|
@ -107,12 +127,25 @@ public abstract class UserAccountsPage {
|
|||
map.put("add", UrlBuilder.getUrl("/accountsAdmin/add"));
|
||||
map.put("delete", UrlBuilder.getUrl("/accountsAdmin/delete"));
|
||||
map.put("createPassword", UrlBuilder.getUrl("/accounts/createPassword"));
|
||||
map.put("resetPassword", UrlBuilder.getUrl("/accounts/resetPassword"));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
protected static String editAccountUrl(String uri) {
|
||||
return UrlBuilder.getUrl("/accountsAdmin/edit",
|
||||
new ParamMap("editAccount", uri));
|
||||
return UrlBuilder.getUrl("/accountsAdmin/edit", new ParamMap(
|
||||
"editAccount", uri));
|
||||
}
|
||||
|
||||
protected Date figureExpirationDate() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.add(Calendar.DATE, DAYS_TO_USE_PASSWORD_LINK);
|
||||
return c.getTime();
|
||||
}
|
||||
|
||||
protected boolean checkPasswordLength(String pw) {
|
||||
return pw.length() >= UserAccount.MIN_PASSWORD_LENGTH
|
||||
&& pw.length() <= UserAccount.MAX_PASSWORD_LENGTH;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,8 +68,9 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
selectedRoleUri = getRoleChoices();
|
||||
associateWithProfile = getAssociateFlag();
|
||||
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
||||
associateWithProfile = isParameterAsExpected(
|
||||
PARAMETER_ASSOCIATE_WITH_PROFILE, "yes");
|
||||
|
||||
strategy.parseAdditionalParameters();
|
||||
}
|
||||
|
@ -126,22 +127,6 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
strategy.notifyUser();
|
||||
}
|
||||
|
||||
/** What role are they asking for? */
|
||||
private String getRoleChoices() {
|
||||
String[] roles = vreq.getParameterValues(PARAMETER_ROLE);
|
||||
if ((roles == null) || (roles.length == 0)) {
|
||||
return "";
|
||||
} else {
|
||||
return roles[0];
|
||||
}
|
||||
}
|
||||
|
||||
/** Are they associating with an Individual profile? */
|
||||
private boolean getAssociateFlag() {
|
||||
return "yes".equals(getStringParameter(
|
||||
PARAMETER_ASSOCIATE_WITH_PROFILE, "no"));
|
||||
}
|
||||
|
||||
public final ResponseValues showPage() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ import static javax.mail.Message.RecipientType.TO;
|
|||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -25,7 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
|||
public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
||||
protected final UserAccountsAddPage page;
|
||||
|
||||
public static UserAccountsAddPageStrategy getInstance(VitroRequest vreq,
|
||||
public static UserAccountsAddPageStrategy getInstance(VitroRequest vreq,
|
||||
UserAccountsAddPage page, boolean emailEnabled) {
|
||||
if (emailEnabled) {
|
||||
return new EmailStrategy(vreq, page);
|
||||
|
@ -34,7 +32,8 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
}
|
||||
}
|
||||
|
||||
public UserAccountsAddPageStrategy(VitroRequest vreq, UserAccountsAddPage page) {
|
||||
public UserAccountsAddPageStrategy(VitroRequest vreq,
|
||||
UserAccountsAddPage page) {
|
||||
super(vreq);
|
||||
this.page = page;
|
||||
}
|
||||
|
@ -57,7 +56,6 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
|
||||
private static class EmailStrategy extends UserAccountsAddPageStrategy {
|
||||
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
|
||||
private static final int DAYS_TO_ACTIVATE_ACCOUNT = 90;
|
||||
|
||||
private boolean sentEmail;
|
||||
|
||||
|
@ -81,12 +79,6 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
u.setPasswordLinkExpires(figureExpirationDate().getTime());
|
||||
u.setStatus(Status.INACTIVE);
|
||||
}
|
||||
|
||||
private Date figureExpirationDate() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.add(Calendar.DATE, DAYS_TO_ACTIVATE_ACCOUNT);
|
||||
return c.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addMoreBodyValues(Map<String, Object> body) {
|
||||
|
@ -117,9 +109,9 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
String email = page.getAddedAccount().getEmailAddress();
|
||||
String hash = page.getAddedAccount()
|
||||
.getPasswordLinkExpiresHash();
|
||||
String relativeUrl = UrlBuilder.getUrl(CREATE_PASSWORD_URL, "user",
|
||||
email, "key", hash);
|
||||
|
||||
String relativeUrl = UrlBuilder.getUrl(CREATE_PASSWORD_URL,
|
||||
"user", email, "key", hash);
|
||||
|
||||
URL context = new URL(vreq.getRequestURL().toString());
|
||||
URL url = new URL(context, relativeUrl);
|
||||
return url.toExternalForm();
|
||||
|
@ -127,7 +119,7 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
return "error_creating_password_link";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean wasPasswordEmailSent() {
|
||||
return sentEmail;
|
||||
|
@ -156,10 +148,8 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
|
||||
@Override
|
||||
protected void parseAdditionalParameters() {
|
||||
initialPassword = getStringParameter(
|
||||
PARAMETER_INITIAL_PASSWORD, "");
|
||||
confirmPassword = getStringParameter(
|
||||
PARAMETER_CONFIRM_PASSWORD, "");
|
||||
initialPassword = getStringParameter(PARAMETER_INITIAL_PASSWORD, "");
|
||||
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -184,6 +174,8 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
|||
protected void addMoreBodyValues(Map<String, Object> body) {
|
||||
body.put("initialPassword", initialPassword);
|
||||
body.put("confirmPassword", confirmPassword);
|
||||
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
|
||||
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,12 +9,15 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
|
||||
/**
|
||||
* Parcel out the different actions required of the Administrators portion of the UserAccounts GUI.
|
||||
* Parcel out the different actions required of the Administrators portion of
|
||||
* the UserAccounts GUI.
|
||||
*/
|
||||
public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
||||
private static final Log log = LogFactory
|
||||
|
@ -64,7 +67,9 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
|||
|
||||
private ResponseValues handleEditRequest(VitroRequest vreq) {
|
||||
UserAccountsEditPage page = new UserAccountsEditPage(vreq);
|
||||
if (page.isSubmit() && page.isValid()) {
|
||||
if (page.isBogus()) {
|
||||
return showHomePage(vreq, page.getBogusMessage());
|
||||
} else if (page.isSubmit() && page.isValid()) {
|
||||
page.updateAccount();
|
||||
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
|
||||
return listPage.showPageWithUpdatedAccount(
|
||||
|
@ -87,4 +92,9 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
|||
return page.showPage();
|
||||
}
|
||||
|
||||
private ResponseValues showHomePage(VitroRequest vreq, String message) {
|
||||
DisplayMessage.setMessage(vreq, message);
|
||||
return new RedirectResponseValues("/");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,75 +2,217 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
|
||||
/**
|
||||
* TODO present the form. Get the submission.
|
||||
* TODO present the form. Get the submission.
|
||||
*
|
||||
* TODO If email is available, present the reset flag with message templage, and send email
|
||||
* TODO If email is available, present the reset flag with message templage, and
|
||||
* send email
|
||||
*
|
||||
* TODO if email is not available, allow password change with checks for validity
|
||||
* TODO if email is not available, allow password change with checks for
|
||||
* validity
|
||||
*
|
||||
* TODO If successful, go to AccountsList with message and optional password message.
|
||||
* TODO If successful, go to AccountsList with message and optional password
|
||||
* message.
|
||||
*
|
||||
* TODO if unsuccessful, go back to the page, with errors.
|
||||
*
|
||||
* TODO How much of this can be shared with AddPage? Email templates?
|
||||
*/
|
||||
public class UserAccountsEditPage extends UserAccountsPage {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(UserAccountsEditPage.class);
|
||||
|
||||
private static final String PARAMETER_SUBMIT = "submitEdit";
|
||||
private static final String PARAMETER_USER_URI = "editAccount";
|
||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||
private static final String PARAMETER_ROLE = "role";
|
||||
private static final String PARAMETER_ASSOCIATE_WITH_PROFILE = "associate";
|
||||
|
||||
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
|
||||
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
|
||||
private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty";
|
||||
private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty";
|
||||
private static final String ERROR_NO_ROLE = "errorNoRoleSelected";
|
||||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-edit.ftl";
|
||||
|
||||
private final UserAccountsEditPageStrategy strategy;
|
||||
|
||||
/* The request parameters */
|
||||
private boolean submit;
|
||||
private String userUri = "";
|
||||
private String emailAddress = "";
|
||||
private String firstName = "";
|
||||
private String lastName = "";
|
||||
private String selectedRoleUri = "";
|
||||
private boolean associateWithProfile;
|
||||
|
||||
private UserAccount userAccount;
|
||||
|
||||
/** The result of checking whether this request is even appropriate. */
|
||||
private String bogusMessage = "";
|
||||
|
||||
/** The result of validating a "submit" request. */
|
||||
private String errorCode = "";
|
||||
|
||||
public UserAccountsEditPage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
|
||||
this.strategy = UserAccountsEditPageStrategy.getInstance(vreq, this,
|
||||
isEmailEnabled(vreq));
|
||||
|
||||
parseRequestParameters();
|
||||
validateUserAccountInfo();
|
||||
|
||||
if (isSubmit() && !isBogus()) {
|
||||
validateParameters();
|
||||
}
|
||||
}
|
||||
|
||||
public ResponseValues showPage() {
|
||||
return new TemplateResponseValues(TEMPLATE_NAME);
|
||||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
userUri = getStringParameter(PARAMETER_USER_URI, "");
|
||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
||||
associateWithProfile = isParameterAsExpected(
|
||||
PARAMETER_ASSOCIATE_WITH_PROFILE, "yes");
|
||||
|
||||
strategy.parseAdditionalParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public UserAccount updateAccount() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("UserAccountsEditPage.updateAccount() not implemented.");
|
||||
private void validateUserAccountInfo() {
|
||||
userAccount = userAccountsDao.getUserAccountByUri(userUri);
|
||||
if (userAccount == null) {
|
||||
log.warn("Edit account for '" + userUri
|
||||
+ "' is bogus: no such user");
|
||||
bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean wasPasswordEmailSent() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("UserAccountsEditPage.wasPasswordEmailSent() not implemented.");
|
||||
public boolean isBogus() {
|
||||
return !bogusMessage.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public UserAccount getUpdatedAccount() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("UserAccountsEditPage.getUpdatedAccount() not implemented.");
|
||||
public String getBogusMessage() {
|
||||
return bogusMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean isValid() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("UserAccountsEditPage.isValid() not implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean isSubmit() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("UserAccountsEditPage.isSubmit() not implemented.");
|
||||
return submit;
|
||||
}
|
||||
|
||||
private void validateParameters() {
|
||||
if (emailAddress.isEmpty()) {
|
||||
errorCode = ERROR_NO_EMAIL;
|
||||
} else if (emailIsChanged() && isEmailInUse()) {
|
||||
errorCode = ERROR_EMAIL_IN_USE;
|
||||
} else if (firstName.isEmpty()) {
|
||||
errorCode = ERROR_NO_FIRST_NAME;
|
||||
} else if (lastName.isEmpty()) {
|
||||
errorCode = ERROR_NO_LAST_NAME;
|
||||
} else if (selectedRoleUri.isEmpty()) {
|
||||
errorCode = ERROR_NO_ROLE;
|
||||
} else {
|
||||
errorCode = strategy.additionalValidations();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean emailIsChanged() {
|
||||
return !emailAddress.equals(userAccount.getEmailAddress());
|
||||
}
|
||||
|
||||
private boolean isEmailInUse() {
|
||||
return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return errorCode.isEmpty();
|
||||
}
|
||||
|
||||
public final ResponseValues showPage() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
if (isSubmit()) {
|
||||
body.put("emailAddress", emailAddress);
|
||||
body.put("firstName", firstName);
|
||||
body.put("lastName", lastName);
|
||||
body.put("selectedRole", selectedRoleUri);
|
||||
} else {
|
||||
body.put("emailAddress", userAccount.getEmailAddress());
|
||||
body.put("firstName", userAccount.getFirstName());
|
||||
body.put("lastName", userAccount.getLastName());
|
||||
body.put("selectedRole", getExistingRoleUri());
|
||||
}
|
||||
body.put("roles", buildRolesList());
|
||||
if (associateWithProfile) {
|
||||
body.put("associate", Boolean.TRUE);
|
||||
}
|
||||
body.put("formUrls", buildUrlsMapWithEditUrl());
|
||||
|
||||
if (!errorCode.isEmpty()) {
|
||||
body.put(errorCode, Boolean.TRUE);
|
||||
}
|
||||
|
||||
strategy.addMoreBodyValues(body);
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
private String getExistingRoleUri() {
|
||||
Set<String> uris = userAccount.getPermissionSetUris();
|
||||
if (uris.isEmpty()) {
|
||||
return "";
|
||||
} else {
|
||||
return uris.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> buildUrlsMapWithEditUrl() {
|
||||
Map<String, String> map = buildUrlsMap();
|
||||
map.put("edit", editAccountUrl(userAccount.getUri()));
|
||||
return map;
|
||||
}
|
||||
|
||||
public void updateAccount() {
|
||||
userAccount.setEmailAddress(emailAddress);
|
||||
userAccount.setFirstName(firstName);
|
||||
userAccount.setLastName(lastName);
|
||||
|
||||
userAccount.setPermissionSetUris(Collections.singleton(selectedRoleUri));
|
||||
|
||||
strategy.setAdditionalProperties(userAccount);
|
||||
|
||||
userAccountsDao.updateUserAccount(userAccount);
|
||||
|
||||
strategy.notifyUser();
|
||||
}
|
||||
|
||||
public boolean wasPasswordEmailSent() {
|
||||
return strategy.wasPasswordEmailSent();
|
||||
}
|
||||
|
||||
public UserAccount getUpdatedAccount() {
|
||||
return userAccount;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
|
||||
|
||||
import static javax.mail.Message.RecipientType.TO;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
|
||||
/**
|
||||
* Handle the variant details of the UserAccountsAddPage.
|
||||
*/
|
||||
public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
||||
protected final UserAccountsEditPage page;
|
||||
|
||||
public static UserAccountsEditPageStrategy getInstance(VitroRequest vreq,
|
||||
UserAccountsEditPage page, boolean emailEnabled) {
|
||||
if (emailEnabled) {
|
||||
return new EmailStrategy(vreq, page);
|
||||
} else {
|
||||
return new NoEmailStrategy(vreq, page);
|
||||
}
|
||||
}
|
||||
|
||||
public UserAccountsEditPageStrategy(VitroRequest vreq,
|
||||
UserAccountsEditPage page) {
|
||||
super(vreq);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
protected abstract void parseAdditionalParameters();
|
||||
|
||||
protected abstract String additionalValidations();
|
||||
|
||||
protected abstract void addMoreBodyValues(Map<String, Object> body);
|
||||
|
||||
protected abstract void setAdditionalProperties(UserAccount u);
|
||||
|
||||
protected abstract void notifyUser();
|
||||
|
||||
protected abstract boolean wasPasswordEmailSent();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Strategy to use if email is enabled.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static class EmailStrategy extends UserAccountsEditPageStrategy {
|
||||
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
|
||||
|
||||
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
|
||||
|
||||
private boolean resetPassword;
|
||||
private boolean sentEmail;
|
||||
|
||||
public EmailStrategy(VitroRequest vreq, UserAccountsEditPage page) {
|
||||
super(vreq, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseAdditionalParameters() {
|
||||
resetPassword = isFlagOnRequest(PARAMETER_RESET_PASSWORD);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String additionalValidations() {
|
||||
// No additional validations
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAdditionalProperties(UserAccount u) {
|
||||
if (resetPassword) {
|
||||
u.setPasswordLinkExpires(figureExpirationDate().getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addMoreBodyValues(Map<String, Object> body) {
|
||||
body.put("emailIsEnabled", Boolean.TRUE);
|
||||
if (resetPassword) {
|
||||
body.put("resetPassword", Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyUser() {
|
||||
if (!resetPassword) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", page.getUpdatedAccount());
|
||||
body.put("passwordLink", buildResetPasswordLink());
|
||||
body.put("subjectLine", "Reset password request");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
|
||||
email.setSubject("Reset password request");
|
||||
email.setHtmlTemplate("userAccounts-resetPasswordEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-resetPasswordEmail-text.ftl");
|
||||
email.setBodyMap(body);
|
||||
email.send();
|
||||
|
||||
sentEmail = true;
|
||||
}
|
||||
|
||||
private String buildResetPasswordLink() {
|
||||
try {
|
||||
String email = page.getUpdatedAccount().getEmailAddress();
|
||||
String hash = page.getUpdatedAccount()
|
||||
.getPasswordLinkExpiresHash();
|
||||
String relativeUrl = UrlBuilder.getUrl(RESET_PASSWORD_URL,
|
||||
"user", email, "key", hash);
|
||||
|
||||
URL context = new URL(vreq.getRequestURL().toString());
|
||||
URL url = new URL(context, relativeUrl);
|
||||
return url.toExternalForm();
|
||||
} catch (MalformedURLException e) {
|
||||
return "error_creating_password_link";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean wasPasswordEmailSent() {
|
||||
return sentEmail;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Strategy to use if email is not enabled.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static class NoEmailStrategy extends UserAccountsEditPageStrategy {
|
||||
private static final String PARAMETER_NEW_PASSWORD = "newPassword";
|
||||
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
|
||||
|
||||
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
||||
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
||||
|
||||
private String newPassword;
|
||||
private String confirmPassword;
|
||||
|
||||
public NoEmailStrategy(VitroRequest vreq, UserAccountsEditPage page) {
|
||||
super(vreq, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseAdditionalParameters() {
|
||||
newPassword = getStringParameter(PARAMETER_NEW_PASSWORD, "");
|
||||
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String additionalValidations() {
|
||||
if (newPassword.isEmpty() && confirmPassword.isEmpty()) {
|
||||
return "";
|
||||
} else if (!checkPasswordLength()) {
|
||||
return ERROR_WRONG_PASSWORD_LENGTH;
|
||||
} else if (!newPassword.equals(confirmPassword)) {
|
||||
return ERROR_PASSWORDS_DONT_MATCH;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkPasswordLength() {
|
||||
return newPassword.length() >= UserAccount.MIN_PASSWORD_LENGTH
|
||||
&& newPassword.length() <= UserAccount.MAX_PASSWORD_LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addMoreBodyValues(Map<String, Object> body) {
|
||||
body.put("newPassword", newPassword);
|
||||
body.put("confirmPassword", confirmPassword);
|
||||
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
|
||||
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAdditionalProperties(UserAccount u) {
|
||||
u.setMd5Password(newPassword);
|
||||
u.setPasswordChangeRequired(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyUser() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean wasPasswordEmailSent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -105,6 +105,9 @@ public class UserAccountsListPage extends UserAccountsPage {
|
|||
|
||||
body.put("newUserAccount", new UserAccountWrapper(userAccount,
|
||||
Collections.<String> emptyList()));
|
||||
if (emailWasSent) {
|
||||
body.put("emailWasSent", Boolean.TRUE);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
@ -114,8 +117,17 @@ public class UserAccountsListPage extends UserAccountsPage {
|
|||
*/
|
||||
public ResponseValues showPageWithUpdatedAccount(UserAccount userAccount,
|
||||
boolean emailWasSent) {
|
||||
throw new RuntimeException(
|
||||
"UserAccountsListPage.showPageWithUpdatedAccount not implemented.");
|
||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
||||
userAccountsModel, criteria);
|
||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||
|
||||
body.put("updatedUserAccount", new UserAccountWrapper(userAccount,
|
||||
Collections.<String> emptyList()));
|
||||
if (emailWasSent) {
|
||||
body.put("emailWasSent", Boolean.TRUE);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,165 +2,68 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
||||
|
||||
import java.util.Date;
|
||||
import static javax.mail.Message.RecipientType.TO;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
|
||||
/**
|
||||
* When the user clicks on the link in their notification email, handle their
|
||||
* request to create a password.
|
||||
*/
|
||||
public class UserAccountsCreatePasswordPage extends UserAccountsPage {
|
||||
public class UserAccountsCreatePasswordPage extends
|
||||
UserAccountsPasswordBasePage {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(UserAccountsCreatePasswordPage.class);
|
||||
|
||||
private static final String PARAMETER_SUBMIT = "submitCreatePassword";
|
||||
private static final String PARAMETER_USER = "user";
|
||||
private static final String PARAMETER_KEY = "key";
|
||||
private static final String PARAMETER_PASSWORD = "password";
|
||||
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
|
||||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
|
||||
|
||||
private static final String ERROR_NO_PASSWORD = "errorPasswordIsEmpty";
|
||||
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
||||
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
||||
|
||||
private boolean submit;
|
||||
private String userEmail = "";
|
||||
private String key = "";
|
||||
private String password = "";
|
||||
private String confirmPassword = "";
|
||||
|
||||
private UserAccount userAccount;
|
||||
|
||||
/** The result of checking whether this request is even appropriate. */
|
||||
private String bogusMessage = "";
|
||||
|
||||
/** The result of validating a "submit" request. */
|
||||
private String errorCode = "";
|
||||
|
||||
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
|
||||
parseRequestParameters();
|
||||
validateUserAccountInfo();
|
||||
|
||||
if (isSubmit() && !isBogus()) {
|
||||
validateParameters();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
userEmail = getStringParameter(PARAMETER_USER, "");
|
||||
key = getStringParameter(PARAMETER_KEY, "");
|
||||
password = getStringParameter(PARAMETER_PASSWORD, "");
|
||||
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
|
||||
}
|
||||
|
||||
private void validateUserAccountInfo() {
|
||||
userAccount = userAccountsDao.getUserAccountByEmail(userEmail);
|
||||
if (userAccount == null) {
|
||||
log.warn("Create password for '" + userEmail
|
||||
+ "' is bogus: no such user");
|
||||
bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (userAccount.getPasswordLinkExpires() == 0L) {
|
||||
log.warn("Create password for '" + userEmail
|
||||
+ "' is bogus: password change is not pending.");
|
||||
bogusMessage = "The account for " + userEmail
|
||||
+ " has already been activated.";
|
||||
return;
|
||||
}
|
||||
|
||||
Date expirationDate = new Date(userAccount.getPasswordLinkExpires());
|
||||
if (expirationDate.before(new Date())) {
|
||||
log.warn("Create password for '" + userEmail
|
||||
+ "' is bogus: expiration date has passed.");
|
||||
bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
|
||||
String expectedKey = userAccount.getPasswordLinkExpiresHash();
|
||||
if (!key.equals(expectedKey)) {
|
||||
log.warn("Create password for '" + userEmail + "' is bogus: key ("
|
||||
+ key + ") doesn't match expected key (" + expectedKey
|
||||
+ ")");
|
||||
bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void validateParameters() {
|
||||
if (password.isEmpty()) {
|
||||
errorCode = ERROR_NO_PASSWORD;
|
||||
} else if (!checkPasswordLength(password)) {
|
||||
errorCode = ERROR_WRONG_PASSWORD_LENGTH;
|
||||
} else if (!password.equals(confirmPassword)) {
|
||||
errorCode = ERROR_PASSWORDS_DONT_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkPasswordLength(String pw) {
|
||||
return pw.length() >= UserAccount.MIN_PASSWORD_LENGTH
|
||||
&& pw.length() <= UserAccount.MAX_PASSWORD_LENGTH;
|
||||
}
|
||||
|
||||
public boolean isBogus() {
|
||||
return bogusMessage.isEmpty();
|
||||
}
|
||||
|
||||
public String getBogusMessage() {
|
||||
return bogusMessage;
|
||||
}
|
||||
|
||||
public boolean isSubmit() {
|
||||
return submit;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return errorCode.isEmpty();
|
||||
}
|
||||
|
||||
public void createPassword() {
|
||||
userAccount.setMd5Password(Authenticator.applyMd5Encoding(password));
|
||||
userAccount.setMd5Password(Authenticator.applyMd5Encoding(newPassword));
|
||||
userAccount.setPasswordLinkExpires(0L);
|
||||
userAccount.setStatus(Status.ACTIVE);
|
||||
userAccountsDao.updateUserAccount(userAccount);
|
||||
log.debug("Set password on '" + userAccount.getEmailAddress()
|
||||
+ "' to '" + password + "'");
|
||||
+ "' to '" + newPassword + "'");
|
||||
|
||||
notifyUser();
|
||||
}
|
||||
|
||||
public final ResponseValues showPage() {
|
||||
@Override
|
||||
protected String passwordChangeNotPendingMessage() {
|
||||
return "The account for " + userEmail + " has already been activated.";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String templateName() {
|
||||
return TEMPLATE_NAME;
|
||||
}
|
||||
|
||||
private void notifyUser() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
|
||||
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
|
||||
body.put("userAccount", userAccount);
|
||||
body.put("key", userAccount.getPasswordLinkExpiresHash());
|
||||
body.put("password", password);
|
||||
body.put("confirmPassword", confirmPassword);
|
||||
body.put("formUrls", buildUrlsMap());
|
||||
body.put("subjectLine", "Password successfully created.");
|
||||
|
||||
if (!errorCode.isEmpty()) {
|
||||
body.put(errorCode, Boolean.TRUE);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||
email.setSubject("Password successfully created.");
|
||||
email.setHtmlTemplate("userAccounts-passwordCreatedEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-passwordCreatedEmail-text.ftl");
|
||||
email.setBodyMap(body);
|
||||
email.send();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
|
||||
/**
|
||||
* Routines in common to the "Create Password" and "Reset Password" pages.
|
||||
*/
|
||||
public abstract class UserAccountsPasswordBasePage extends UserAccountsPage {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(UserAccountsPasswordBasePage.class);
|
||||
|
||||
private static final String PARAMETER_SUBMIT = "submit";
|
||||
private static final String PARAMETER_USER = "user";
|
||||
private static final String PARAMETER_KEY = "key";
|
||||
private static final String PARAMETER_NEW_PASSWORD = "newPassword";
|
||||
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
|
||||
|
||||
private static final String ERROR_NO_PASSWORD = "errorPasswordIsEmpty";
|
||||
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
||||
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
||||
|
||||
protected boolean submit;
|
||||
protected String userEmail = "";
|
||||
protected String key = "";
|
||||
protected String newPassword = "";
|
||||
protected String confirmPassword = "";
|
||||
|
||||
protected UserAccount userAccount;
|
||||
|
||||
/** The result of checking whether this request is even appropriate. */
|
||||
private String bogusMessage = "";
|
||||
|
||||
/** The result of validating a "submit" request. */
|
||||
private String errorCode = "";
|
||||
|
||||
protected UserAccountsPasswordBasePage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
|
||||
parseRequestParameters();
|
||||
validateUserAccountInfo();
|
||||
|
||||
if (isSubmit() && !isBogus()) {
|
||||
validateParameters();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
userEmail = getStringParameter(PARAMETER_USER, "");
|
||||
key = getStringParameter(PARAMETER_KEY, "");
|
||||
newPassword = getStringParameter(PARAMETER_NEW_PASSWORD, "");
|
||||
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
|
||||
}
|
||||
|
||||
public boolean isSubmit() {
|
||||
return submit;
|
||||
}
|
||||
|
||||
private void validateUserAccountInfo() {
|
||||
userAccount = userAccountsDao.getUserAccountByEmail(userEmail);
|
||||
if (userAccount == null) {
|
||||
log.warn("Password request for '" + userEmail
|
||||
+ "' is bogus: no such user");
|
||||
bogusMessage = BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (userAccount.getPasswordLinkExpires() == 0L) {
|
||||
log.warn("Password request for '" + userEmail
|
||||
+ "' is bogus: password change is not pending.");
|
||||
bogusMessage = passwordChangeNotPendingMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
Date expirationDate = new Date(userAccount.getPasswordLinkExpires());
|
||||
if (expirationDate.before(new Date())) {
|
||||
log.warn("Password request for '" + userEmail
|
||||
+ "' is bogus: expiration date has passed.");
|
||||
bogusMessage = BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
|
||||
String expectedKey = userAccount.getPasswordLinkExpiresHash();
|
||||
if (!key.equals(expectedKey)) {
|
||||
log.warn("Password request for '" + userEmail + "' is bogus: key ("
|
||||
+ key + ") doesn't match expected key (" + expectedKey
|
||||
+ ")");
|
||||
bogusMessage = BOGUS_STANDARD_MESSAGE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBogus() {
|
||||
return !bogusMessage.isEmpty();
|
||||
}
|
||||
|
||||
public String getBogusMessage() {
|
||||
return bogusMessage;
|
||||
}
|
||||
|
||||
private void validateParameters() {
|
||||
if (newPassword.isEmpty()) {
|
||||
errorCode = ERROR_NO_PASSWORD;
|
||||
} else if (!checkPasswordLength(newPassword)) {
|
||||
errorCode = ERROR_WRONG_PASSWORD_LENGTH;
|
||||
} else if (!newPassword.equals(confirmPassword)) {
|
||||
errorCode = ERROR_PASSWORDS_DONT_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return errorCode.isEmpty();
|
||||
}
|
||||
|
||||
public final ResponseValues showPage() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
|
||||
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
|
||||
body.put("userAccount", userAccount);
|
||||
body.put("key", userAccount.getPasswordLinkExpiresHash());
|
||||
body.put("newPassword", newPassword);
|
||||
body.put("confirmPassword", confirmPassword);
|
||||
body.put("formUrls", buildUrlsMap());
|
||||
|
||||
if (!errorCode.isEmpty()) {
|
||||
body.put(errorCode, Boolean.TRUE);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(templateName(), body);
|
||||
}
|
||||
|
||||
protected abstract String passwordChangeNotPendingMessage();
|
||||
protected abstract String templateName();
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
||||
|
||||
import static javax.mail.Message.RecipientType.TO;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
|
||||
/**
|
||||
* When the user clicks on the link in their notification email, handle their
|
||||
* request to reset their password.
|
||||
*/
|
||||
public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(UserAccountsResetPasswordPage.class);
|
||||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
|
||||
|
||||
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
}
|
||||
|
||||
public void resetPassword() {
|
||||
userAccount.setMd5Password(Authenticator.applyMd5Encoding(newPassword));
|
||||
userAccount.setPasswordLinkExpires(0L);
|
||||
userAccount.setStatus(Status.ACTIVE);
|
||||
userAccountsDao.updateUserAccount(userAccount);
|
||||
log.debug("Set password on '" + userAccount.getEmailAddress()
|
||||
+ "' to '" + newPassword + "'");
|
||||
|
||||
notifyUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String passwordChangeNotPendingMessage() {
|
||||
return "The password for " + userEmail + " has already been reset.";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String templateName() {
|
||||
return TEMPLATE_NAME;
|
||||
}
|
||||
|
||||
private void notifyUser() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", userAccount);
|
||||
body.put("subjectLine", "Password changed.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||
email.setSubject("Password changed.");
|
||||
email.setHtmlTemplate("userAccounts-passwordResetEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-passwordResetEmail-text.ftl");
|
||||
email.setBodyMap(body);
|
||||
email.send();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
public static final String BOGUS_STANDARD_MESSAGE = "Request failed. Please contact your system administrator.";
|
||||
|
||||
private static final String ACTION_CREATE_PASSWORD = "/createPassword";
|
||||
private static final String ACTION_RESET_PASSWORD = "/resetPassword";
|
||||
|
||||
@Override
|
||||
protected Actions requiredActions(VitroRequest vreq) {
|
||||
|
@ -39,6 +40,8 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
|
||||
if (ACTION_CREATE_PASSWORD.equals(action)) {
|
||||
return handleCreatePasswordRequest(vreq);
|
||||
} else if (ACTION_RESET_PASSWORD.equals(action)) {
|
||||
return handleResetPasswordRequest(vreq);
|
||||
} else {
|
||||
return handleInvalidRequest(vreq);
|
||||
}
|
||||
|
@ -59,6 +62,21 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
|
||||
}
|
||||
|
||||
private ResponseValues handleResetPasswordRequest(VitroRequest vreq) {
|
||||
UserAccountsResetPasswordPage page = new UserAccountsResetPasswordPage(
|
||||
vreq);
|
||||
if (page.isBogus()) {
|
||||
return showHomePage(vreq, page.getBogusMessage());
|
||||
} else if (page.isSubmit() && page.isValid()) {
|
||||
page.resetPassword();
|
||||
return showHomePage(vreq,
|
||||
"Your password has been saved. Please log in.");
|
||||
} else {
|
||||
return page.showPage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ResponseValues handleInvalidRequest(VitroRequest vreq) {
|
||||
return showHomePage(vreq, BOGUS_STANDARD_MESSAGE);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue