NIHVIVO-2279 Implement the MyAccount page.
This commit is contained in:
parent
64fa779638
commit
3b5eb3a846
10 changed files with 528 additions and 14 deletions
|
@ -59,8 +59,8 @@ public abstract class UserAccountsPage {
|
|||
userAccountsDao = wdf.getUserAccountsDao();
|
||||
}
|
||||
|
||||
protected static boolean isEmailEnabled(HttpServletRequest req) {
|
||||
return FreemarkerEmailFactory.isConfigured(req);
|
||||
protected boolean isEmailEnabled() {
|
||||
return FreemarkerEmailFactory.isConfigured(vreq);
|
||||
}
|
||||
|
||||
protected String getStringParameter(String key, String defaultValue) {
|
||||
|
@ -126,6 +126,7 @@ public abstract class UserAccountsPage {
|
|||
map.put("list", UrlBuilder.getUrl("/accountsAdmin/list"));
|
||||
map.put("add", UrlBuilder.getUrl("/accountsAdmin/add"));
|
||||
map.put("delete", UrlBuilder.getUrl("/accountsAdmin/delete"));
|
||||
map.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
|
||||
map.put("createPassword", UrlBuilder.getUrl("/accounts/createPassword"));
|
||||
map.put("resetPassword", UrlBuilder.getUrl("/accounts/resetPassword"));
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
|||
super(vreq);
|
||||
|
||||
this.strategy = UserAccountsAddPageStrategy.getInstance(vreq, this,
|
||||
isEmailEnabled(vreq));
|
||||
isEmailEnabled());
|
||||
|
||||
parseRequestParameters();
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
|||
super(vreq);
|
||||
|
||||
this.strategy = UserAccountsEditPageStrategy.getInstance(vreq, this,
|
||||
isEmailEnabled(vreq));
|
||||
isEmailEnabled());
|
||||
|
||||
parseRequestParameters();
|
||||
validateUserAccountInfo();
|
||||
|
|
|
@ -13,6 +13,7 @@ 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.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
|
@ -166,7 +167,7 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
|||
protected String additionalValidations() {
|
||||
if (newPassword.isEmpty() && confirmPassword.isEmpty()) {
|
||||
return "";
|
||||
} else if (!checkPasswordLength()) {
|
||||
} else if (!checkPasswordLength(newPassword)) {
|
||||
return ERROR_WRONG_PASSWORD_LENGTH;
|
||||
} else if (!newPassword.equals(confirmPassword)) {
|
||||
return ERROR_PASSWORDS_DONT_MATCH;
|
||||
|
@ -175,11 +176,6 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -190,8 +186,10 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
|||
|
||||
@Override
|
||||
protected void setAdditionalProperties(UserAccount u) {
|
||||
u.setMd5Password(newPassword);
|
||||
u.setPasswordChangeRequired(true);
|
||||
if (!newPassword.isEmpty()) {
|
||||
u.setMd5Password(Authenticator.applyMd5Encoding(newPassword));
|
||||
u.setPasswordChangeRequired(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.User;
|
||||
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.admin.UserAccountsEditPage;
|
||||
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.dao.UserDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
|
||||
/**
|
||||
* Handle the "My Account" form display and submission.
|
||||
*/
|
||||
public class UserAccountsMyAccountPage extends UserAccountsPage {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(UserAccountsEditPage.class);
|
||||
|
||||
private static final String PARAMETER_SUBMIT = "submitMyAccount";
|
||||
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 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 TEMPLATE_NAME = "userAccounts-myAccount.ftl";
|
||||
|
||||
private final UserAccountsMyAccountPageStrategy strategy;
|
||||
|
||||
private final UserAccount userAccount;
|
||||
|
||||
/* The request parameters */
|
||||
private boolean submit;
|
||||
private String emailAddress = "";
|
||||
private String firstName = "";
|
||||
private String lastName = "";
|
||||
|
||||
/** The result of validating a "submit" request. */
|
||||
private String errorCode = "";
|
||||
|
||||
/** The result of updating the account. */
|
||||
private String confirmationCode = "";
|
||||
|
||||
public UserAccountsMyAccountPage(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
|
||||
this.userAccount = getLoggedInUser();
|
||||
this.strategy = UserAccountsMyAccountPageStrategy.getInstance(vreq,
|
||||
this, isExternalAccount());
|
||||
|
||||
parseRequestParameters();
|
||||
|
||||
if (isSubmit()) {
|
||||
validateParameters();
|
||||
}
|
||||
}
|
||||
|
||||
public UserAccount getUserAccount() {
|
||||
return userAccount;
|
||||
}
|
||||
|
||||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
|
||||
strategy.parseAdditionalParameters();
|
||||
}
|
||||
|
||||
public boolean isSubmit() {
|
||||
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 {
|
||||
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();
|
||||
}
|
||||
|
||||
private UserAccount getLoggedInUser() {
|
||||
// TODO This is a bogus measure.
|
||||
// TODO It only works because for now we are not deleting old User
|
||||
// structures, and there is a new UserAccount with email set to the old
|
||||
// User username.
|
||||
String uri = LoginStatusBean.getBean(vreq).getUserURI();
|
||||
WebappDaoFactory wdf = (WebappDaoFactory) this.ctx
|
||||
.getAttribute("webappDaoFactory");
|
||||
User u = wdf.getUserDao().getUserByURI(uri);
|
||||
|
||||
UserAccount ua = userAccountsDao.getUserAccountByEmail(u.getUsername());
|
||||
if (ua == null) {
|
||||
throw new IllegalStateException("Couldn't find a UserAccount "
|
||||
+ "for uri: '" + uri + "'");
|
||||
}
|
||||
log.debug("Logged-in user is " + ua);
|
||||
return ua;
|
||||
}
|
||||
|
||||
private boolean isExternalAccount() {
|
||||
return LoginStatusBean.getBean(vreq).hasExternalAuthentication();
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
body.put("emailAddress", userAccount.getEmailAddress());
|
||||
body.put("firstName", userAccount.getFirstName());
|
||||
body.put("lastName", userAccount.getLastName());
|
||||
}
|
||||
body.put("formUrls", buildUrlsMap());
|
||||
|
||||
if (!errorCode.isEmpty()) {
|
||||
body.put(errorCode, Boolean.TRUE);
|
||||
}
|
||||
if (!confirmationCode.isEmpty()) {
|
||||
body.put(confirmationCode, Boolean.TRUE);
|
||||
}
|
||||
|
||||
strategy.addMoreBodyValues(body);
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
}
|
||||
|
||||
public void updateAccount() {
|
||||
userAccount.setEmailAddress(emailAddress);
|
||||
userAccount.setFirstName(firstName);
|
||||
userAccount.setLastName(lastName);
|
||||
|
||||
strategy.setAdditionalProperties(userAccount);
|
||||
|
||||
userAccountsDao.updateUserAccount(userAccount);
|
||||
|
||||
strategy.notifyUser();
|
||||
confirmationCode = strategy.getConfirmationCode();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
/* $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 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.authenticate.Authenticator;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
|
||||
/**
|
||||
* Handle the variant details of the MyAccounts page
|
||||
*/
|
||||
public abstract class UserAccountsMyAccountPageStrategy extends
|
||||
UserAccountsPage {
|
||||
|
||||
private static final String CONFIRM_CHANGE = "confirmChange";
|
||||
private static final String CONFIRM_EMAIL_SENT = "confirmEmailSent";
|
||||
|
||||
protected final UserAccountsMyAccountPage page;
|
||||
|
||||
public static UserAccountsMyAccountPageStrategy getInstance(
|
||||
VitroRequest vreq, UserAccountsMyAccountPage page,
|
||||
boolean externalAuth) {
|
||||
if (externalAuth) {
|
||||
return new ExternalAuthStrategy(vreq, page);
|
||||
} else {
|
||||
return new InternalAuthStrategy(vreq, page);
|
||||
}
|
||||
}
|
||||
|
||||
protected UserAccountsMyAccountPageStrategy(VitroRequest vreq,
|
||||
UserAccountsMyAccountPage page) {
|
||||
super(vreq);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public abstract void parseAdditionalParameters();
|
||||
|
||||
public abstract String additionalValidations();
|
||||
|
||||
public abstract void addMoreBodyValues(Map<String, Object> body);
|
||||
|
||||
public abstract void setAdditionalProperties(UserAccount userAccount);
|
||||
|
||||
public abstract void notifyUser();
|
||||
|
||||
public abstract String getConfirmationCode();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Strategy to use if the account used External Authentication
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static class ExternalAuthStrategy extends
|
||||
UserAccountsMyAccountPageStrategy {
|
||||
|
||||
ExternalAuthStrategy(VitroRequest vreq, UserAccountsMyAccountPage page) {
|
||||
super(vreq, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseAdditionalParameters() {
|
||||
// No additional parameters
|
||||
}
|
||||
|
||||
@Override
|
||||
public String additionalValidations() {
|
||||
// No additional validations
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMoreBodyValues(Map<String, Object> body) {
|
||||
body.put("externalAuth", Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdditionalProperties(UserAccount userAccount) {
|
||||
// No additional properties.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUser() {
|
||||
// No notification beyond the screen message.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfirmationCode() {
|
||||
return CONFIRM_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Strategy to use if the account used Internal Authentication
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static class InternalAuthStrategy extends
|
||||
UserAccountsMyAccountPageStrategy {
|
||||
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 final String originalEmail;
|
||||
|
||||
private String newPassword;
|
||||
private String confirmPassword;
|
||||
private boolean emailSent;
|
||||
|
||||
InternalAuthStrategy(VitroRequest vreq, UserAccountsMyAccountPage page) {
|
||||
super(vreq, page);
|
||||
originalEmail = page.getUserAccount().getEmailAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseAdditionalParameters() {
|
||||
newPassword = getStringParameter(PARAMETER_NEW_PASSWORD, "");
|
||||
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String additionalValidations() {
|
||||
if (newPassword.isEmpty() && confirmPassword.isEmpty()) {
|
||||
return "";
|
||||
} else if (!newPassword.equals(confirmPassword)) {
|
||||
return ERROR_PASSWORDS_DONT_MATCH;
|
||||
} else if (!checkPasswordLength(newPassword)) {
|
||||
return ERROR_WRONG_PASSWORD_LENGTH;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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
|
||||
public void setAdditionalProperties(UserAccount userAccount) {
|
||||
if (!newPassword.isEmpty()) {
|
||||
userAccount.setMd5Password(Authenticator
|
||||
.applyMd5Encoding(newPassword));
|
||||
userAccount.setPasswordChangeRequired(false);
|
||||
userAccount.setPasswordLinkExpires(0L);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUser() {
|
||||
if (!isEmailEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (!emailHasChanged()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("userAccount", page.getUserAccount());
|
||||
body.put("subjectLine", "Your VIVO email account has been changed.");
|
||||
|
||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||
.createNewMessage(vreq);
|
||||
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
|
||||
email.setSubject("Your VIVO email account has been changed.");
|
||||
email.setHtmlTemplate("userAccounts-confirmEmailChangedEmail-html.ftl");
|
||||
email.setTextTemplate("userAccounts-confirmEmailChangedEmail-text.ftl");
|
||||
email.setBodyMap(body);
|
||||
email.send();
|
||||
|
||||
emailSent = true;
|
||||
}
|
||||
|
||||
private boolean emailHasChanged() {
|
||||
return !page.getUserAccount().getEmailAddress()
|
||||
.equals(originalEmail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfirmationCode() {
|
||||
return emailSent ? CONFIRM_EMAIL_SENT : CONFIRM_CHANGE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount;
|
||||
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;
|
||||
|
@ -23,10 +24,17 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
|
||||
private static final String ACTION_CREATE_PASSWORD = "/createPassword";
|
||||
private static final String ACTION_RESET_PASSWORD = "/resetPassword";
|
||||
private static final String ACTION_MY_ACCOUNT = "/myAccount";
|
||||
|
||||
@Override
|
||||
protected Actions requiredActions(VitroRequest vreq) {
|
||||
return Actions.AUTHORIZED;
|
||||
String action = vreq.getPathInfo();
|
||||
|
||||
if (ACTION_MY_ACCOUNT.equals(action)) {
|
||||
return new Actions(new EditOwnAccount());
|
||||
} else {
|
||||
return Actions.AUTHORIZED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +46,9 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
String action = vreq.getPathInfo();
|
||||
log.debug("action = '" + action + "'");
|
||||
|
||||
if (ACTION_CREATE_PASSWORD.equals(action)) {
|
||||
if (ACTION_MY_ACCOUNT.equals(action)) {
|
||||
return handleMyAccountRequest(vreq);
|
||||
} else if (ACTION_CREATE_PASSWORD.equals(action)) {
|
||||
return handleCreatePasswordRequest(vreq);
|
||||
} else if (ACTION_RESET_PASSWORD.equals(action)) {
|
||||
return handleResetPasswordRequest(vreq);
|
||||
|
@ -47,6 +57,14 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
private ResponseValues handleMyAccountRequest(VitroRequest vreq) {
|
||||
UserAccountsMyAccountPage page = new UserAccountsMyAccountPage(vreq);
|
||||
if (page.isSubmit() && page.isValid()) {
|
||||
page.updateAccount();
|
||||
}
|
||||
return page.showPage();
|
||||
}
|
||||
|
||||
private ResponseValues handleCreatePasswordRequest(VitroRequest vreq) {
|
||||
UserAccountsCreatePasswordPage page = new UserAccountsCreatePasswordPage(
|
||||
vreq);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue