NIHVIVO-1207 Factor out the model-related stuff from Authenticate into Authenticator.
This commit is contained in:
parent
d0c73a4d23
commit
db304c4f52
4 changed files with 369 additions and 140 deletions
|
@ -0,0 +1,84 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.User;
|
||||
|
||||
/**
|
||||
* The tool that a login process will use to interface with the user records in
|
||||
* the model (or wherever).
|
||||
*/
|
||||
public abstract class Authenticator {
|
||||
// ----------------------------------------------------------------------
|
||||
// The factory
|
||||
//
|
||||
// Unit tests can replace the factory to get a stub class instead.
|
||||
// Note: this can only work because the factory value is not final.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static interface AuthenticatorFactory {
|
||||
Authenticator newInstance(HttpServletRequest request);
|
||||
}
|
||||
|
||||
private static AuthenticatorFactory factory = new AuthenticatorFactory() {
|
||||
@Override
|
||||
public Authenticator newInstance(HttpServletRequest request) {
|
||||
return new BasicAuthenticator(request);
|
||||
}
|
||||
};
|
||||
|
||||
public static Authenticator getInstance(HttpServletRequest request) {
|
||||
return factory.newInstance(request);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The interface.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/** Maximum inactive interval for a ordinary logged-in session, in seconds. */
|
||||
public static final int LOGGED_IN_TIMEOUT_INTERVAL = 300;
|
||||
|
||||
/** Maximum inactive interval for a editor (or better) session, in seconds. */
|
||||
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 32000;
|
||||
|
||||
/**
|
||||
* Does a user by this name exist?
|
||||
*/
|
||||
public abstract boolean isExistingUser(String username);
|
||||
|
||||
/**
|
||||
* Does a user by this name have this password?
|
||||
*/
|
||||
public abstract boolean isCurrentPassword(String username,
|
||||
String clearTextPassword);
|
||||
|
||||
/**
|
||||
* Get the user with this name, or null if no such user exists.
|
||||
*/
|
||||
public abstract User getUserByUsername(String username);
|
||||
|
||||
/**
|
||||
* Return a list of URIs of the people that this user is allowed to edit.
|
||||
*/
|
||||
public abstract List<String> asWhomMayThisUserEdit(User user);
|
||||
|
||||
/**
|
||||
* Record a new password for the user.
|
||||
*/
|
||||
public abstract void recordNewPassword(User user,
|
||||
String newClearTextPassword);
|
||||
|
||||
/**
|
||||
* Record that the user has logged in.
|
||||
*/
|
||||
public abstract void recordSuccessfulLogin(User user);
|
||||
|
||||
/**
|
||||
* Set the login status in the session.
|
||||
*/
|
||||
public abstract void setLoggedIn(User user);
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginFormBean;
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.User;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.edit.Authenticate;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.UserDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginEvent;
|
||||
|
||||
/**
|
||||
* The "standard" implementation of Authenticator.
|
||||
*/
|
||||
public class BasicAuthenticator extends Authenticator {
|
||||
/** User roles are recorded in the model like "role:/50", etc. */
|
||||
private static final String ROLE_NAMESPACE = "role:/";
|
||||
|
||||
private static final Log log = LogFactory.getLog(BasicAuthenticator.class);
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
public BasicAuthenticator(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExistingUser(String username) {
|
||||
return getUserByUsername(username) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserByUsername(String username) {
|
||||
UserDao userDao = getUserDao(request);
|
||||
if (userDao == null) {
|
||||
return null;
|
||||
}
|
||||
return userDao.getUserByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentPassword(String username, String clearTextPassword) {
|
||||
User user = getUserDao(request).getUserByUsername(username);
|
||||
if (user == null) {
|
||||
log.trace("Checking password '" + clearTextPassword
|
||||
+ "' for user '" + username + "', but user doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String md5NewPassword = Authenticate
|
||||
.applyMd5Encoding(clearTextPassword);
|
||||
return md5NewPassword.equals(user.getMd5password());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordNewPassword(User user, String newClearTextPassword) {
|
||||
user.setOldPassword(user.getMd5password());
|
||||
user.setMd5password(Authenticate.applyMd5Encoding(newClearTextPassword));
|
||||
getUserDao(request).updateUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordSuccessfulLogin(User user) {
|
||||
user.setLoginCount(user.getLoginCount() + 1);
|
||||
if (user.getFirstTime() == null) { // first login
|
||||
user.setFirstTime(new Date());
|
||||
}
|
||||
getUserDao(request).updateUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoggedIn(User user) {
|
||||
HttpSession session = request.getSession();
|
||||
createLoginFormBean(user, session);
|
||||
createLoginStatusBean(user, session);
|
||||
setSessionTimeoutLimit(session);
|
||||
recordInUserSessionMap(user, session);
|
||||
notifyOtherUsers(user, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the login bean into the session.
|
||||
*
|
||||
* TODO The LoginFormBean is being phased out.
|
||||
*/
|
||||
private void createLoginFormBean(User user, HttpSession session) {
|
||||
LoginFormBean lfb = new LoginFormBean();
|
||||
lfb.setUserURI(user.getURI());
|
||||
lfb.setLoginStatus("authenticated");
|
||||
lfb.setSessionId(session.getId());
|
||||
lfb.setLoginRole(user.getRoleURI());
|
||||
lfb.setLoginRemoteAddr(request.getRemoteAddr());
|
||||
lfb.setLoginName(user.getUsername());
|
||||
session.setAttribute("loginHandler", lfb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the login bean into the session.
|
||||
*
|
||||
* TODO this should eventually replace the LoginFormBean.
|
||||
*/
|
||||
private void createLoginStatusBean(User user, HttpSession session) {
|
||||
LoginStatusBean lsb = new LoginStatusBean(user.getURI(),
|
||||
user.getUsername(), parseUserSecurityLevel(user));
|
||||
LoginStatusBean.setBean(session, lsb);
|
||||
log.info("Adding status bean: " + lsb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Editors and other privileged users get a longer timeout interval.
|
||||
*/
|
||||
private void setSessionTimeoutLimit(HttpSession session) {
|
||||
if (LoginStatusBean.getBean(session).isLoggedInAtLeast(
|
||||
LoginStatusBean.EDITOR)) {
|
||||
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
||||
} else {
|
||||
session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the login in the user/session map.
|
||||
*
|
||||
* TODO What is this map used for?
|
||||
*/
|
||||
private void recordInUserSessionMap(User user, HttpSession session) {
|
||||
Map<String, HttpSession> userURISessionMap = Authenticate
|
||||
.getUserURISessionMapFromContext(session.getServletContext());
|
||||
userURISessionMap.put(user.getURI(), session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Anyone listening to themodel might need to know that another user is
|
||||
* logged in.
|
||||
*/
|
||||
private void notifyOtherUsers(User user, HttpSession session) {
|
||||
Authenticate.sendLoginNotifyEvent(new LoginEvent(user.getURI()),
|
||||
session.getServletContext(), session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> asWhomMayThisUserEdit(User user) {
|
||||
if (user == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
UserDao userDao = getUserDao(request);
|
||||
if (userDao == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
String userUri = user.getURI();
|
||||
if (userUri == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return userDao.getIndividualsUserMayEditAs(userUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the {@link UserDao}, or <code>null</code>.
|
||||
*/
|
||||
private UserDao getUserDao(HttpServletRequest request) {
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ServletContext servletContext = session.getServletContext();
|
||||
WebappDaoFactory wadf = (WebappDaoFactory) servletContext
|
||||
.getAttribute("webappDaoFactory");
|
||||
if (wadf == null) {
|
||||
log.error("getUserDao: no WebappDaoFactory");
|
||||
return null;
|
||||
}
|
||||
|
||||
UserDao userDao = wadf.getUserDao();
|
||||
if (userDao == null) {
|
||||
log.error("getUserDao: no UserDao");
|
||||
}
|
||||
|
||||
return userDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the role URI from User. Don't crash if it is not valid.
|
||||
*/
|
||||
private int parseUserSecurityLevel(User user) {
|
||||
String roleURI = user.getRoleURI();
|
||||
try {
|
||||
if (roleURI.startsWith(ROLE_NAMESPACE)) {
|
||||
String roleLevel = roleURI.substring(ROLE_NAMESPACE.length());
|
||||
return Integer.parseInt(roleLevel);
|
||||
} else {
|
||||
return Integer.parseInt(roleURI);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Invalid RoleURI '" + roleURI + "' for user '"
|
||||
+ user.getURI() + "'");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.net.URLEncoder;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -24,31 +23,19 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginFormBean;
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy.AuthRole;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.User;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||
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.dao.UserDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginEvent;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginLogoutEvent;
|
||||
|
||||
public class Authenticate extends FreemarkerHttpServlet {
|
||||
/**
|
||||
* Maximum inactive interval for a ordinary logged in user session, in
|
||||
* seconds.
|
||||
*/
|
||||
public static final int LOGGED_IN_TIMEOUT_INTERVAL = 300;
|
||||
|
||||
/** Maximum inactive interval for a editor (or better) session, in seconds. */
|
||||
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 32000;
|
||||
|
||||
private static final Log log = LogFactory.getLog(Authenticate.class
|
||||
.getName());
|
||||
|
||||
|
@ -155,7 +142,7 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
bean.setUsername(username);
|
||||
}
|
||||
|
||||
User user = getUserDao(request).getUserByUsername(username);
|
||||
User user = getAuthenticator(request).getUserByUsername(username);
|
||||
log.trace("User is " + (user == null ? "null" : user.getURI()));
|
||||
|
||||
if (user == null) {
|
||||
|
@ -168,11 +155,7 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
return null;
|
||||
}
|
||||
|
||||
String md5Password = applyMd5Encoding(password);
|
||||
|
||||
if (!md5Password.equals(user.getMd5password())) {
|
||||
log.trace("Encoded passwords don't match: right="
|
||||
+ user.getMd5password() + ", wrong=" + md5Password);
|
||||
if (!getAuthenticator(request).isCurrentPassword(username, password)) {
|
||||
bean.setMessage(Message.INCORRECT_PASSWORD);
|
||||
return null;
|
||||
}
|
||||
|
@ -239,24 +222,15 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
return null;
|
||||
}
|
||||
|
||||
User user = getUserDao(request).getUserByUsername(bean.getUsername());
|
||||
log.trace("User is " + (user == null ? "null" : user.getURI()));
|
||||
|
||||
if (user == null) {
|
||||
throw new IllegalStateException(
|
||||
"Changing password but bean has no user: '"
|
||||
+ bean.getUsername() + "'");
|
||||
}
|
||||
|
||||
String md5NewPassword = applyMd5Encoding(newPassword);
|
||||
log.trace("Old password: " + user.getMd5password() + ", new password: "
|
||||
+ md5NewPassword);
|
||||
|
||||
if (md5NewPassword.equals(user.getMd5password())) {
|
||||
String username = bean.getUsername();
|
||||
|
||||
if (getAuthenticator(request).isCurrentPassword(username, newPassword)) {
|
||||
bean.setMessage(Message.USING_OLD_PASSWORD);
|
||||
return null;
|
||||
}
|
||||
|
||||
User user = getAuthenticator(request).getUserByUsername(username);
|
||||
log.trace("User is " + (user == null ? "null" : user.getURI()));
|
||||
return user;
|
||||
}
|
||||
|
||||
|
@ -266,10 +240,7 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
private void recordSuccessfulPasswordChange(HttpServletRequest request,
|
||||
User user) {
|
||||
String newPassword = request.getParameter(PARAMETER_NEW_PASSWORD);
|
||||
String md5NewPassword = applyMd5Encoding(newPassword);
|
||||
user.setOldPassword(user.getMd5password());
|
||||
user.setMd5password(md5NewPassword);
|
||||
getUserDao(request).updateUser(user);
|
||||
getAuthenticator(request).recordNewPassword(user, newPassword);
|
||||
log.debug("Completed first-time password change.");
|
||||
|
||||
recordLoginInfo(request, user.getUsername());
|
||||
|
@ -282,52 +253,16 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
private void recordLoginInfo(HttpServletRequest request, String username) {
|
||||
log.debug("Completed login.");
|
||||
|
||||
// Get a fresh user object, so we know it's not stale.
|
||||
User user = getUserDao(request).getUserByUsername(username);
|
||||
// Record the login on the user record (start with a fresh copy).
|
||||
User user = getAuthenticator(request).getUserByUsername(username);
|
||||
getAuthenticator(request).recordSuccessfulLogin(user);
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
|
||||
// Put the login info into the session.
|
||||
// TODO the LoginFormBean is being phased out.
|
||||
LoginFormBean lfb = new LoginFormBean();
|
||||
lfb.setUserURI(user.getURI());
|
||||
lfb.setLoginStatus("authenticated");
|
||||
lfb.setSessionId(session.getId());
|
||||
lfb.setLoginRole(user.getRoleURI());
|
||||
lfb.setLoginRemoteAddr(request.getRemoteAddr());
|
||||
lfb.setLoginName(user.getUsername());
|
||||
session.setAttribute("loginHandler", lfb);
|
||||
// TODO this should eventually replace the LoginFormBean.
|
||||
LoginStatusBean lsb = new LoginStatusBean(user.getURI(),
|
||||
user.getUsername(), parseUserSecurityLevel(user));
|
||||
LoginStatusBean.setBean(session, lsb);
|
||||
log.info("Adding status bean: " + lsb);
|
||||
// Record that a new user has logged in to this session.
|
||||
getAuthenticator(request).setLoggedIn(user);
|
||||
|
||||
// Remove the login process info from the session.
|
||||
HttpSession session = request.getSession();
|
||||
session.removeAttribute(LoginProcessBean.SESSION_ATTRIBUTE);
|
||||
|
||||
// Record the login on the user.
|
||||
user.setLoginCount(user.getLoginCount() + 1);
|
||||
if (user.getFirstTime() == null) { // first login
|
||||
user.setFirstTime(new Date());
|
||||
}
|
||||
getUserDao(request).updateUser(user);
|
||||
|
||||
// Set the timeout limit on the session - editors, etc, get more.
|
||||
if (lsb.isLoggedInAtLeast(LoginStatusBean.EDITOR)) {
|
||||
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
||||
} else {
|
||||
session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL);
|
||||
}
|
||||
|
||||
// Record the user in the user/Session map.
|
||||
Map<String, HttpSession> userURISessionMap = getUserURISessionMapFromContext(getServletContext());
|
||||
userURISessionMap.put(user.getURI(), request.getSession());
|
||||
|
||||
// Notify the other users of this model.
|
||||
sendLoginNotifyEvent(new LoginEvent(user.getURI()),
|
||||
getServletContext(), session);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -395,23 +330,17 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
|
||||
// If the user is a self-editor, send them to their home page.
|
||||
User user = getLoggedInUser(request);
|
||||
if (user != null
|
||||
&& user.getRoleURI() != null
|
||||
&& user.getRoleURI().equals(
|
||||
Integer.toString(AuthRole.USER.level()))) {
|
||||
UserDao userDao = getUserDao(request);
|
||||
if (userDao != null) {
|
||||
List<String> uris = userDao.getIndividualsUserMayEditAs(user
|
||||
.getURI());
|
||||
if (uris != null && uris.size() > 0) {
|
||||
String userHomePage = request.getContextPath()
|
||||
+ "/individual?uri="
|
||||
+ URLEncoder.encode(uris.get(0), "UTF-8");
|
||||
log.debug("User is logged in. Redirect as self-editor to "
|
||||
+ userHomePage);
|
||||
response.sendRedirect(userHomePage);
|
||||
return;
|
||||
}
|
||||
if (userIsANonEditor(user)) {
|
||||
List<String> uris = getAuthenticator(request).asWhomMayThisUserEdit(
|
||||
user);
|
||||
if (uris != null && uris.size() > 0) {
|
||||
String userHomePage = request.getContextPath()
|
||||
+ "/individual?uri="
|
||||
+ URLEncoder.encode(uris.get(0), "UTF-8");
|
||||
log.debug("User is logged in. Redirect as self-editor to "
|
||||
+ userHomePage);
|
||||
response.sendRedirect(userHomePage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,6 +349,15 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
response.sendRedirect(getSiteAdminUrl(request));
|
||||
}
|
||||
|
||||
/** Is the logged in user an AuthRole.USER? */
|
||||
private boolean userIsANonEditor(User user) {
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
String nonEditorRoleUri = Integer.toString(AuthRole.USER.level());
|
||||
return nonEditorRoleUri.equals(user.getRoleURI());
|
||||
}
|
||||
|
||||
/**
|
||||
* There has been an unexpected exception. Complain mightily.
|
||||
*/
|
||||
|
@ -452,43 +390,18 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
* What user are we logged in as?
|
||||
*/
|
||||
private User getLoggedInUser(HttpServletRequest request) {
|
||||
UserDao userDao = getUserDao(request);
|
||||
if (userDao == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LoginStatusBean lsb = LoginStatusBean.getBean(request);
|
||||
if (!lsb.isLoggedIn()) {
|
||||
log.debug("getLoggedInUser: not logged in");
|
||||
return null;
|
||||
}
|
||||
|
||||
return userDao.getUserByUsername(lsb.getUsername());
|
||||
return getAuthenticator(request).getUserByUsername(lsb.getUsername());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the {@link UserDao}, or <code>null</code>.
|
||||
*/
|
||||
private UserDao getUserDao(HttpServletRequest request) {
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ServletContext servletContext = session.getServletContext();
|
||||
WebappDaoFactory wadf = (WebappDaoFactory) servletContext
|
||||
.getAttribute("webappDaoFactory");
|
||||
if (wadf == null) {
|
||||
log.error("getUserDao: no WebappDaoFactory");
|
||||
return null;
|
||||
}
|
||||
|
||||
UserDao userDao = wadf.getUserDao();
|
||||
if (userDao == null) {
|
||||
log.error("getUserDao: no UserDao");
|
||||
}
|
||||
|
||||
return userDao;
|
||||
/** Get a reference to the Authenticator. */
|
||||
private Authenticator getAuthenticator(HttpServletRequest request) {
|
||||
return Authenticator.getInstance(request);
|
||||
}
|
||||
|
||||
/** What's the URL for the login screen? */
|
||||
|
@ -515,19 +428,6 @@ public class Authenticate extends FreemarkerHttpServlet {
|
|||
return LoginProcessBean.getBeanFromSession(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the role URI from User. Don't crash if it is not valid.
|
||||
*/
|
||||
private int parseUserSecurityLevel(User user) {
|
||||
try {
|
||||
return Integer.parseInt(user.getRoleURI());
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Invalid RoleURI '" + user.getRoleURI() + "' for user '"
|
||||
+ user.getURI() + "'");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Public utility methods.
|
||||
// ----------------------------------------------------------------------
|
||||
|
|
|
@ -11,6 +11,7 @@ import static org.junit.Assert.assertNull;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
|
@ -40,6 +41,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
private static final String USER_OLDHAND_NAME = "oldHandName";
|
||||
private static final String USER_OLDHAND_URI = "oldHandURI";
|
||||
private static final String USER_OLDHAND_PASSWORD = "oldHandPassword";
|
||||
private static final int USER_OLDHAND_LOGIN_COUNT = 100;
|
||||
|
||||
private static final String URL_LOGIN_PAGE = Controllers.LOGIN
|
||||
+ "?login=block";
|
||||
|
@ -73,6 +75,8 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
dbaUser.setURI(USER_DBA_URI);
|
||||
dbaUser.setRoleURI("50");
|
||||
dbaUser.setMd5password(Authenticate.applyMd5Encoding(USER_DBA_PASSWORD));
|
||||
dbaUser.setFirstTime(null);
|
||||
dbaUser.setLoginCount(0);
|
||||
|
||||
User ohUser = new User();
|
||||
ohUser.setUsername(USER_OLDHAND_NAME);
|
||||
|
@ -80,7 +84,8 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
ohUser.setRoleURI("1");
|
||||
ohUser.setMd5password(Authenticate
|
||||
.applyMd5Encoding(USER_OLDHAND_PASSWORD));
|
||||
ohUser.setLoginCount(100);
|
||||
ohUser.setLoginCount(USER_OLDHAND_LOGIN_COUNT);
|
||||
ohUser.setFirstTime(new Date(0));
|
||||
|
||||
userDao = new UserDaoStub();
|
||||
userDao.addUser(dbaUser);
|
||||
|
@ -118,6 +123,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertExpectedRedirect(URL_LOGIN_PAGE);
|
||||
assertNoProcessBean();
|
||||
assertExpectedStatusBean(LOGIN_STATUS_DBA);
|
||||
assertExpectedUserValues(USER_DBA_NAME, USER_DBA_PASSWORD, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -198,6 +204,8 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertExpectedRedirect(URL_LOGIN_PAGE);
|
||||
assertExpectedStatusBean(LOGIN_STATUS_OLDHAND);
|
||||
assertNoProcessBean();
|
||||
assertExpectedUserValues(USER_OLDHAND_NAME, USER_OLDHAND_PASSWORD,
|
||||
USER_OLDHAND_LOGIN_COUNT + 1, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -214,6 +222,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertExpectedRedirect(URL_LOGIN_PAGE);
|
||||
assertNoStatusBean();
|
||||
assertExpectedProcessBean(FORCED_PASSWORD_CHANGE, USER_DBA_NAME, "", "");
|
||||
assertExpectedUserValues(USER_DBA_NAME, USER_DBA_PASSWORD, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -226,6 +235,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertExpectedRedirect(URL_HOME_PAGE);
|
||||
assertNoStatusBean();
|
||||
assertNoProcessBean();
|
||||
assertExpectedUserValues(USER_DBA_NAME, USER_DBA_PASSWORD, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -239,6 +249,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertNoStatusBean();
|
||||
assertExpectedProcessBean(FORCED_PASSWORD_CHANGE, USER_DBA_NAME, "",
|
||||
"Please enter a password between 6 and 12 characters in length.");
|
||||
assertExpectedUserValues(USER_DBA_NAME, USER_DBA_PASSWORD, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -252,6 +263,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertNoStatusBean();
|
||||
assertExpectedProcessBean(FORCED_PASSWORD_CHANGE, USER_DBA_NAME, "",
|
||||
"The passwords entered do not match.");
|
||||
assertExpectedUserValues(USER_DBA_NAME, USER_DBA_PASSWORD, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -266,6 +278,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertExpectedProcessBean(FORCED_PASSWORD_CHANGE, USER_DBA_NAME, "",
|
||||
"Please choose a different password from the "
|
||||
+ "temporary one provided initially.");
|
||||
assertExpectedUserValues(USER_DBA_NAME, USER_DBA_PASSWORD, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -278,6 +291,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
assertExpectedRedirect(URL_LOGIN_PAGE);
|
||||
assertExpectedStatusBean(LOGIN_STATUS_DBA);
|
||||
assertNoProcessBean();
|
||||
assertExpectedUserValues(USER_DBA_NAME, "NewPassword", 1, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -388,6 +402,18 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
bean.getSecurityLevel());
|
||||
}
|
||||
|
||||
/** Check that this user looks like we expected. */
|
||||
private void assertExpectedUserValues(String username, String password,
|
||||
int loginCount, boolean firstTimeIsSet) {
|
||||
User user = userDao.getUserByUsername(username);
|
||||
assertEquals("user " + username + " password",
|
||||
Authenticate.applyMd5Encoding(password), user.getMd5password());
|
||||
assertEquals("user " + username + " login count", loginCount,
|
||||
user.getLoginCount());
|
||||
assertEquals("user " + username + " firstTimeIsSet", firstTimeIsSet,
|
||||
user.getFirstTime() != null);
|
||||
}
|
||||
|
||||
/** Boilerplate login process for the rediret tests. */
|
||||
private void loginNotFirstTime() {
|
||||
setProcessBean(LOGGING_IN);
|
||||
|
@ -397,6 +423,8 @@ public class AuthenticateTest extends AbstractTestClass {
|
|||
|
||||
assertExpectedStatusBean(LOGIN_STATUS_OLDHAND);
|
||||
assertNoProcessBean();
|
||||
assertExpectedUserValues(USER_OLDHAND_NAME, USER_OLDHAND_PASSWORD,
|
||||
USER_OLDHAND_LOGIN_COUNT + 1, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
Loading…
Add table
Reference in a new issue