diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java
index 62254d186..e619b68ec 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java
@@ -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;
+ }
+
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java
index b99e4c85b..556326c77 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java
@@ -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 body = new HashMap();
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java
index 9c9380e50..9de5f2c07 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java
@@ -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 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 body) {
body.put("initialPassword", initialPassword);
body.put("confirmPassword", confirmPassword);
+ body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
+ body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
}
@Override
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAdminController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAdminController.java
index b98974bb8..b17a01c32 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAdminController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAdminController.java
@@ -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("/");
+ }
+
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java
index 039a63300..fe186286d 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java
@@ -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 body = new HashMap();
+
+ 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 uris = userAccount.getPermissionSetUris();
+ if (uris.isEmpty()) {
+ return "";
+ } else {
+ return uris.iterator().next();
+ }
+ }
+
+ private Map buildUrlsMapWithEditUrl() {
+ Map 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;
+ }
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java
new file mode 100644
index 000000000..6de05de00
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java
@@ -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 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 body) {
+ body.put("emailIsEnabled", Boolean.TRUE);
+ if (resetPassword) {
+ body.put("resetPassword", Boolean.TRUE);
+ }
+ }
+
+ @Override
+ protected void notifyUser() {
+ if (!resetPassword) {
+ return;
+ }
+
+ Map body = new HashMap();
+ 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 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;
+ }
+
+ }
+
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java
index c263c0419..08476691d 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java
@@ -105,6 +105,9 @@ public class UserAccountsListPage extends UserAccountsPage {
body.put("newUserAccount", new UserAccountWrapper(userAccount,
Collections. 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 body = buildTemplateBodyMap(selection);
+
+ body.put("updatedUserAccount", new UserAccountWrapper(userAccount,
+ Collections. emptyList()));
+ if (emailWasSent) {
+ body.put("emailWasSent", Boolean.TRUE);
+ }
+
+ return new TemplateResponseValues(TEMPLATE_NAME, body);
}
/**
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java
index e524180a4..07264f328 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java
@@ -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 body = new HashMap();
-
- 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();
}
-
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java
new file mode 100644
index 000000000..2cf64c585
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java
@@ -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 body = new HashMap();
+
+ 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();
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java
new file mode 100644
index 000000000..98bd350f0
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java
@@ -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 body = new HashMap();
+ 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();
+ }
+
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java
index 6f4ea9e11..8b17be386 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java
@@ -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);
}
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl
index 4cbce0936..0b3131991 100644
--- a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl
@@ -68,6 +68,8 @@
Initial password *
+ Minimum of ${minimumLength} characters in length.
+
Confirm initial password *
#if>
@@ -79,10 +81,6 @@
checked#if> id="no-associate" />
No
-
-
- Reset password
-
<#if emailIsEnabled??>
Note: An email will be sent to the address entered above
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-createPassword.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-createPassword.ftl
index 6bd7b6a99..2b75cff0c 100644
--- a/webapp/web/templates/freemarker/body/accounts/userAccounts-createPassword.ftl
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-createPassword.ftl
@@ -2,7 +2,7 @@
<#-- Template for adding a user account -->
-
Add new account
+Create your Password
<#if errorPasswordIsEmpty??>
<#assign errorMessage = "No password supplied." />
@@ -23,23 +23,23 @@
#if>
-
+
- Add new account
+ Please enter your new password for ${userAccount.emailAddress}
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl
index 9df6b9905..9060a37ea 100644
--- a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl
@@ -2,5 +2,103 @@
<#-- Template for editing a user account -->
-Edit user account
+Edit account
+ <#if errorEmailIsEmpty??>
+ <#assign errorMessage = "You must supply an email address." />
+ #if>
+
+ <#if errorEmailInUse??>
+ <#assign errorMessage = "An account with that email address already exists." />
+ #if>
+
+ <#if errorFirstNameIsEmpty??>
+ <#assign errorMessage = "You must supply a first name." />
+ #if>
+
+ <#if errorLastNameIsEmpty??>
+ <#assign errorMessage = "You must supply a last name." />
+ #if>
+
+ <#if errorNoRoleSelected??>
+ <#assign errorMessage = "You must select a role." />
+ #if>
+
+ <#if errorPasswordIsEmpty??>
+ <#assign errorMessage = "No password supplied." />
+ #if>
+
+ <#if errorPasswordIsWrongLength??>
+ <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." />
+ #if>
+
+ <#if errorPasswordsDontMatch??>
+ <#assign errorMessage = "Passwords do not match." />
+ #if>
+
+ <#if errorMessage?has_content>
+
+
+ ${errorMessage}
+
+ #if>
+
+
+
+ Edit new account
+
+
+
+
+
+${stylesheets.add(' ')}
\ No newline at end of file
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl
index d59d8d20b..a0d476e8a 100644
--- a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl
@@ -47,8 +47,26 @@
A new account for
${newUserAccount.firstName} ${newUserAccount.lastName}
- was successfully created. A notification email has been sent to ${newUserAccount.emailAddress}
- with instructions for activating the account and creating a password.
+ was successfully created.
+ <#if emailWasSent?? >
+ A notification email has been sent to ${newUserAccount.emailAddress}
+ with instructions for activating the account and creating a password.
+ #if>
+
+
+#if>
+
+<#if updatedUserAccount?? >
+
+
+ The account for
+ ${updatedUserAccount.firstName} ${updatedUserAccount.lastName}
+ has been updated.
+ <#if emailWasSent?? >
+ A confirmation email has been sent to ${updatedUserAccount.emailAddress}
+ with instructions for resetting a password.
+ The password will not be reset until the user follows the link provided in this email.
+ #if>
#if>
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-html.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-html.ftl
index c6733d9d7..1773766e9 100644
--- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-html.ftl
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-html.ftl
@@ -1,6 +1,6 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
-<#-- Confirmation that an account has been created. -->
+<#-- Confirmation that an password has been created. -->
@@ -16,7 +16,7 @@
- Yout new password associated with ${userAccount.emailAddress} has been created.
+ Your new password associated with ${userAccount.emailAddress} has been created.
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-text.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-text.ftl
index c44afae0d..2a339d4a9 100644
--- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-text.ftl
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail-text.ftl
@@ -1,6 +1,6 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
-<#-- Confirmation that an account has been created. -->
+<#-- Confirmation that a password has been created. -->
${userAccount.firstName} ${userAccount.lastName}
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail-html.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail-html.ftl
new file mode 100644
index 000000000..5212fbebb
--- /dev/null
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail-html.ftl
@@ -0,0 +1,26 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#-- Confirmation that an password has been reset. -->
+
+
+
+ ${subjectLine}
+
+
+
+ ${userAccount.firstName} ${userAccount.lastName}
+
+
+
+ Password successfully changed.
+
+
+
+ Your new password associated with ${userAccount.emailAddress} has been changed.
+
+
+
+ Thank you.
+
+
+
\ No newline at end of file
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail-text.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail-text.ftl
new file mode 100644
index 000000000..cfe0cd00f
--- /dev/null
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetEmail-text.ftl
@@ -0,0 +1,12 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#-- Confirmation that a password has been reset. -->
+
+${userAccount.firstName} ${userAccount.lastName}
+
+Password successfully changed.
+
+Your new password associated with ${userAccount.emailAddress}
+has been changed.
+
+Thank you.
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl
new file mode 100644
index 000000000..d0f8e75a5
--- /dev/null
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl
@@ -0,0 +1,49 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#-- Template for adding a user account -->
+
+Reset your Password
+
+ <#if errorPasswordIsEmpty??>
+ <#assign errorMessage = "No password supplied." />
+ #if>
+
+ <#if errorPasswordIsWrongLength??>
+ <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." />
+ #if>
+
+ <#if errorPasswordsDontMatch??>
+ <#assign errorMessage = "Passwords do not match." />
+ #if>
+
+ <#if errorMessage?has_content>
+
+
+ ${errorMessage}
+
+ #if>
+
+
+
+ Please enter your new password for ${userAccount.emailAddress}
+
+
+
+
+
+${stylesheets.add(' ')}
\ No newline at end of file
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail-html.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail-html.ftl
new file mode 100644
index 000000000..0fa37fba3
--- /dev/null
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail-html.ftl
@@ -0,0 +1,40 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#-- Notification that your password has been reset. -->
+
+
+
+ ${subjectLine}
+
+
+
+ ${userAccount.firstName} ${userAccount.lastName}
+
+
+
+ We received a request to reset the password for your account (${userAccount.emailAddress}).
+ Please follow the instructions below to proceed with your password reset.
+
+
+
+ If you did not request this new account you can safely ignore this email.
+ This request will expire if not acted upon for 30 days.
+
+
+
+ Click the link below to reset your password using our secure server.
+
+
+
+ ${passwordLink}
+
+
+
+ If the link above doesn't work, you can copy and paste the link directly into your browser's address bar.
+
+
+
+ Thank you!
+
+
+
\ No newline at end of file
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail-text.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail-text.ftl
new file mode 100644
index 000000000..82624c327
--- /dev/null
+++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPasswordEmail-text.ftl
@@ -0,0 +1,19 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#-- Notification that your password has been reset. -->
+
+${userAccount.firstName} ${userAccount.lastName}
+
+We received a request to reset the password for your account
+(${userAccount.emailAddress}).
+Please follow the instructions below to proceed with your password reset.
+
+If you did not request this new account you can safely ignore this email.
+This request will expire if not acted upon for 30 days.
+
+Paste the link below into your browser's address bar to reset your password
+using our secure server.
+
+${passwordLink}
+
+Thank you!