NIHVIVO-2694 Add methods and an exception to Authenticator, so we can tell when a user is not allowed to login.
This commit is contained in:
parent
0a19ed7d86
commit
6986eb6308
12 changed files with 164 additions and 32 deletions
|
@ -124,6 +124,11 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
+ "'";
|
+ "'";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!Authenticator.getInstance(vreq).isUserPermittedToLogin(null)) {
|
||||||
|
bogusMessage = "User logins are temporarily disabled "
|
||||||
|
+ "while the system is being maintained.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBogus() {
|
public boolean isBogus() {
|
||||||
|
|
|
@ -13,6 +13,7 @@ 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.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
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.Authenticator.LoginNotPermitted;
|
||||||
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.freemarker.FreemarkerHttpServlet;
|
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.RedirectResponseValues;
|
||||||
|
@ -108,10 +109,15 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
||||||
if (page.isBogus()) {
|
if (page.isBogus()) {
|
||||||
return showHomePage(vreq, page.getBogusMessage());
|
return showHomePage(vreq, page.getBogusMessage());
|
||||||
} else if (page.isSubmit() && page.isValid()) {
|
} else if (page.isSubmit() && page.isValid()) {
|
||||||
UserAccount userAccount = page.createAccount();
|
try {
|
||||||
Authenticator auth = Authenticator.getInstance(vreq);
|
UserAccount userAccount = page.createAccount();
|
||||||
auth.recordLoginAgainstUserAccount(userAccount, EXTERNAL);
|
Authenticator auth = Authenticator.getInstance(vreq);
|
||||||
return showLoginRedirection(vreq, page.getAfterLoginUrl());
|
auth.recordLoginAgainstUserAccount(userAccount, EXTERNAL);
|
||||||
|
return showLoginRedirection(vreq, page.getAfterLoginUrl());
|
||||||
|
} catch (LoginNotPermitted e) {
|
||||||
|
// This should have been anticipated by the page.
|
||||||
|
return showHomePage(vreq, BOGUS_STANDARD_MESSAGE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return page.showPage();
|
return page.showPage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator.LoginNotPermitted;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
|
||||||
|
@ -44,6 +45,7 @@ public class AdminLoginController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
private static final String MESSAGE_NO_EMAIL_ADDRESS = "errorNoEmail";
|
private static final String MESSAGE_NO_EMAIL_ADDRESS = "errorNoEmail";
|
||||||
private static final String MESSAGE_NO_PASSWORD = "errorNoPassword";
|
private static final String MESSAGE_NO_PASSWORD = "errorNoPassword";
|
||||||
|
private static final String MESSAGE_LOGIN_DISABLED = "errorLoginDisabled";
|
||||||
private static final String MESSAGE_LOGIN_FAILED = "errorLoginFailed";
|
private static final String MESSAGE_LOGIN_FAILED = "errorLoginFailed";
|
||||||
private static final String MESSAGE_NEW_PASSWORD_REQUIRED = "newPasswordRequired";
|
private static final String MESSAGE_NEW_PASSWORD_REQUIRED = "newPasswordRequired";
|
||||||
private static final String MESSAGE_NEW_PASSWORD_WRONG_LENGTH = "errorNewPasswordWrongLength";
|
private static final String MESSAGE_NEW_PASSWORD_WRONG_LENGTH = "errorNewPasswordWrongLength";
|
||||||
|
@ -101,6 +103,9 @@ public class AdminLoginController extends FreemarkerHttpServlet {
|
||||||
if (password.isEmpty()) {
|
if (password.isEmpty()) {
|
||||||
return showForm(MESSAGE_NO_PASSWORD);
|
return showForm(MESSAGE_NO_PASSWORD);
|
||||||
}
|
}
|
||||||
|
if (!loginPermitted()) {
|
||||||
|
return showForm(MESSAGE_LOGIN_DISABLED);
|
||||||
|
}
|
||||||
if (newPasswordRequired()) {
|
if (newPasswordRequired()) {
|
||||||
if (newPassword.isEmpty()) {
|
if (newPassword.isEmpty()) {
|
||||||
return showForm(MESSAGE_NEW_PASSWORD_REQUIRED);
|
return showForm(MESSAGE_NEW_PASSWORD_REQUIRED);
|
||||||
|
@ -127,6 +132,10 @@ public class AdminLoginController extends FreemarkerHttpServlet {
|
||||||
return showForm(MESSAGE_LOGIN_FAILED);
|
return showForm(MESSAGE_LOGIN_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean loginPermitted() {
|
||||||
|
return auth.isUserPermittedToLogin(userAccount);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean newPasswordRequired() {
|
private boolean newPasswordRequired() {
|
||||||
return auth.isCurrentPassword(userAccount, password)
|
return auth.isCurrentPassword(userAccount, password)
|
||||||
&& (userAccount.isPasswordChangeRequired());
|
&& (userAccount.isPasswordChangeRequired());
|
||||||
|
@ -138,17 +147,21 @@ public class AdminLoginController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean tryToLogin() {
|
private boolean tryToLogin() {
|
||||||
if (auth.isCurrentPassword(userAccount, password)) {
|
if (!auth.isCurrentPassword(userAccount, password)) {
|
||||||
auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
|
|
||||||
|
|
||||||
if (!newPassword.isEmpty()) {
|
|
||||||
auth.recordNewPassword(userAccount, newPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
|
||||||
|
} catch (LoginNotPermitted e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newPassword.isEmpty()) {
|
||||||
|
auth.recordNewPassword(userAccount, newPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues showForm(String... codes) {
|
private ResponseValues showForm(String... codes) {
|
||||||
|
|
|
@ -23,6 +23,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
* This needs to be based on a HttpSession, because things like the UserDAO are
|
* This needs to be based on a HttpSession, because things like the UserDAO are
|
||||||
* tied to the session. It seemed easier to base it on a HttpServletRequest,
|
* tied to the session. It seemed easier to base it on a HttpServletRequest,
|
||||||
* which we can use to get the session.
|
* which we can use to get the session.
|
||||||
|
*
|
||||||
|
* TODO: Wouldn't it be cool if we could remove the LoginNotPermitted exception?
|
||||||
|
* Perhaps we could have a sub-object called an Authenticator.ForUser, and you
|
||||||
|
* call a getAuthenticatorForUser() method which returns null if your login has
|
||||||
|
* been disabled. Then, that object would provide these methods:
|
||||||
|
* accountRequiresEditing(), getAssociatedIndividualUris(), isCurrentPassword(),
|
||||||
|
* recordLoginAgainstUserAccount(), recordNewPassword(). If you didn't have such
|
||||||
|
* an object, you couldn't even call these methods.
|
||||||
*/
|
*/
|
||||||
public abstract class Authenticator {
|
public abstract class Authenticator {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -48,11 +56,11 @@ public abstract class Authenticator {
|
||||||
public static Authenticator getInstance(HttpServletRequest request) {
|
public static Authenticator getInstance(HttpServletRequest request) {
|
||||||
ServletContext ctx = request.getSession().getServletContext();
|
ServletContext ctx = request.getSession().getServletContext();
|
||||||
Object attribute = ctx.getAttribute(FACTORY_ATTRIBUTE_NAME);
|
Object attribute = ctx.getAttribute(FACTORY_ATTRIBUTE_NAME);
|
||||||
if (! (attribute instanceof AuthenticatorFactory)) {
|
if (!(attribute instanceof AuthenticatorFactory)) {
|
||||||
attribute = new BasicAuthenticator.Factory();
|
attribute = new BasicAuthenticator.Factory();
|
||||||
ctx.setAttribute(FACTORY_ATTRIBUTE_NAME, attribute);
|
ctx.setAttribute(FACTORY_ATTRIBUTE_NAME, attribute);
|
||||||
}
|
}
|
||||||
AuthenticatorFactory factory = (AuthenticatorFactory) attribute;
|
AuthenticatorFactory factory = (AuthenticatorFactory) attribute;
|
||||||
|
|
||||||
return factory.getInstance(request);
|
return factory.getInstance(request);
|
||||||
}
|
}
|
||||||
|
@ -77,6 +85,16 @@ public abstract class Authenticator {
|
||||||
*/
|
*/
|
||||||
public abstract UserAccount getAccountForInternalAuth(String emailAddress);
|
public abstract UserAccount getAccountForInternalAuth(String emailAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this user permitted to login? Some Authenticators might disable logins
|
||||||
|
* for certain users.
|
||||||
|
*
|
||||||
|
* Behavior when userAccount is null depends on the particular
|
||||||
|
* Authenticator. An answer of "true" presumably means that the user will be
|
||||||
|
* permitted to login and create an account on the fly.
|
||||||
|
*/
|
||||||
|
public abstract boolean isUserPermittedToLogin(UserAccount userAccount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal: does this UserAccount have this password? False if the
|
* Internal: does this UserAccount have this password? False if the
|
||||||
* userAccount is null.
|
* userAccount is null.
|
||||||
|
@ -113,9 +131,14 @@ public abstract class Authenticator {
|
||||||
* - record the user in the session map
|
* - record the user in the session map
|
||||||
* - notify other users of the model
|
* - notify other users of the model
|
||||||
* </pre>
|
* </pre>
|
||||||
|
*
|
||||||
|
* @throws LoginNotPermitted
|
||||||
|
* if the Authenticator denies this user the ability to login.
|
||||||
|
* This should be thrown if and only if isUserPermittedToLogin()
|
||||||
|
* returns false.
|
||||||
*/
|
*/
|
||||||
public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
|
public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
|
||||||
AuthenticationSource authSource);
|
AuthenticationSource authSource) throws LoginNotPermitted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
|
@ -173,4 +196,12 @@ public abstract class Authenticator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Exceptions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public static class LoginNotPermitted extends Exception {
|
||||||
|
// no other information
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,11 @@ public class BaseLoginServlet extends HttpServlet {
|
||||||
protected static final Message MESSAGE_LOGIN_FAILED = new LoginProcessBean.Message(
|
protected static final Message MESSAGE_LOGIN_FAILED = new LoginProcessBean.Message(
|
||||||
"External login failed.", LoginProcessBean.MLevel.ERROR);
|
"External login failed.", LoginProcessBean.MLevel.ERROR);
|
||||||
|
|
||||||
|
/** Tell the user that it's nothing personal, they just aren't allowed in. */
|
||||||
|
protected static final Message MESSAGE_LOGIN_DISABLED = new LoginProcessBean.Message(
|
||||||
|
"User logins are temporarily disabled while the system is being maintained.",
|
||||||
|
LoginProcessBean.MLevel.ERROR);
|
||||||
|
|
||||||
protected Authenticator getAuthenticator(HttpServletRequest req) {
|
protected Authenticator getAuthenticator(HttpServletRequest req) {
|
||||||
return Authenticator.getInstance(req);
|
return Authenticator.getInstance(req);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,13 @@ public class BasicAuthenticator extends Authenticator {
|
||||||
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId);
|
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUserPermittedToLogin(UserAccount userAccount) {
|
||||||
|
// All users are permitted to login. If the user doesn't have an account
|
||||||
|
// yet (userAccount is null), an account should be created for them.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCurrentPassword(UserAccount userAccount,
|
public boolean isCurrentPassword(UserAccount userAccount,
|
||||||
String clearTextPassword) {
|
String clearTextPassword) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsFirstTimeExternalPage;
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsFirstTimeExternalPage;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator.LoginNotPermitted;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||||
|
|
||||||
|
@ -77,6 +78,14 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
||||||
|
|
||||||
UserAccount userAccount = getAuthenticator(req)
|
UserAccount userAccount = getAuthenticator(req)
|
||||||
.getAccountForExternalAuth(externalAuthId);
|
.getAccountForExternalAuth(externalAuthId);
|
||||||
|
|
||||||
|
if (!getAuthenticator(req).isUserPermittedToLogin(userAccount)) {
|
||||||
|
log.debug("Logins disabled for " + userAccount);
|
||||||
|
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
|
||||||
|
MESSAGE_LOGIN_DISABLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (userAccount == null) {
|
if (userAccount == null) {
|
||||||
log.debug("Creating new account for " + externalAuthId
|
log.debug("Creating new account for " + externalAuthId
|
||||||
+ ", return to '" + afterLoginUrl + "'");
|
+ ", return to '" + afterLoginUrl + "'");
|
||||||
|
@ -84,12 +93,20 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
||||||
externalAuthId, afterLoginUrl);
|
externalAuthId, afterLoginUrl);
|
||||||
resp.sendRedirect(UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
resp.sendRedirect(UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
log.debug("Logging in as " + userAccount.getUri());
|
log.debug("Logging in as " + userAccount.getUri());
|
||||||
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
|
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
|
||||||
AuthenticationSource.EXTERNAL);
|
AuthenticationSource.EXTERNAL);
|
||||||
new LoginRedirector(req, afterLoginUrl).redirectLoggedInUser(resp);
|
new LoginRedirector(req, afterLoginUrl).redirectLoggedInUser(resp);
|
||||||
return;
|
return;
|
||||||
|
} catch (LoginNotPermitted e) {
|
||||||
|
// should have been caught by isUserPermittedToLogin()
|
||||||
|
log.debug("Logins disabled for " + userAccount);
|
||||||
|
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
|
||||||
|
MESSAGE_LOGIN_DISABLED);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,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.beans.UserAccount;
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator.LoginNotPermitted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide a means for programmatic login If they provide the right parameters,
|
* Provide a means for programmatic login If they provide the right parameters,
|
||||||
|
@ -29,13 +30,18 @@ public class ProgramLogin extends HttpServlet {
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
new ProgramLoginCore(req, resp).process();
|
try {
|
||||||
|
new ProgramLoginCore(req, resp).process();
|
||||||
|
} catch (LoginNotPermitted e) {
|
||||||
|
// This should have been prevented by the test for loginDisabled()
|
||||||
|
throw new ServletException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
new ProgramLoginCore(req, resp).process();
|
doGet(req, resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ProgramLoginCore {
|
static class ProgramLoginCore {
|
||||||
|
@ -50,6 +56,8 @@ public class ProgramLogin extends HttpServlet {
|
||||||
+ " parameter is required.";
|
+ " parameter is required.";
|
||||||
private static final String MESSAGE_WRONG_USER_OR_PASSWORD = PARAM_EMAIL_ADDRESS
|
private static final String MESSAGE_WRONG_USER_OR_PASSWORD = PARAM_EMAIL_ADDRESS
|
||||||
+ " or " + PARAM_PASSWORD + " is incorrect.";
|
+ " or " + PARAM_PASSWORD + " is incorrect.";
|
||||||
|
private static final String MESSAGE_LOGIN_DISABLED = "User logins are "
|
||||||
|
+ "temporarily disabled while the system is being maintained.";
|
||||||
private static final String MESSAGE_NEED_NEW_PASSWORD = "first-time login: "
|
private static final String MESSAGE_NEED_NEW_PASSWORD = "first-time login: "
|
||||||
+ PARAM_NEW_PASSWORD + " parameter is required.";
|
+ PARAM_NEW_PASSWORD + " parameter is required.";
|
||||||
private static final String MESSAGE_NEW_PASSWORD_NOT_NEEDED = "not first-time login: "
|
private static final String MESSAGE_NEW_PASSWORD_NOT_NEEDED = "not first-time login: "
|
||||||
|
@ -90,7 +98,7 @@ public class ProgramLogin extends HttpServlet {
|
||||||
.getAccountForInternalAuth(this.emailAddress);
|
.getAccountForInternalAuth(this.emailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process() throws IOException {
|
void process() throws IOException, LoginNotPermitted {
|
||||||
if (emailAddress.isEmpty()) {
|
if (emailAddress.isEmpty()) {
|
||||||
sendError(MESSAGE_NEED_EMAIL_ADDRESS);
|
sendError(MESSAGE_NEED_EMAIL_ADDRESS);
|
||||||
return;
|
return;
|
||||||
|
@ -104,6 +112,11 @@ public class ProgramLogin extends HttpServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loginDisabled()) {
|
||||||
|
sendError(MESSAGE_LOGIN_DISABLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isPasswordChangeRequired()) {
|
if (!isPasswordChangeRequired()) {
|
||||||
if (!newPassword.isEmpty()) {
|
if (!newPassword.isEmpty()) {
|
||||||
sendError(MESSAGE_NEW_PASSWORD_NOT_NEEDED);
|
sendError(MESSAGE_NEW_PASSWORD_NOT_NEEDED);
|
||||||
|
@ -147,6 +160,10 @@ public class ProgramLogin extends HttpServlet {
|
||||||
return auth.isCurrentPassword(userAccount, password);
|
return auth.isCurrentPassword(userAccount, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean loginDisabled() {
|
||||||
|
return !auth.isUserPermittedToLogin(userAccount);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean newPasswordIsValidPasswordLength() {
|
private boolean newPasswordIsValidPasswordLength() {
|
||||||
return (newPassword.length() >= MIN_PASSWORD_LENGTH)
|
return (newPassword.length() >= MIN_PASSWORD_LENGTH)
|
||||||
&& (newPassword.length() <= MAX_PASSWORD_LENGTH);
|
&& (newPassword.length() <= MAX_PASSWORD_LENGTH);
|
||||||
|
@ -160,11 +177,11 @@ public class ProgramLogin extends HttpServlet {
|
||||||
return (userAccount.isPasswordChangeRequired());
|
return (userAccount.isPasswordChangeRequired());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordLogin() {
|
private void recordLogin() throws LoginNotPermitted {
|
||||||
auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
|
auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordLoginWithPasswordChange() {
|
private void recordLoginWithPasswordChange() throws LoginNotPermitted {
|
||||||
auth.recordNewPassword(userAccount, newPassword);
|
auth.recordNewPassword(userAccount, newPassword);
|
||||||
auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
|
auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
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.Authenticator.LoginNotPermitted;
|
||||||
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;
|
||||||
|
@ -327,6 +328,11 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!getAuthenticator(request).isUserPermittedToLogin(user)) {
|
||||||
|
bean.setMessage(Message.LOGIN_DISABLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!getAuthenticator(request).isCurrentPassword(user, password)) {
|
if (!getAuthenticator(request).isCurrentPassword(user, password)) {
|
||||||
bean.setMessage(Message.INCORRECT_PASSWORD);
|
bean.setMessage(Message.INCORRECT_PASSWORD);
|
||||||
return;
|
return;
|
||||||
|
@ -336,7 +342,13 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
if (user.isPasswordChangeRequired()) {
|
if (user.isPasswordChangeRequired()) {
|
||||||
transitionToForcedPasswordChange(request);
|
transitionToForcedPasswordChange(request);
|
||||||
} else {
|
} else {
|
||||||
transitionToLoggedIn(request, user);
|
try {
|
||||||
|
transitionToLoggedIn(request, user);
|
||||||
|
} catch (LoginNotPermitted e) {
|
||||||
|
// This should have been caught by isUserPermittedToLogin()
|
||||||
|
bean.setMessage(Message.LOGIN_DISABLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +404,13 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New password is acceptable. Store it and go on.
|
// New password is acceptable. Store it and go on.
|
||||||
transitionToLoggedIn(request, user, newPassword);
|
try {
|
||||||
|
transitionToLoggedIn(request, user, newPassword);
|
||||||
|
} catch (LoginNotPermitted e) {
|
||||||
|
// This should have been caught by isUserPermittedToLogin()
|
||||||
|
bean.setMessage(Message.LOGIN_DISABLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -424,7 +442,7 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
* State change: all requirements are satisfied. Log them in.
|
* State change: all requirements are satisfied. Log them in.
|
||||||
*/
|
*/
|
||||||
private void transitionToLoggedIn(HttpServletRequest request,
|
private void transitionToLoggedIn(HttpServletRequest request,
|
||||||
UserAccount user) {
|
UserAccount user) throws LoginNotPermitted {
|
||||||
log.debug("Completed login: " + user.getEmailAddress());
|
log.debug("Completed login: " + user.getEmailAddress());
|
||||||
getAuthenticator(request).recordLoginAgainstUserAccount(user,
|
getAuthenticator(request).recordLoginAgainstUserAccount(user,
|
||||||
AuthenticationSource.INTERNAL);
|
AuthenticationSource.INTERNAL);
|
||||||
|
@ -435,7 +453,7 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
* log them in.
|
* log them in.
|
||||||
*/
|
*/
|
||||||
private void transitionToLoggedIn(HttpServletRequest request,
|
private void transitionToLoggedIn(HttpServletRequest request,
|
||||||
UserAccount user, String newPassword) {
|
UserAccount user, String newPassword) throws LoginNotPermitted {
|
||||||
log.debug("Completed login: " + user.getEmailAddress()
|
log.debug("Completed login: " + user.getEmailAddress()
|
||||||
+ ", password changed.");
|
+ ", password changed.");
|
||||||
getAuthenticator(request).recordNewPassword(user, newPassword);
|
getAuthenticator(request).recordNewPassword(user, newPassword);
|
||||||
|
@ -477,9 +495,10 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
response.sendRedirect(loginProcessPage);
|
response.sendRedirect(loginProcessPage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exit: user has completed the login. Redirect appropriately and clear the bean.
|
* Exit: user has completed the login. Redirect appropriately and clear the
|
||||||
|
* bean.
|
||||||
*/
|
*/
|
||||||
private void showLoginComplete(HttpServletResponse response,
|
private void showLoginComplete(HttpServletResponse response,
|
||||||
VitroRequest vreq) throws IOException {
|
VitroRequest vreq) throws IOException {
|
||||||
|
@ -497,12 +516,11 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoginRedirector getLoginRedirector(VitroRequest vreq) {
|
private LoginRedirector getLoginRedirector(VitroRequest vreq) {
|
||||||
String afterLoginUrl = LoginProcessBean.getBean(vreq).getAfterLoginUrl();
|
String afterLoginUrl = LoginProcessBean.getBean(vreq)
|
||||||
|
.getAfterLoginUrl();
|
||||||
return new LoginRedirector(vreq, afterLoginUrl);
|
return new LoginRedirector(vreq, afterLoginUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Get a reference to the Authenticator. */
|
/** Get a reference to the Authenticator. */
|
||||||
private Authenticator getAuthenticator(HttpServletRequest request) {
|
private Authenticator getAuthenticator(HttpServletRequest request) {
|
||||||
return Authenticator.getInstance(request);
|
return Authenticator.getInstance(request);
|
||||||
|
|
|
@ -125,6 +125,10 @@ public class LoginProcessBean {
|
||||||
public static final Message UNKNOWN_USERNAME = new Message(
|
public static final Message UNKNOWN_USERNAME = new Message(
|
||||||
"The email or password you entered is incorrect.", MLevel.ERROR);
|
"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(
|
public static final Message INCORRECT_PASSWORD = new Message(
|
||||||
"The email or password you entered is incorrect.", MLevel.ERROR);
|
"The email or password you entered is incorrect.", MLevel.ERROR);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
public class AuthenticatorStub extends Authenticator {
|
public class AuthenticatorStub extends Authenticator {
|
||||||
public static final String FACTORY_ATTRIBUTE_NAME = AuthenticatorFactory.class
|
public static final String FACTORY_ATTRIBUTE_NAME = AuthenticatorFactory.class
|
||||||
.getName();
|
.getName();
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// factory - store this in the context.
|
// factory - store this in the context.
|
||||||
//
|
//
|
||||||
|
@ -97,6 +97,11 @@ public class AuthenticatorStub extends Authenticator {
|
||||||
return usersByExternalAuthId.get(externalAuthId);
|
return usersByExternalAuthId.get(externalAuthId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUserPermittedToLogin(UserAccount userAccount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCurrentPassword(UserAccount userAccount,
|
public boolean isCurrentPassword(UserAccount userAccount,
|
||||||
String clearTextPassword) {
|
String clearTextPassword) {
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
<#assign errorMessage = "No password supplied." />
|
<#assign errorMessage = "No password supplied." />
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
<#if errorLoginDisabled??>
|
||||||
|
<#assign errorMessage = "User logins are temporarily disabled while the system is being maintained." />
|
||||||
|
</#if>
|
||||||
|
|
||||||
<#if errorLoginFailed??>
|
<#if errorLoginFailed??>
|
||||||
<#assign errorMessage = "Email or Password was incorrect." />
|
<#assign errorMessage = "Email or Password was incorrect." />
|
||||||
</#if>
|
</#if>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue