Convert the Authentication mechanism from User to UserAccount.

This commit is contained in:
j2blake 2011-06-07 15:00:41 +00:00
parent ee577adff7
commit 72314d3598
24 changed files with 517 additions and 379 deletions

View file

@ -12,7 +12,7 @@ import javax.servlet.http.HttpServletRequest;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.webapp.beans.User;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
/**
* A simple stub for unit tests that require an Authenticator. Call setup() to
@ -67,7 +67,9 @@ public class AuthenticatorStub extends Authenticator {
// Stub infrastructure
// ----------------------------------------------------------------------
private final Map<String, User> usersByName = new HashMap<String, User>();
private final Map<String, UserAccount> usersByEmail = new HashMap<String, UserAccount>();
private final Map<String, UserAccount> usersByExternalAuthId = new HashMap<String, UserAccount>();
private final Map<String, List<String>> editingPermissions = new HashMap<String, List<String>>();
private final Map<String, String> associatedUris = new HashMap<String, String>();
private final List<String> recordedLogins = new ArrayList<String>();
@ -79,8 +81,13 @@ public class AuthenticatorStub extends Authenticator {
this.request = request;
}
public void addUser(User user) {
usersByName.put(user.getUsername(), user);
public void addUser(UserAccount user) {
usersByEmail.put(user.getEmailAddress(), user);
String externalAuthId = user.getExternalAuthId();
if (!externalAuthId.isEmpty()) {
usersByExternalAuthId.put(user.getExternalAuthId(), user);
}
}
public void addEditingPermission(String username, String personUri) {
@ -107,52 +114,55 @@ public class AuthenticatorStub extends Authenticator {
// ----------------------------------------------------------------------
@Override
public boolean isExistingUser(String username) {
return usersByName.containsKey(username);
public UserAccount getAccountForInternalAuth(String emailAddress) {
return usersByEmail.get(emailAddress);
}
@Override
public User getUserByUsername(String username) {
return usersByName.get(username);
public UserAccount getAccountForExternalAuth(String externalAuthId) {
return usersByExternalAuthId.get(externalAuthId);
}
@Override
public List<String> getAssociatedIndividualUris(String username) {
public boolean isCurrentPassword(UserAccount userAccount,
String clearTextPassword) {
if (userAccount == null) {
return false;
} else {
return userAccount.getMd5Password().equals(
Authenticator.applyMd5Encoding(clearTextPassword));
}
}
@Override
public List<String> getAssociatedIndividualUris(UserAccount userAccount) {
List<String> uris = new ArrayList<String>();
if (associatedUris.containsKey(username)) {
uris.add(associatedUris.get(username));
String emailAddress = userAccount.getEmailAddress();
if (associatedUris.containsKey(emailAddress)) {
uris.add(associatedUris.get(emailAddress));
}
if (editingPermissions.containsKey(username)) {
uris.addAll(editingPermissions.get(username));
if (editingPermissions.containsKey(emailAddress)) {
uris.addAll(editingPermissions.get(emailAddress));
}
return uris;
}
@Override
public boolean isCurrentPassword(String username, String clearTextPassword) {
if (!isExistingUser(username)) {
return false;
}
String md5Password = applyMd5Encoding(clearTextPassword);
User user = getUserByUsername(username);
return md5Password.equals(user.getMd5password());
public void recordNewPassword(UserAccount userAccount,
String newClearTextPassword) {
newPasswords.put(userAccount.getEmailAddress(), newClearTextPassword);
}
@Override
public void recordNewPassword(String username, String newClearTextPassword) {
newPasswords.put(username, newClearTextPassword);
}
@Override
public void recordLoginAgainstUserAccount(String username,
public void recordLoginAgainstUserAccount(UserAccount userAccount,
AuthenticationSource authSource) {
recordedLogins.add(username);
recordedLogins.add(userAccount.getEmailAddress());
User user = getUserByUsername(username);
LoginStatusBean lsb = new LoginStatusBean(user.getURI(), authSource);
LoginStatusBean lsb = new LoginStatusBean(userAccount.getUri(),
authSource);
LoginStatusBean.setBean(request.getSession(), lsb);
}
@ -167,16 +177,15 @@ public class AuthenticatorStub extends Authenticator {
}
@Override
public void recordLoginWithoutUserAccount(String username,
String individualUri, AuthenticationSource authSource) {
public boolean accountRequiresEditing(UserAccount userAccount) {
throw new RuntimeException(
"AuthenticatorStub.accountRequiresEditing() not implemented.");
}
@Override
public void recordLoginWithoutUserAccount(String individualUri) {
throw new RuntimeException(
"AuthenticatorStub.recordLoginWithoutUserAccount() not implemented.");
}
@Override
public boolean isPasswordChangeRequired(String username) {
throw new RuntimeException(
"AuthenticatorStub.isPasswordChangeRequired() not implemented.");
}
}

View file

@ -2,15 +2,15 @@
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.ProgramLoginCore.PARAM_EMAIL_ADDRESS;
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.ProgramLoginCore.PARAM_NEW_PASSWORD;
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.ProgramLoginCore.PARAM_PASSWORD;
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.ProgramLoginCore.PARAM_USERNAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.Collections;
import javax.servlet.ServletException;
@ -27,7 +27,8 @@ import stubs.javax.servlet.http.HttpServletResponseStub;
import stubs.javax.servlet.http.HttpSessionStub;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.beans.User;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
/**
* Test the basic features of ProgramTest.
@ -38,13 +39,13 @@ public class ProgramLoginTest extends AbstractTestClass {
private static final String NEW_USER_URI = "new_user_uri";
private static final String NEW_USER_NAME = "new_user";
private static final String NEW_USER_PASSWORD = "new_user_pw";
private static final User NEW_USER = createUser(NEW_USER_URI,
private static final UserAccount NEW_USER = createUserAccount(NEW_USER_URI,
NEW_USER_NAME, NEW_USER_PASSWORD, 0);
private static final String OLD_USER_URI = "old_user_uri";
private static final String OLD_USER_NAME = "old_user";
private static final String OLD_USER_PASSWORD = "old_user_pw";
private static final User OLD_USER = createUser(OLD_USER_URI,
private static final UserAccount OLD_USER = createUserAccount(OLD_USER_URI,
OLD_USER_NAME, OLD_USER_PASSWORD, 10);
private AuthenticatorStub authenticator;
@ -57,7 +58,8 @@ public class ProgramLoginTest extends AbstractTestClass {
@Before
public void setLogging() {
// setLoggerLevel(this.getClass(), Level.DEBUG);
// setLoggerLevel(this.getClass(), Level.DEBUG);
// setLoggerLevel(ProgramLogin.class, Level.DEBUG);
}
@Before
@ -85,17 +87,16 @@ public class ProgramLoginTest extends AbstractTestClass {
response = new HttpServletResponseStub();
}
private static User createUser(String uri, String name, String password,
int loginCount) {
User user = new User();
user.setUsername(name);
user.setURI(uri);
user.setRoleURI(String.valueOf(50));
user.setMd5password(Authenticator.applyMd5Encoding(password));
private static UserAccount createUserAccount(String uri, String name,
String password, int loginCount) {
UserAccount user = new UserAccount();
user.setEmailAddress(name);
user.setUri(uri);
user.setPermissionSetUris(Collections
.singleton(PermissionSetsLoader.URI_DBA));
user.setMd5Password(Authenticator.applyMd5Encoding(password));
user.setLoginCount(loginCount);
if (loginCount > 0) {
user.setFirstTime(new Date(0));
}
user.setPasswordChangeRequired(loginCount == 0);
return user;
}
@ -170,10 +171,10 @@ public class ProgramLoginTest extends AbstractTestClass {
// Helper methods
// ----------------------------------------------------------------------
private void executeRequest(String username, String password,
private void executeRequest(String email, String password,
String newPassword) {
if (username != null) {
request.addParameter(PARAM_USERNAME, username);
if (email != null) {
request.addParameter(PARAM_EMAIL_ADDRESS, email);
}
if (password != null) {
request.addParameter(PARAM_PASSWORD, password);

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.controller.edit;
import static edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader.URI_DBA;
import static edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader.URI_SELF_EDITOR;
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.LOGGING_IN;
import static org.junit.Assert.assertEquals;
@ -10,7 +12,7 @@ import static org.junit.Assert.fail;
import java.net.URL;
import java.util.Arrays;
import java.util.Date;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -20,7 +22,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserDaoStub;
import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub;
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
import stubs.javax.servlet.ServletConfigStub;
import stubs.javax.servlet.ServletContextStub;
@ -30,7 +32,7 @@ import stubs.javax.servlet.http.HttpSessionStub;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.beans.User;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.AuthenticatorStub;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
@ -43,7 +45,7 @@ public class AuthenticateTest extends AbstractTestClass {
private AuthenticatorStub authenticator;
private ServletContextStub servletContext;
private WebappDaoFactoryStub webappDaoFactory;
private UserDaoStub userDao;
private UserAccountsDaoStub userAccountsDao;
private ServletConfigStub servletConfig;
private HttpSessionStub session;
private HttpServletRequestStub request;
@ -59,27 +61,27 @@ public class AuthenticateTest extends AbstractTestClass {
private static final String NEW_DBA_NAME = "new_dba_name";
private static final String NEW_DBA_PW = "new_dba_pw";
private static final UserInfo NEW_DBA = new UserInfo(NEW_DBA_NAME,
"new_dba_uri", NEW_DBA_PW, 50, 0);
"new_dba_uri", NEW_DBA_PW, URI_DBA, 0);
/** A DBA who has logged in before. */
private static final String OLD_DBA_NAME = "old_dba_name";
private static final String OLD_DBA_PW = "old_dba_pw";
private static final String OLD_DBA_URI = "old_dba_uri";
private static final int OLD_DBA_SECURITY_LEVEL = 50;
private static final UserInfo OLD_DBA = new UserInfo(OLD_DBA_NAME,
OLD_DBA_URI, OLD_DBA_PW, OLD_DBA_SECURITY_LEVEL, 5);
OLD_DBA_URI, OLD_DBA_PW, URI_DBA, 5);
/** A self-editor who has logged in before and has a profile. */
private static final String OLD_SELF_NAME = "old_self_name";
private static final String OLD_SELF_PW = "old_self_pw";
private static final UserInfo OLD_SELF = new UserInfo(OLD_SELF_NAME,
"old_self_uri", OLD_SELF_PW, 1, 100);
"old_self_uri", OLD_SELF_PW, URI_SELF_EDITOR, 100);
/** A self-editor who has logged in before but has no profile. */
private static final String OLD_STRANGER_NAME = "old_stranger_name";
private static final String OLD_STRANGER_PW = "stranger_pw";
private static final UserInfo OLD_STRANGER = new UserInfo(
OLD_STRANGER_NAME, "old_stranger_uri", OLD_STRANGER_PW, 1, 20);
OLD_STRANGER_NAME, "old_stranger_uri", OLD_STRANGER_PW,
URI_SELF_EDITOR, 20);
/** the login page */
private static final String URL_LOGIN = "/vivo/login";
@ -114,14 +116,14 @@ public class AuthenticateTest extends AbstractTestClass {
authenticator.setAssociatedUri(OLD_SELF.username,
"old_self_associated_uri");
userDao = new UserDaoStub();
userDao.addUser(createUserFromUserInfo(NEW_DBA));
userDao.addUser(createUserFromUserInfo(OLD_DBA));
userDao.addUser(createUserFromUserInfo(OLD_SELF));
userDao.addUser(createUserFromUserInfo(OLD_STRANGER));
userAccountsDao = new UserAccountsDaoStub();
userAccountsDao.addUser(createUserFromUserInfo(NEW_DBA));
userAccountsDao.addUser(createUserFromUserInfo(OLD_DBA));
userAccountsDao.addUser(createUserFromUserInfo(OLD_SELF));
userAccountsDao.addUser(createUserFromUserInfo(OLD_STRANGER));
webappDaoFactory = new WebappDaoFactoryStub();
webappDaoFactory.setUserDao(userDao);
webappDaoFactory.setUserAccountsDao(userAccountsDao);
servletContext = new ServletContextStub();
servletContext.setAttribute("webappDaoFactory", webappDaoFactory);
@ -143,16 +145,14 @@ public class AuthenticateTest extends AbstractTestClass {
auth.init(servletConfig);
}
private User createUserFromUserInfo(UserInfo userInfo) {
User user = new User();
user.setUsername(userInfo.username);
user.setURI(userInfo.uri);
user.setRoleURI(String.valueOf(userInfo.securityLevel));
user.setMd5password(Authenticator.applyMd5Encoding(userInfo.password));
private UserAccount createUserFromUserInfo(UserInfo userInfo) {
UserAccount user = new UserAccount();
user.setEmailAddress(userInfo.username);
user.setUri(userInfo.uri);
user.setPermissionSetUris(userInfo.permissionSetUris);
user.setMd5Password(Authenticator.applyMd5Encoding(userInfo.password));
user.setLoginCount(userInfo.loginCount);
if (userInfo.loginCount > 0) {
user.setFirstTime(new Date(0));
}
user.setPasswordChangeRequired(userInfo.loginCount == 0);
return user;
}
@ -617,23 +617,23 @@ public class AuthenticateTest extends AbstractTestClass {
final String username;
final String uri;
final String password;
final int securityLevel;
final Set<String> permissionSetUris;
final int loginCount;
public UserInfo(String username, String uri, String password,
int securityLevel, int loginCount) {
String roleUri, int loginCount) {
this.username = username;
this.uri = uri;
this.password = password;
this.securityLevel = securityLevel;
this.permissionSetUris = Collections.singleton(roleUri);
this.loginCount = loginCount;
}
@Override
public String toString() {
return "UserInfo[username=" + username + ", uri=" + uri
+ ", password=" + password + ", securityLevel="
+ securityLevel + ", loginCount=" + loginCount + "]";
+ ", password=" + password + ", roleUri="
+ permissionSetUris + ", loginCount=" + loginCount + "]";
}
}

View file

@ -0,0 +1,87 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package stubs.edu.cornell.mannlib.vitro.webapp.dao;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
/**
* TODO
*/
public class UserAccountsDaoStub implements UserAccountsDao {
private static final Log log = LogFactory.getLog(UserAccountsDaoStub.class);
private final Map<String, UserAccount> userAccountsByUri = new HashMap<String, UserAccount>();
// ----------------------------------------------------------------------
// Stub infrastructure
// ----------------------------------------------------------------------
public void addUser(UserAccount user) {
userAccountsByUri.put(user.getUri(), user);
}
// ----------------------------------------------------------------------
// Stub methods
// ----------------------------------------------------------------------
@Override
public UserAccount getUserAccountByUri(String uri) {
return userAccountsByUri.get(uri);
}
// ----------------------------------------------------------------------
// Un-implemented methods
// ----------------------------------------------------------------------
@Override
public UserAccount getUserAccountByEmail(String emailAddress) {
throw new RuntimeException(
"UserAccountsDaoStub.getUserAccountByEmail() not implemented.");
}
@Override
public String insertUserAccount(UserAccount userAccount) {
throw new RuntimeException(
"UserAccountsDaoStub.insertUserAccount() not implemented.");
}
@Override
public void updateUserAccount(UserAccount userAccount) {
throw new RuntimeException(
"UserAccountsDaoStub.updateUserAccount() not implemented.");
}
@Override
public void deleteUserAccount(String userAccountUri) {
throw new RuntimeException(
"UserAccountsDaoStub.deleteUserAccount() not implemented.");
}
@Override
public PermissionSet getPermissionSetByUri(String uri) {
throw new RuntimeException(
"UserAccountsDaoStub.getPermissionSetByUri() not implemented.");
}
@Override
public Collection<PermissionSet> getAllPermissionSets() {
throw new RuntimeException(
"UserAccountsDaoStub.getAllPermissionSets() not implemented.");
}
@Override
public UserAccount getUserAccountByExternalAuthId(String externalAuthId) {
throw new RuntimeException(
"UserAccountsDao.getUserAccountByExternalAuthId() not implemented.");
}
}

View file

@ -45,6 +45,7 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
private IndividualDao individualDao;
private DataPropertyDao dataPropertyDao;
private ObjectPropertyDao objectPropertyDao;
private UserAccountsDao userAccountsDao;
public void setIndividualDao(IndividualDao individualDao) {
this.individualDao = individualDao;
@ -58,10 +59,8 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
this.objectPropertyDao = objectPropertyDao;
}
// TODO This goes away when the UserAccounts stuff is fully implemented -- jb
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
public void setUserAccountsDao(UserAccountsDao userAccountsDao) {
this.userAccountsDao = userAccountsDao;
}
// ----------------------------------------------------------------------
@ -83,10 +82,9 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
return this.objectPropertyDao;
}
// TODO This goes away when the UserAccounts stuff is fully implemented -- jb
@Override
public UserDao getUserDao() {
return this.userDao;
public UserAccountsDao getUserAccountsDao() {
return this.userAccountsDao;
}
// ----------------------------------------------------------------------
@ -225,12 +223,6 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
"WebappDaoFactory.getLinktypeDao() not implemented.");
}
@Override
public UserAccountsDao getUserAccountsDao() {
throw new RuntimeException(
"WebappDaoFactory.getUserAccountsDao() not implemented.");
}
@Override
public VClassGroupDao getVClassGroupDao() {
throw new RuntimeException(
@ -272,4 +264,9 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
throw new RuntimeException("WebappDaoFactory.close() not implemented.");
}
@Override
public UserDao getUserDao() {
throw new RuntimeException("WebappDaoFactory.getUserDao() not implemented.");
}
}