VIVO-139 Use the I18n framework wherever DisplayMessage is loaded.

This commit is contained in:
j2blake 2013-06-14 12:47:37 -04:00
parent aa7c8024d0
commit 5de5a322a2
19 changed files with 151 additions and 128 deletions

View file

@ -30,6 +30,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
public class VitroHttpServlet extends HttpServlet { public class VitroHttpServlet extends HttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -63,15 +64,6 @@ public class VitroHttpServlet extends HttpServlet {
super.service(req, resp); super.service(req, resp);
} }
/**
* Show this to the user if they are logged in, but still not authorized to
* view the page.
*/
private static final String INSUFFICIENT_AUTHORIZATION_MESSAGE = "We're sorry, "
+ "but you are not authorized to view the page you requested. "
+ "If you think this is an error, "
+ "please contact us and we'll be happy to help.";
/** /**
* doGet does nothing. * doGet does nothing.
*/ */
@ -148,7 +140,7 @@ public class VitroHttpServlet extends HttpServlet {
HttpServletRequest request, HttpServletResponse response) { HttpServletRequest request, HttpServletResponse response) {
try { try {
DisplayMessage.setMessage(request, DisplayMessage.setMessage(request,
INSUFFICIENT_AUTHORIZATION_MESSAGE); I18n.bundle(request).text("insufficient_authorization"));
response.sendRedirect(request.getContextPath()); response.sendRedirect(request.getContextPath());
} catch (IOException e) { } catch (IOException e) {
log.error("Could not redirect to show insufficient authorization."); log.error("Could not redirect to show insufficient authorization.");

View file

@ -172,6 +172,9 @@ public class AdminLoginController extends FreemarkerHttpServlet {
body.put("newPassword", newPassword); body.put("newPassword", newPassword);
body.put("confirmPassword", confirmPassword); body.put("confirmPassword", confirmPassword);
body.put("minPasswordLength", MIN_PASSWORD_LENGTH);
body.put("maxPasswordLength", MAX_PASSWORD_LENGTH);
for (String code : codes) { for (String code : codes) {
body.put(code, Boolean.TRUE); body.put(code, Boolean.TRUE);
} }

View file

@ -12,6 +12,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.MLevel;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Message; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Message;
/** /**
@ -21,13 +22,14 @@ public class BaseLoginServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(BaseLoginServlet.class); private static final Log log = LogFactory.getLog(BaseLoginServlet.class);
/** A general purpose error message for the user to see. */ /** A general purpose error message for the user to see. */
protected static final Message MESSAGE_LOGIN_FAILED = new LoginProcessBean.Message( protected static Message messageLoginFailed(HttpServletRequest req) {
"External login failed.", LoginProcessBean.MLevel.ERROR); return new LoginProcessBean.Message(req, MLevel.ERROR, "external_login_failed");
}
/** Tell the user that it's nothing personal, they just aren't allowed in. */ /** Tell the user that it's nothing personal, they just aren't allowed in. */
protected static final Message MESSAGE_LOGIN_DISABLED = new LoginProcessBean.Message( protected static Message messageLoginDisabled(HttpServletRequest req) {
"User logins are temporarily disabled while the system is being maintained.", return new LoginProcessBean.Message(req, MLevel.ERROR, "logins_temporarily_disabled");
LoginProcessBean.MLevel.ERROR); }
protected Authenticator getAuthenticator(HttpServletRequest req) { protected Authenticator getAuthenticator(HttpServletRequest req) {
return Authenticator.getInstance(req); return Authenticator.getInstance(req);
@ -40,10 +42,9 @@ public class BaseLoginServlet extends HttpServlet {
*/ */
protected void complainAndReturnToReferrer(HttpServletRequest req, protected void complainAndReturnToReferrer(HttpServletRequest req,
HttpServletResponse resp, String sessionAttributeForReferrer, HttpServletResponse resp, String sessionAttributeForReferrer,
Message message, Object... args) throws IOException { Message message) throws IOException {
log.debug(message.getMessageLevel() + ": " log.debug(message);
+ message.formatMessage(args)); LoginProcessBean.getBean(req).setMessage(message);
LoginProcessBean.getBean(req).setMessage(message, args);
String referrer = (String) req.getSession().getAttribute( String referrer = (String) req.getSession().getAttribute(
sessionAttributeForReferrer); sessionAttributeForReferrer);

View file

@ -71,7 +71,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
if (externalAuthId == null) { if (externalAuthId == null) {
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER, complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_LOGIN_FAILED); messageLoginFailed(req));
return; return;
} }
@ -84,7 +84,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
if (!getAuthenticator(req).isUserPermittedToLogin(userAccount)) { if (!getAuthenticator(req).isUserPermittedToLogin(userAccount)) {
log.debug("Logins disabled for " + userAccount); log.debug("Logins disabled for " + userAccount);
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER, complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_LOGIN_DISABLED); messageLoginDisabled(req));
return; return;
} }
@ -107,7 +107,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
// should have been caught by isUserPermittedToLogin() // should have been caught by isUserPermittedToLogin()
log.debug("Logins disabled for " + userAccount); log.debug("Logins disabled for " + userAccount);
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER, complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_LOGIN_DISABLED); messageLoginDisabled(req));
return; return;
} }
} }
@ -115,10 +115,10 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
@Override @Override
protected void complainAndReturnToReferrer(HttpServletRequest req, protected void complainAndReturnToReferrer(HttpServletRequest req,
HttpServletResponse resp, String sessionAttributeForReferrer, HttpServletResponse resp, String sessionAttributeForReferrer,
Message message, Object... args) throws IOException { Message message) throws IOException {
DisplayMessage.setMessage(req, message.formatMessage(args)); DisplayMessage.setMessage(req, message.getText());
super.complainAndReturnToReferrer(req, resp, super.complainAndReturnToReferrer(req, resp,
sessionAttributeForReferrer, message, args); sessionAttributeForReferrer, message);
} }
private void removeLoginProcessArtifacts(HttpServletRequest req) { private void removeLoginProcessArtifacts(HttpServletRequest req) {

View file

@ -53,7 +53,7 @@ public class LoginExternalAuthSetup extends BaseLoginServlet {
if (redirectUrl == null) { if (redirectUrl == null) {
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER, complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_LOGIN_FAILED); messageLoginFailed(req));
} }
log.debug("redirecting to '" + redirectUrl + "'"); log.debug("redirecting to '" + redirectUrl + "'");

View file

@ -21,6 +21,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
/** /**
* A user has just completed the login process. What page do we direct them to? * A user has just completed the login process. What page do we direct them to?
@ -30,6 +32,7 @@ public class LoginRedirector {
private final HttpServletRequest request; private final HttpServletRequest request;
private final HttpSession session; private final HttpSession session;
private final I18nBundle i18n;
private final String uriOfAssociatedIndividual; private final String uriOfAssociatedIndividual;
private final String afterLoginPage; private final String afterLoginPage;
@ -37,6 +40,7 @@ public class LoginRedirector {
public LoginRedirector(HttpServletRequest request, String afterLoginPage) { public LoginRedirector(HttpServletRequest request, String afterLoginPage) {
this.request = request; this.request = request;
this.session = request.getSession(); this.session = request.getSession();
this.i18n = I18n.bundle(request);
this.afterLoginPage = afterLoginPage; this.afterLoginPage = afterLoginPage;
uriOfAssociatedIndividual = getAssociatedIndividualUri(); uriOfAssociatedIndividual = getAssociatedIndividualUri();
@ -114,26 +118,23 @@ public class LoginRedirector {
public String assembleWelcomeMessage() { public String assembleWelcomeMessage() {
if (!canSeeSiteAdminPage() && !isSelfEditorWithIndividual()) { if (!canSeeSiteAdminPage() && !isSelfEditorWithIndividual()) {
// A special message for unrecognized self-editors: // A special message for unrecognized self-editors:
return "You have logged in, " return i18n.text("logged_in_but_no_profile");
+ "but the system contains no profile for you.";
} }
String backString = ""; String greeting = i18n.text("unknown_user_name");
String greeting = ""; int loginCount = 0;
UserAccount userAccount = LoginStatusBean.getCurrentUser(request); UserAccount userAccount = LoginStatusBean.getCurrentUser(request);
if (userAccount != null) { if (userAccount != null) {
greeting = userAccount.getEmailAddress(); loginCount = userAccount.getLoginCount();
if (userAccount.getLoginCount() > 1) { if (StringUtils.isNotEmpty(userAccount.getFirstName())) {
backString = " back"; greeting = userAccount.getFirstName();
} } else if (StringUtils.isNotEmpty(userAccount.getEmailAddress())) {
String name = userAccount.getFirstName(); greeting = userAccount.getEmailAddress();
if (!StringUtils.isEmpty(name)) {
greeting = name;
} }
} }
return "Welcome" + backString + ", " + greeting; return i18n.text("login_welcome_message", greeting, loginCount);
} }
public void redirectCancellingUser(HttpServletResponse response) public void redirectCancellingUser(HttpServletResponse response)

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit;
import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH;
import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.MLevel.ERROR;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.FORCED_PASSWORD_CHANGE; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.FORCED_PASSWORD_CHANGE;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGED_IN; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGED_IN;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGING_IN; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGING_IN;
@ -37,7 +38,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator.Lo
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFlag; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFlag;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Message;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginLogoutEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginLogoutEvent;
@ -309,7 +309,7 @@ public class Authenticate extends VitroHttpServlet {
+ bean); + bean);
if ((username == null) || username.isEmpty()) { if ((username == null) || username.isEmpty()) {
bean.setMessage(Message.NO_USERNAME); bean.setMessage(request, ERROR, "error_no_email_address");
return; return;
} }
@ -320,22 +320,22 @@ public class Authenticate extends VitroHttpServlet {
log.trace("User is " + (user == null ? "null" : user.getUri())); log.trace("User is " + (user == null ? "null" : user.getUri()));
if (user == null) { if (user == null) {
bean.setMessage(Message.UNKNOWN_USERNAME, username); bean.setMessage(request, ERROR, "error_incorrect_credentials");
return; return;
} }
if ((password == null) || password.isEmpty()) { if ((password == null) || password.isEmpty()) {
bean.setMessage(Message.NO_PASSWORD); bean.setMessage(request, ERROR, "error_no_password");
return; return;
} }
if (!getAuthenticator(request).isUserPermittedToLogin(user)) { if (!getAuthenticator(request).isUserPermittedToLogin(user)) {
bean.setMessage(Message.LOGIN_DISABLED); bean.setMessage(request, ERROR, "logins_disabled_for_maintenance");
return; return;
} }
if (!getAuthenticator(request).isCurrentPassword(user, password)) { if (!getAuthenticator(request).isCurrentPassword(user, password)) {
bean.setMessage(Message.INCORRECT_PASSWORD); bean.setMessage(request, ERROR, "error_incorrect_credentials");
return; return;
} }
@ -347,7 +347,8 @@ public class Authenticate extends VitroHttpServlet {
transitionToLoggedIn(request, user); transitionToLoggedIn(request, user);
} catch (LoginNotPermitted e) { } catch (LoginNotPermitted e) {
// This should have been caught by isUserPermittedToLogin() // This should have been caught by isUserPermittedToLogin()
bean.setMessage(Message.LOGIN_DISABLED); bean.setMessage(request, ERROR,
"logins_disabled_for_maintenance");
return; return;
} }
} }
@ -379,19 +380,19 @@ public class Authenticate extends VitroHttpServlet {
+ ", bean=" + bean); + ", bean=" + bean);
if ((newPassword == null) || newPassword.isEmpty()) { if ((newPassword == null) || newPassword.isEmpty()) {
bean.setMessage(Message.NO_NEW_PASSWORD); bean.setMessage(request, ERROR, "error_no_new_password");
return; return;
} }
if (!newPassword.equals(confirm)) { if (!newPassword.equals(confirm)) {
bean.setMessage(Message.MISMATCH_PASSWORD); bean.setMessage(request, ERROR, "error_passwords_dont_match");
return; return;
} }
if ((newPassword.length() < MIN_PASSWORD_LENGTH) if ((newPassword.length() < MIN_PASSWORD_LENGTH)
|| (newPassword.length() > MAX_PASSWORD_LENGTH)) { || (newPassword.length() > MAX_PASSWORD_LENGTH)) {
bean.setMessage(Message.PASSWORD_LENGTH, MIN_PASSWORD_LENGTH, bean.setMessage(request, ERROR, "error_password_length",
MAX_PASSWORD_LENGTH); MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH);
return; return;
} }
@ -400,7 +401,7 @@ public class Authenticate extends VitroHttpServlet {
UserAccount user = getAuthenticator(request).getAccountForInternalAuth( UserAccount user = getAuthenticator(request).getAccountForInternalAuth(
username); username);
if (getAuthenticator(request).isCurrentPassword(user, newPassword)) { if (getAuthenticator(request).isCurrentPassword(user, newPassword)) {
bean.setMessage(Message.USING_OLD_PASSWORD); bean.setMessage(request, ERROR, "error_previous_password");
return; return;
} }
@ -409,7 +410,7 @@ public class Authenticate extends VitroHttpServlet {
transitionToLoggedIn(request, user, newPassword); transitionToLoggedIn(request, user, newPassword);
} catch (LoginNotPermitted e) { } catch (LoginNotPermitted e) {
// This should have been caught by isUserPermittedToLogin() // This should have been caught by isUserPermittedToLogin()
bean.setMessage(Message.LOGIN_DISABLED); bean.setMessage(request, ERROR, "logins_disabled_for_maintenance");
return; return;
} }
} }

View file

@ -12,6 +12,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
/** /**
* Provide a means for programmatic logout. * Provide a means for programmatic logout.
@ -22,13 +23,14 @@ public class Logout extends HttpServlet {
/** This http header holds the referring page. */ /** This http header holds the referring page. */
private static final String HEADING_REFERRER = "referer"; private static final String HEADING_REFERRER = "referer";
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) { public void doPost(HttpServletRequest request, HttpServletResponse response) {
try { try {
String referrer = getReferringPage(request); String referrer = getReferringPage(request);
String redirectUrl = LogoutRedirector.getRedirectUrl(request, response, referrer); String redirectUrl = LogoutRedirector.getRedirectUrl(request, response, referrer);
Authenticator.getInstance(request).recordUserIsLoggedOut(); Authenticator.getInstance(request).recordUserIsLoggedOut();
DisplayMessage.setMessage(request, "You have logged out."); DisplayMessage.setMessage(request, I18n.bundle(request).text("logged_out"));
response.sendRedirect(redirectUrl); response.sendRedirect(redirectUrl);
} catch (Exception ex) { } catch (Exception ex) {
@ -45,6 +47,7 @@ public class Logout extends HttpServlet {
return referrer; return referrer;
} }
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) { public void doGet(HttpServletRequest request, HttpServletResponse response) {
doPost(request, response); doPost(request, response);
} }

View file

@ -2,7 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.login; package edu.cornell.mannlib.vitro.webapp.controller.login;
import java.text.MessageFormat;
import java.util.Arrays; import java.util.Arrays;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -11,6 +10,8 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
/** /**
* Where are we in the process of logging on? What message should we show to the * Where are we in the process of logging on? What message should we show to the
* user? * user?
@ -110,60 +111,32 @@ public class LoginProcessBean {
} }
public static class Message { public static class Message {
public static final Message NO_MESSAGE = new Message("", MLevel.NONE); public static final Message NO_MESSAGE = new Message();
public static final Message PASSWORD_CHANGE_SAVED = new Message( private final String text;
"Your password has been saved.<br/>" + "Please log in.",
MLevel.INFO);
public static final Message NO_USERNAME = new Message(
"Please enter your email address.", MLevel.ERROR);
public static final Message NO_PASSWORD = new Message(
"Please enter your password.", MLevel.ERROR);
public static final Message UNKNOWN_USERNAME = new Message(
"The email or password you entered is incorrect.", MLevel.ERROR);
public static final Message LOGIN_DISABLED = new Message(
"User logins are temporarily disabled while the system is being maintained.",
MLevel.ERROR);
public static final Message INCORRECT_PASSWORD = new Message(
"The email or password you entered is incorrect.", MLevel.ERROR);
public static final Message NO_NEW_PASSWORD = new Message(
"Please enter your new password.", MLevel.ERROR);
public static final Message MISMATCH_PASSWORD = new Message(
"The passwords entered do not match.", MLevel.ERROR);
public static final Message PASSWORD_LENGTH = new Message(
"Please enter a password between {0} and {1} characters in length.",
MLevel.ERROR);
public static final Message USING_OLD_PASSWORD = new Message(
"Your new password cannot match the current one.", MLevel.ERROR);
private final String format;
private final MLevel messageLevel; private final MLevel messageLevel;
public Message(String format, MLevel messageLevel) { public Message() {
this.format = format; this.messageLevel = MLevel.NONE;
this.text = "";
}
public Message(HttpServletRequest req, MLevel messageLevel, String textKey, Object... parameters) {
this.messageLevel = messageLevel; this.messageLevel = messageLevel;
this.text = I18n.bundle(req).text(textKey, parameters);
} }
public MLevel getMessageLevel() { public MLevel getMessageLevel() {
return this.messageLevel; return this.messageLevel;
} }
public String formatMessage(Object[] args) { public String getText() {
return new MessageFormat(this.format).format(args); return text;
} }
@Override @Override
public String toString() { public String toString() {
return "Message[" + messageLevel + ", '" + format + "']"; return "Message[" + messageLevel + ", '" + text + "']";
} }
} }
@ -210,10 +183,15 @@ public class LoginProcessBean {
} }
} }
public void setMessage(Message message, Object... args) { public void setMessage(Message message) {
synchronized (messageSynchronizer) { synchronized (messageSynchronizer) {
this.message = message; this.message = message;
this.messageArguments = args; }
}
public void setMessage(HttpServletRequest req, MLevel level, String textKey, Object... parameters) {
synchronized (messageSynchronizer) {
this.message = new Message(req, level, textKey, parameters);
} }
} }
@ -221,7 +199,7 @@ public class LoginProcessBean {
synchronized (messageSynchronizer) { synchronized (messageSynchronizer) {
String text = ""; String text = "";
if (message.getMessageLevel() == MLevel.INFO) { if (message.getMessageLevel() == MLevel.INFO) {
text = message.formatMessage(messageArguments); text = message.getText();
clearMessage(); clearMessage();
} }
return text; return text;
@ -232,7 +210,7 @@ public class LoginProcessBean {
synchronized (messageSynchronizer) { synchronized (messageSynchronizer) {
String text = ""; String text = "";
if (message.getMessageLevel() == MLevel.ERROR) { if (message.getMessageLevel() == MLevel.ERROR) {
text = message.formatMessage(messageArguments); text = message.getText();
clearMessage(); clearMessage();
} }
return text; return text;

View file

@ -18,6 +18,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
/** /**
* Call this at /selectLocale&selection=[locale_string] * Call this at /selectLocale&selection=[locale_string]
@ -75,8 +76,7 @@ public class LocaleSelectionController extends HttpServlet {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
log.error("Failed to convert the selection to a Locale", e); log.error("Failed to convert the selection to a Locale", e);
DisplayMessage.setMessage(req, DisplayMessage.setMessage(req,
"There was a problem in the system. " I18n.bundle(req).text("language_selection_failed"));
+ "Your language choice was rejected.");
return; return;
} }

View file

@ -12,6 +12,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFlag; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFlag;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
@ -56,7 +57,8 @@ public class LoginWidget extends Widget {
EXTERNAL_AUTH_NAME("externalAuthName"), EXTERNAL_AUTH_NAME("externalAuthName"),
EXTERNAL_AUTH_URL("externalAuthUrl"), EXTERNAL_AUTH_URL("externalAuthUrl"),
CANCEL_URL("cancelUrl"), CANCEL_URL("cancelUrl"),
SITE_NAME("siteName"); SITE_NAME("siteName"),
MINIMUM_PASSWORD_LENGTH("minimumPasswordLength");
private final String variableName; private final String variableName;
@ -172,6 +174,7 @@ public class LoginWidget extends Widget {
Macro.FORCE_PASSWORD_CHANGE.toString()); Macro.FORCE_PASSWORD_CHANGE.toString());
values.put(TemplateVariable.FORM_ACTION.toString(), getAuthenticateUrl(request)); values.put(TemplateVariable.FORM_ACTION.toString(), getAuthenticateUrl(request));
values.put(TemplateVariable.CANCEL_URL.toString(), getCancelUrl(request)); values.put(TemplateVariable.CANCEL_URL.toString(), getCancelUrl(request));
values.put(TemplateVariable.MINIMUM_PASSWORD_LENGTH.toString(), UserAccount.MIN_PASSWORD_LENGTH);
String errorMessage = bean.getErrorMessageAndClear(); String errorMessage = bean.getErrorMessageAndClear();
if (!errorMessage.isEmpty()) { if (!errorMessage.isEmpty()) {

View file

@ -26,6 +26,7 @@ import stubs.edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesStub
import stubs.edu.cornell.mannlib.vitro.webapp.dao.IndividualDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.IndividualDaoStub;
import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub;
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
import stubs.edu.cornell.mannlib.vitro.webapp.i18n.I18nStub;
import stubs.javax.servlet.ServletConfigStub; import stubs.javax.servlet.ServletConfigStub;
import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.ServletContextStub;
import stubs.javax.servlet.http.HttpServletRequestStub; import stubs.javax.servlet.http.HttpServletRequestStub;
@ -120,6 +121,11 @@ public class AuthenticateTest extends AbstractTestClass {
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
// Create an I18n module that has a value for any key, but the value is
// the key itself.
@SuppressWarnings("unused")
I18nStub i18n = new I18nStub();
authenticatorFactory = new AuthenticatorStub.Factory(); authenticatorFactory = new AuthenticatorStub.Factory();
authenticator = authenticatorFactory.getInstance(request); authenticator = authenticatorFactory.getInstance(request);
authenticator.addUser(createUserFromUserInfo(NEW_DBA)); authenticator.addUser(createUserFromUserInfo(NEW_DBA));
@ -314,7 +320,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(LOGGING_IN, NO_USER, NO_MSG, assertProcessBean(LOGGING_IN, NO_USER, NO_MSG,
"Please enter your email address.", URL_LOGIN, URL_WITH_LINK); "error_no_email_address", URL_LOGIN, URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }
@ -326,8 +332,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(LOGGING_IN, "unknownBozo", NO_MSG, assertProcessBean(LOGGING_IN, "unknownBozo", NO_MSG,
"The email or password you entered is incorrect.", URL_LOGIN, "error_incorrect_credentials", URL_LOGIN, URL_WITH_LINK);
URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }
@ -339,7 +344,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG, assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG,
"Please enter your password.", URL_LOGIN, URL_WITH_LINK); "error_no_password", URL_LOGIN, URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }
@ -351,8 +356,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG, assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG,
"The email or password you entered is incorrect.", URL_LOGIN, "error_incorrect_credentials", URL_LOGIN, URL_WITH_LINK);
URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }
@ -403,8 +407,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG,
"Please enter a password between 6 and 12 " "error_password_length", URL_LOGIN, URL_WITH_LINK);
+ "characters in length.", URL_LOGIN, URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }
@ -417,7 +420,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG,
"The passwords entered do not match.", URL_LOGIN, URL_WITH_LINK); "error_passwords_dont_match", URL_LOGIN, URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }
@ -430,7 +433,7 @@ public class AuthenticateTest extends AbstractTestClass {
doTheRequest(); doTheRequest();
assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG,
"Your new password cannot match the current one.", URL_LOGIN, "error_previous_password", URL_LOGIN,
URL_WITH_LINK); URL_WITH_LINK);
assertRedirectToLoginProcessPage(); assertRedirectToLoginProcessPage();
} }

View file

@ -108,6 +108,14 @@ updated_account_notification = A confirmation email has been sent to {0} \
deleted_accounts = Deleted {0} {0, choice, 0#accounts |1#account |1<accounts}. deleted_accounts = Deleted {0} {0, choice, 0#accounts |1#account |1<accounts}.
enter_new_password = Please enter your new password for {0} enter_new_password = Please enter your new password for {0}
error_no_email_address = Please enter your email address.
error_no_password = Please enter your password.
error_incorrect_credentials = The email or password you entered is incorrect.
logins_disabled_for_maintenance = User logins are temporarily disabled while the system is being maintained.
error_no_new_password = Please enter your new password.
error_passwords_dont_match = The passwords entered do not match.
error_password_length = Please enter a password between {0} and {1} characters in length.
error_previous_password = Your new password cannot match the current one.
search_accounts_button = Search accounts search_accounts_button = Search accounts
accounts_search_results = Search results for accounts_search_results = Search results for
@ -216,6 +224,14 @@ error_no_password = No password supplied.
error_password_length = Password must be between {0} and {1} characters. error_password_length = Password must be between {0} and {1} characters.
error_password_mismatch = Passwords do not match. error_password_mismatch = Passwords do not match.
logged_in_but_no_profile = You have logged in, but the system contains no profile for you.
unknown_user_name = friend
login_welcome_message = Welcome{1, choice, 1# |1< back}, {0}
external_login_failed = External login failed
logged_out = You have logged out.
insufficient_authorization = We're sorry, but you are not authorized to view the page you requested. If you think this is an error, please contact us and we'll be happy to help.
# #
# "partial" individual templates ( /templates/freemarker/body/partials/individual ) # "partial" individual templates ( /templates/freemarker/body/partials/individual )
# #
@ -259,6 +275,8 @@ logins_already_restricted = Logins are already restricted.
logins_not_already_restricted = Logins are already not restricted. logins_not_already_restricted = Logins are already not restricted.
logins_restricted = Logins are now restricted. logins_restricted = Logins are now restricted.
logins_not_restricted = Logins are no longer restricted. logins_not_restricted = Logins are no longer restricted.
logins_are_open = Logins are open to all.
logins_are_restricted = Logins are restricted.
remove_restrictions = Remove Restrictions remove_restrictions = Remove Restrictions
restrict_logins = Restrict Logins restrict_logins = Restrict Logins
error_alert_icon = Error alert icon error_alert_icon = Error alert icon
@ -351,7 +369,7 @@ no_email_supplied = No email supplied.
no_password_supplied = No password supplied. no_password_supplied = No password supplied.
logins_temporarily_disabled = User logins are temporarily disabled while the system is being maintained. logins_temporarily_disabled = User logins are temporarily disabled while the system is being maintained.
incorrect_email_password = Email or Password was incorrect. incorrect_email_password = Email or Password was incorrect.
password_length = Password must be between 6 and 12 characters. password_length = Password must be between {0} and {1} characters.
password_mismatch = Passwords do not match. password_mismatch = Passwords do not match.
new_pwd_matches_existing = Your new password must be different from your existing password. new_pwd_matches_existing = Your new password must be different from your existing password.
enter_email_password = Enter the email address and password for your internal Vitro account. enter_email_password = Enter the email address and password for your internal Vitro account.
@ -615,6 +633,7 @@ index = Index
search_form = Search form search_form = Search form
select_locale = select locale select_locale = select locale
language_selection_failed = There was a problem in the system. Your language choice was rejected.
menu_item = menu item menu_item = menu item
version = Version version = Version
@ -637,7 +656,7 @@ account = account
change_password_to_login = Change Password to Log in change_password_to_login = Change Password to Log in
new_password_capitalized = New Password new_password_capitalized = New Password
confirm_password_capitalized = Confirm Password confirm_password_capitalized = Confirm Password
minimum_six_chars = Minimum of 6 characters in length. minimum_password_length = Minimum of {0} characters in length.
already_logged_in = You are already logged in. already_logged_in = You are already logged in.
# #

View file

@ -99,9 +99,17 @@ updated_account_1 = La cuenta para el
updated_account_2 = se ha actualizado. updated_account_2 = se ha actualizado.
updated_account_title = descripción actualizada updated_account_title = descripción actualizada
updated_account_notification = Un correo electrónico de confirmación ha sido enviado a {0} con instrucciones para restablecer la contraseña. La contraseña no se restablecerá hasta que el usuario sigue el enlace que aparece en este correo electrónico. updated_account_notification = Un correo electrónico de confirmación ha sido enviado a {0} con instrucciones para restablecer la contraseña. La contraseña no se restablecerá hasta que el usuario sigue el enlace que aparece en este correo electrónico.
deleted_accounts = Suprimido {0} {0, choice, 0 # cuentas | # 1 cuenta | 1 <cuentas}. deleted_accounts = Suprimido {0} {0, choice, 0#cuentas | 1#cuenta | 1<cuentas}.
enter_new_password = Introduzca su nueva contraseña para {0} enter_new_password = Introduzca su nueva contraseña para {0}
error_no_email_address = Introduzca su dirección de correo electrónico.
error_no_password = Suministrado ninguna contraseña.
error_incorrect_credentials = El email o la contraseña son incorrectos.
logins_disabled_for_maintenance = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema.
error_no_new_password = Introduzca su nueva contraseña.
error_passwords_dont_match = Las contraseñas introducidas no coinciden.
error_password_length = La contraseña debe tener entre {0} y {1} caracteres.
error_previous_password = La nueva contraseña no puede coincidir con la actual.
search_accounts_button = Cuentas búsqueda search_accounts_button = Cuentas búsqueda
accounts_search_results = Resultados de la búsqueda accounts_search_results = Resultados de la búsqueda
@ -204,6 +212,14 @@ error_no_password = Suministrado ninguna contraseña.
error_password_length = La contraseña debe tener entre {0} y {1} caracteres. error_password_length = La contraseña debe tener entre {0} y {1} caracteres.
error_password_mismatch = Las contraseñas no coinciden. error_password_mismatch = Las contraseñas no coinciden.
logged_in_but_no_profile = Usted ha ingresado, pero el sistema no contiene ningún perfil para usted.
unknown_user_name = amigo
login_welcome_message = Bienvenido {1, choice, 1# | 1< atrás}, {0}
external_login_failed = Acceso externo no
logged_out = Ha cerrado la sesión.
insufficient_authorization = Lo sentimos, pero no está autorizado para ver la página solicitada. Si crees que esto es un error, por favor póngase en contacto con nosotros y estaremos encantados de ayudarle.
# #
# "partial" individual templates ( /templates/freemarker/body/partials/individual ) # "partial" individual templates ( /templates/freemarker/body/partials/individual )
# #
@ -247,6 +263,8 @@ logins_already_restricted = Inicios de sesión ya se encuentran restringidas.
logins_not_already_restricted = Inicios de sesión ya no están restringidos. logins_not_already_restricted = Inicios de sesión ya no están restringidos.
logins_restricted = Inicios de sesión están restringidas. logins_restricted = Inicios de sesión están restringidas.
logins_not_restricted = Inicios de sesión ya no están restringidos. logins_not_restricted = Inicios de sesión ya no están restringidos.
logins_are_open = Inicios de sesión están abiertas a todos.
logins_are_restricted = Inicios de sesión se encuentran restringidas.
remove_restrictions = Eliminar las restricciones remove_restrictions = Eliminar las restricciones
restrict_logins = Restringir inicios de sesión restrict_logins = Restringir inicios de sesión
error_alert_icon = Error icono de alerta error_alert_icon = Error icono de alerta
@ -339,7 +357,7 @@ no_email_supplied = Sin correo electrónico suministrado.
no_password_supplied = Suministrado ninguna contraseña. no_password_supplied = Suministrado ninguna contraseña.
logins_temporarily_disabled = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema. logins_temporarily_disabled = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema.
incorrect_email_password = Email o contraseña es incorrecta. incorrect_email_password = Email o contraseña es incorrecta.
password_length = La contraseña debe tener entre 6 y 12 caracteres. password_length = La contraseña debe tener entre {0} y {1} caracteres.
password_mismatch = Las contraseñas no coinciden. password_mismatch = Las contraseñas no coinciden.
new_pwd_matches_existing = Su nueva contraseña debe ser diferente de la contraseña existente. new_pwd_matches_existing = Su nueva contraseña debe ser diferente de la contraseña existente.
enter_email_password = Introduzca la dirección de correo electrónico y la contraseña de su cuenta de Vitro interna. enter_email_password = Introduzca la dirección de correo electrónico y la contraseña de su cuenta de Vitro interna.
@ -603,6 +621,7 @@ index = Índice
search_form = Formulario de búsqueda search_form = Formulario de búsqueda
select_locale = seleccionar la configuración regional select_locale = seleccionar la configuración regional
language_selection_failed = Hubo un problema en el sistema. Su elección de la lengua fue rechazada.
menu_item = elemento de menú menu_item = elemento de menú
version = Versión version = Versión
@ -625,7 +644,7 @@ account = cuenta
change_password_to_login = Cambiar contraseña para iniciar sesión en change_password_to_login = Cambiar contraseña para iniciar sesión en
new_password_capitalized = Nueva contraseña new_password_capitalized = Nueva contraseña
confirm_password_capitalized = Confirmar Contraseña confirm_password_capitalized = Confirmar Contraseña
minimum_six_chars = Mínimo de 6 caracteres de longitud. minimum_password_length = Mínimo de {0} caracteres de longitud.
already_logged_in = Usted ya está registrado already_logged_in = Usted ya está registrado
# #

View file

@ -62,7 +62,7 @@
<section id="passwordContainer" role="region"> <section id="passwordContainer" role="region">
<label for="initial-password">${strings.initial_password}<span class="requiredHint"> *</span></label> <label for="initial-password">${strings.initial_password}<span class="requiredHint"> *</span></label>
<input type="password" name="initialPassword" value="${initialPassword}" id="initial-password" role="input" /> <input type="password" name="initialPassword" value="${initialPassword}" id="initial-password" role="input" />
<p class="note">${strings.minimum_password_length}</p> <p class="note">${strings.minimum_password_length(minimumLength)}</p>
<label for="confirm-password">${strings.confirm_initial_password}<span class="requiredHint"> *</span></label> <label for="confirm-password">${strings.confirm_initial_password}<span class="requiredHint"> *</span></label>
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" /> <input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />

View file

@ -47,7 +47,7 @@
<p><input type="submit" name="submit" value="${strings.create_account}" class="submit"/> <p><input type="submit" name="submit" value="${strings.create_account}" class="submit"/>
${strings.or} ${strings.or}
<a class="cancel" href="${urls.home}" title="${string.cancel_title}">${strings.cancel_link}</a> <a class="cancel" href="${urls.home}" title="${strings.cancel_title}">${strings.cancel_link}</a>
</p> </p>
<p class="requiredHint">* ${strings.required_fields}</p> <p class="requiredHint">* ${strings.required_fields}</p>

View file

@ -2,7 +2,7 @@
<#-- Template for restricting (or opening) access to logins. --> <#-- Template for restricting (or opening) access to logins. -->
<h2>Restrict Logins</h2> <h2>${i18n().restrict_logins}</h2>
<#if messageAlreadyRestricted??> <#if messageAlreadyRestricted??>
<#assign errorMessage = "${i18n().logins_already_restricted}" /> <#assign errorMessage = "${i18n().logins_already_restricted}" />
</#if> </#if>
@ -35,10 +35,10 @@
<section id="restrict-login" role="region"> <section id="restrict-login" role="region">
<#if restricted == true> <#if restricted == true>
<h4>Logins are restricted</h4> <h4>${i18n().logins_are_restricted}</h4>
<p><a href="${openUrl}" title="${i18n().remove_restrictions}">${i18n().remove_restrictions}</a></p> <p><a href="${openUrl}" title="${i18n().remove_restrictions}">${i18n().remove_restrictions}</a></p>
<#else> <#else>
<h4>Logins are open to all</h4> <h4>${i18n().logins_are_open}</h4>
<p><a href="${restrictUrl}" title="${i18n().Restrict Logins}">${i18n().Restrict Logins}</a></p> <p><a href="${restrictUrl}" title="${i18n().restrict_logins}">${i18n().restrict_logins}</a></p>
</#if> </#if>
</section> </section>

View file

@ -22,7 +22,7 @@
</#if> </#if>
<#if errorNewPasswordWrongLength??> <#if errorNewPasswordWrongLength??>
<#assign errorMessage = "${i18n().password_length}" /> <#assign errorMessage = "${i18n().password_length(minPasswordLength, maxPasswordLength)}" />
</#if> </#if>
<#if errorNewPasswordsDontMatch??> <#if errorNewPasswordsDontMatch??>
@ -51,7 +51,7 @@
<label for="newPassword">${i18n().new_password}</label> <label for="newPassword">${i18n().new_password}</label>
<input name="newPassword" id="newPassword" class="text-field" type="password" required autofocus /> <input name="newPassword" id="newPassword" class="text-field" type="password" required autofocus />
<p class="password-note">${i18n().Minimum of 6 characters in length.</p> <p class="password-note">${i18n().minimum_password_length(minPasswordLength)}</p>
<label for="confirmPassword">${i18n().confirm_password}</label> <label for="confirmPassword">${i18n().confirm_password}</label>
<input id="confirmPassword" name="confirmPassword" class="text-field" type="password" required /> <input id="confirmPassword" name="confirmPassword" class="text-field" type="password" required />

View file

@ -90,7 +90,7 @@
<label for="newPassword">${i18n().new_password_capitalized}</label> <label for="newPassword">${i18n().new_password_capitalized}</label>
<input id="newPassword" name="newPassword" class="text-field focus" type="password" required autofocus/> <input id="newPassword" name="newPassword" class="text-field focus" type="password" required autofocus/>
<p class="password-note">${i18n().minimum_six_chars}</p> <p class="password-note">${i18n().minimum_password_length(minimumPasswordLength)}</p>
<label for="confirmPassword">${i18n().confirm_password_capitalized}</label> <label for="confirmPassword">${i18n().confirm_password_capitalized}</label>
<input id="confirmPassword" name="confirmPassword" class="text-field" type="password" required /> <input id="confirmPassword" name="confirmPassword" class="text-field" type="password" required />