git-svn-id: https://samskivert.googlecode.com/svn/trunk@2125 6335cc39-0255-0410-8fd6-9bcaacd3b74c

This commit is contained in:
mdb
2007-07-10 21:59:32 +00:00
parent 03040c0258
commit 85024c595b
11 changed files with 159 additions and 142 deletions
@@ -27,6 +27,6 @@ public class AuthenticationFailedException extends Exception
{
public AuthenticationFailedException (String message)
{
super(message);
super(message);
}
}
@@ -27,6 +27,6 @@ public class InvalidPasswordException extends AuthenticationFailedException
{
public InvalidPasswordException (String message)
{
super(message);
super(message);
}
}
@@ -27,6 +27,6 @@ public class InvalidUsernameException extends Exception
{
public InvalidUsernameException (String message)
{
super(message);
super(message);
}
}
@@ -27,6 +27,6 @@ public class NoSuchUserException extends AuthenticationFailedException
{
public NoSuchUserException (String message)
{
super(message);
super(message);
}
}
@@ -1,5 +1,22 @@
//
// $Id: Password.java,v 1.1 2004/01/31 06:24:01 mdb Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.samskivert.servlet.user;
@@ -65,7 +65,7 @@ public class User
*/
public void setRealName (String realname)
{
this.realname = realname;
this.realname = realname;
_dirty.setModified("realname");
}
@@ -86,7 +86,7 @@ public class User
*/
public void setPassword (Password password)
{
this.password = password.getEncrypted();
this.password = password.getEncrypted();
_dirty.setModified("password");
}
@@ -95,7 +95,7 @@ public class User
*/
public void setEmail (String email)
{
this.email = email;
this.email = email;
_dirty.setModified("email");
}
@@ -30,6 +30,6 @@ public class UserExistsException extends PersistenceException
{
public UserExistsException (String message)
{
super(message);
super(message);
}
}
@@ -100,20 +100,20 @@ public class UserManager
* the user database.
*/
public void init (Properties config, ConnectionProvider conprov)
throws PersistenceException
throws PersistenceException
{
// save this for later
_config = config;
// create the user repository
_repository = createRepository(conprov);
// create the user repository
_repository = createRepository(conprov);
// fetch the login URL from the properties
_loginURL = config.getProperty("login_url");
if (_loginURL == null) {
Log.warning("No login_url supplied in user manager config. Authentication won't work.");
// fetch the login URL from the properties
_loginURL = config.getProperty("login_url");
if (_loginURL == null) {
Log.warning("No login_url supplied in user manager config. Authentication won't work.");
_loginURL = "/missing_login_url";
}
}
// look up any override to our user auth cookie
String authCook = config.getProperty("auth_cookie.name");
@@ -126,24 +126,24 @@ public class UserManager
", login=" + _loginURL + "].");
}
// register a cron job to prune the session table every hour
_pruner = new Interval() {
public void expired ()
{
try {
_repository.pruneSessions();
} catch (PersistenceException pe) {
Log.warning("Error pruning session table.");
// register a cron job to prune the session table every hour
_pruner = new Interval() {
public void expired ()
{
try {
_repository.pruneSessions();
} catch (PersistenceException pe) {
Log.warning("Error pruning session table.");
Log.logStackTrace(pe);
}
}
};
}
}
};
_pruner.schedule(SESSION_PRUNE_INTERVAL, true);
}
public void shutdown ()
{
// cancel our session table pruning thread
// cancel our session table pruning thread
_pruner.cancel();
}
@@ -152,7 +152,7 @@ public class UserManager
*/
public UserRepository getRepository ()
{
return _repository;
return _repository;
}
/**
@@ -163,20 +163,20 @@ public class UserManager
* request or if the authentication information is bogus.
*/
public User loadUser (HttpServletRequest req)
throws PersistenceException
throws PersistenceException
{
String authcook = CookieUtil.getCookieValue(req, _userAuthCookie);
if (USERMGR_DEBUG) {
Log.info("Loading user by cookie [" + _userAuthCookie + "=" + authcook + "].");
}
return loadUser(authcook);
return loadUser(authcook);
}
/**
* Loads up a user based on the supplied session authentication token.
*/
public User loadUser (String authcode)
throws PersistenceException
throws PersistenceException
{
User user = (authcode == null) ? null : _repository.loadUserBySession(authcode);
if (USERMGR_DEBUG) {
@@ -194,20 +194,20 @@ public class UserManager
* @return the user associated with the request.
*/
public User requireUser (HttpServletRequest req)
throws PersistenceException, RedirectException
throws PersistenceException, RedirectException
{
User user = loadUser(req);
// if no user was loaded, we need to redirect these fine people to the login page
if (user == null) {
// first construct the redirect URL
User user = loadUser(req);
// if no user was loaded, we need to redirect these fine people to the login page
if (user == null) {
// first construct the redirect URL
String eurl = RequestUtils.getLocationEncoded(req);
String target = StringUtil.replace(_loginURL, "%R", eurl);
String target = StringUtil.replace(_loginURL, "%R", eurl);
if (USERMGR_DEBUG) {
Log.info("No user found in require, redirecting [to=" + target + "].");
}
throw new RedirectException(target);
}
return user;
throw new RedirectException(target);
}
return user;
}
/**
@@ -230,13 +230,13 @@ public class UserManager
*/
public User login (String username, Password password, boolean persist,
HttpServletRequest req, HttpServletResponse rsp, Authenticator auth)
throws PersistenceException, AuthenticationFailedException
throws PersistenceException, AuthenticationFailedException
{
// load up the requested user
User user = _repository.loadUser(username);
if (user == null) {
throw new NoSuchUserException("error.no_such_user");
}
// load up the requested user
User user = _repository.loadUser(username);
if (user == null) {
throw new NoSuchUserException("error.no_such_user");
}
// potentially convert the user's legacy password
if (password != null && password.getCleartext() != null &&
@@ -251,7 +251,7 @@ public class UserManager
// give them the necessary cookies and business
effectLogin(user, persist ? PERSIST_EXPIRE_DAYS : NON_PERSIST_EXPIRE_DAYS, req, rsp);
return user;
return user;
}
/**
@@ -269,13 +269,13 @@ public class UserManager
*/
public Tuple<User,String> login (
String username, Password password, int expires, Authenticator auth)
throws PersistenceException, AuthenticationFailedException
throws PersistenceException, AuthenticationFailedException
{
// load up the requested user
User user = _repository.loadUser(username);
if (user == null) {
throw new NoSuchUserException("error.no_such_user");
}
// load up the requested user
User user = _repository.loadUser(username);
if (user == null) {
throw new NoSuchUserException("error.no_such_user");
}
// potentially convert the user's legacy password
if (password != null && password.getCleartext() != null &&
@@ -287,12 +287,12 @@ public class UserManager
// run the user through the authentication gamut
auth.authenticateUser(user, username, password);
// register a session for this user
String authcode = _repository.registerSession(user, expires);
// register a session for this user
String authcode = _repository.registerSession(user, expires);
if (USERMGR_DEBUG) {
Log.info("Session started [user=" + username + ", code=" + authcode + "].");
}
return new Tuple<User,String>(user, authcode);
return new Tuple<User,String>(user, authcode);
}
/**
@@ -306,18 +306,18 @@ public class UserManager
User user, int expires, HttpServletRequest req, HttpServletResponse rsp)
throws PersistenceException
{
String authcode = _repository.registerSession(user, Math.max(expires, 1));
Cookie acookie = new Cookie(_userAuthCookie, authcode);
String authcode = _repository.registerSession(user, Math.max(expires, 1));
Cookie acookie = new Cookie(_userAuthCookie, authcode);
// strip the hostname from the server and use that as the domain unless configured not to
if (!"false".equalsIgnoreCase(_config.getProperty("auth_cookie.strip_hostname"))) {
CookieUtil.widenDomain(req, acookie);
}
acookie.setPath("/");
acookie.setPath("/");
acookie.setMaxAge((expires > 0) ? (expires*24*60*60) : -1);
if (USERMGR_DEBUG) {
Log.info("Setting cookie " + acookie + ".");
}
rsp.addCookie(acookie);
rsp.addCookie(acookie);
}
/**
@@ -325,13 +325,13 @@ public class UserManager
*/
public void logout (HttpServletRequest req, HttpServletResponse rsp)
{
// nothing to do if they don't already have an auth cookie
String authcode = CookieUtil.getCookieValue(req, _userAuthCookie);
if (authcode == null) {
return;
}
// nothing to do if they don't already have an auth cookie
String authcode = CookieUtil.getCookieValue(req, _userAuthCookie);
if (authcode == null) {
return;
}
// set them up the bomb
// set them up the bomb
Cookie c = new Cookie(_userAuthCookie, "x");
c.setPath("/");
c.setMaxAge(0);
@@ -68,7 +68,7 @@ public class UserRepository extends JORARepository
public UserRepository (ConnectionProvider provider)
throws PersistenceException
{
super(provider, USER_REPOSITORY_IDENT);
super(provider, USER_REPOSITORY_IDENT);
}
/**
@@ -87,9 +87,9 @@ public class UserRepository extends JORARepository
*/
public int createUser (
Username username, Password password, String realname, String email, int siteId)
throws UserExistsException, PersistenceException
throws UserExistsException, PersistenceException
{
// create a new user object...
// create a new user object...
User user = new User();
user.setDirtyMask(_utable.getFieldMask());
@@ -105,7 +105,7 @@ public class UserRepository extends JORARepository
* @return the user with the specified user id or null if no user with that id exists.
*/
public User loadUser (String username)
throws PersistenceException
throws PersistenceException
{
return loadUserWhere("where username = " + JDBCUtil.escape(username));
}
@@ -116,7 +116,7 @@ public class UserRepository extends JORARepository
* @return the user with the specified user id or null if no user with that id exists.
*/
public User loadUser (int userId)
throws PersistenceException
throws PersistenceException
{
return loadUserWhere("where userId = " + userId);
}
@@ -128,7 +128,7 @@ public class UserRepository extends JORARepository
* supplied identifier.
*/
public User loadUserBySession (String sessionKey)
throws PersistenceException
throws PersistenceException
{
User user = load(_utable, "sessions", "where authcode = '" + sessionKey + "' " +
"AND sessions.userId = users.userId");
@@ -144,7 +144,7 @@ public class UserRepository extends JORARepository
* @return the users whom have a user id in the userIds array.
*/
public HashIntMap<User> loadUsersFromId (int[] userIds)
throws PersistenceException
throws PersistenceException
{
HashIntMap<User> data = new HashIntMap<User>();
if (userIds.length > 0) {
@@ -164,7 +164,7 @@ public class UserRepository extends JORARepository
* @return the user with the specified user id or null if no user with that id exists.
*/
public ArrayList<User> lookupUsersByEmail (String email)
throws PersistenceException
throws PersistenceException
{
return loadAll(_utable, "where email = " + JDBCUtil.escape(email));
}
@@ -177,7 +177,7 @@ public class UserRepository extends JORARepository
* @return the users matching the specified query or an empty list if there are no matches.
*/
public ArrayList<User> lookupUsersWhere (final String where)
throws PersistenceException
throws PersistenceException
{
ArrayList<User> users = loadAll(_utable, where);
for (User user : users) {
@@ -196,7 +196,7 @@ public class UserRepository extends JORARepository
* the user record were modified.
*/
public boolean updateUser (final User user)
throws PersistenceException
throws PersistenceException
{
if (!user.getDirtyMask().isModified()) {
// nothing doing!
@@ -219,16 +219,16 @@ public class UserRepository extends JORARepository
* email.
*/
public void deleteUser (final User user)
throws PersistenceException
throws PersistenceException
{
if (user.isDeleted()) {
return;
}
executeUpdate(new Operation<Object>() {
executeUpdate(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException
{
{
// create our modified fields mask
FieldMask mask = _utable.getFieldMask();
mask.setModified("username");
@@ -257,8 +257,8 @@ public class UserRepository extends JORARepository
// ok we failed to rename the user, lets bust an error
throw new PersistenceException("Failed to 'delete' the user");
}
});
}
});
}
/**
@@ -269,7 +269,7 @@ public class UserRepository extends JORARepository
* @param expireDays the number of days in which the session token should expire.
*/
public String registerSession (User user, int expireDays)
throws PersistenceException
throws PersistenceException
{
// look for an existing session for this user
final String query = "select sessionId, authcode from sessions " +
@@ -291,9 +291,9 @@ public class UserRepository extends JORARepository
}
});
// figure out when to expire the session
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, expireDays);
// figure out when to expire the session
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, expireDays);
Date expires = new Date(cal.getTime().getTime());
// if we found one, update its expires time and reuse it
@@ -307,7 +307,7 @@ public class UserRepository extends JORARepository
String authcode = UserUtil.genAuthCode(user);
update("insert into sessions (authcode, userId, expires) values('" + authcode + "', " +
user.userId + ", '" + expires + "')");
return authcode;
return authcode;
}
/**
@@ -319,8 +319,8 @@ public class UserRepository extends JORARepository
public boolean refreshSession (String sessionKey, int expireDays)
throws PersistenceException
{
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, expireDays);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, expireDays);
Date expires = new Date(cal.getTime().getTime());
// attempt to update an existing session row, returning true if we found and updated it
@@ -332,7 +332,7 @@ public class UserRepository extends JORARepository
* Prunes any expired sessions from the sessions table.
*/
public void pruneSessions ()
throws PersistenceException
throws PersistenceException
{
update("delete from sessions where expires <= CURRENT_DATE()");
}
@@ -342,9 +342,9 @@ public class UserRepository extends JORARepository
* array. If any users do not exist, their slot in the array will contain a null.
*/
public String[] loadUserNames (int[] userIds)
throws PersistenceException
throws PersistenceException
{
return loadNames(userIds, "username");
return loadNames(userIds, "username");
}
/**
@@ -352,20 +352,20 @@ public class UserRepository extends JORARepository
* array. If any users do not exist, their slot in the array will contain a null.
*/
public String[] loadRealNames (int[] userIds)
throws PersistenceException
throws PersistenceException
{
return loadNames(userIds, "realname");
return loadNames(userIds, "realname");
}
/**
* Returns an array with the real names of every user in the system.
*/
public String[] loadAllRealNames ()
throws PersistenceException
throws PersistenceException
{
final ArrayList<String> names = new ArrayList<String>();
// do the query
// do the query
execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException
@@ -387,7 +387,7 @@ public class UserRepository extends JORARepository
}
});
// finally construct our result
// finally construct our result
return names.toArray(new String[names.size()]);
}
@@ -398,11 +398,11 @@ public class UserRepository extends JORARepository
protected void populateUser (
User user, Username name, Password pass, String realname, String email, int siteId)
{
user.username = name.getUsername();
user.setPassword(pass);
user.setRealName(realname);
user.setEmail(email);
user.created = new Date(System.currentTimeMillis());
user.username = name.getUsername();
user.setPassword(pass);
user.setRealName(realname);
user.setEmail(email);
user.created = new Date(System.currentTimeMillis());
user.setSiteId(siteId);
}
@@ -411,16 +411,16 @@ public class UserRepository extends JORARepository
* process, which is returned.
*/
protected int insertUser (final User user)
throws UserExistsException, PersistenceException
throws UserExistsException, PersistenceException
{
executeUpdate(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException
{
try {
_utable.insert(conn, user);
// update the userid now that it's known
user.userId = liaison.lastInsertedId(conn);
_utable.insert(conn, user);
// update the userid now that it's known
user.userId = liaison.lastInsertedId(conn);
// nothing to return
return null;
@@ -434,7 +434,7 @@ public class UserRepository extends JORARepository
}
});
return user.userId;
return user.userId;
}
/**
@@ -442,7 +442,7 @@ public class UserRepository extends JORARepository
* matches.
*/
protected User loadUserWhere (String where)
throws PersistenceException
throws PersistenceException
{
User user = load(_utable, where);
if (user != null) {
@@ -452,16 +452,16 @@ public class UserRepository extends JORARepository
}
protected String[] loadNames (int[] userIds, final String column)
throws PersistenceException
throws PersistenceException
{
// if userids is zero length, we've got no work to do
if (userIds.length == 0) {
return new String[0];
}
// do the query
// do the query
final String ids = genIdString(userIds);
final HashIntMap<String> map = new HashIntMap<String>();
final HashIntMap<String> map = new HashIntMap<String>();
execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException
@@ -486,12 +486,12 @@ public class UserRepository extends JORARepository
}
});
// finally construct our result
String[] result = new String[userIds.length];
for (int i = 0; i < userIds.length; i++) {
result[i] = map.get(userIds[i]);
}
return result;
// finally construct our result
String[] result = new String[userIds.length];
for (int i = 0; i < userIds.length; i++) {
result[i] = map.get(userIds[i]);
}
return result;
}
/**
@@ -500,14 +500,14 @@ public class UserRepository extends JORARepository
*/
protected String genIdString (int[] userIds)
{
// build up the string we need for the query
StringBuilder ids = new StringBuilder();
for (int i = 0; i < userIds.length; i++) {
if (ids.length() > 0) {
// build up the string we need for the query
StringBuilder ids = new StringBuilder();
for (int i = 0; i < userIds.length; i++) {
if (ids.length() > 0) {
ids.append(",");
}
ids.append(userIds[i]);
}
}
return ids.toString();
}
@@ -515,8 +515,8 @@ public class UserRepository extends JORARepository
// documentation inherited
protected void createTables ()
{
// create our table object
_utable = new Table<User>(User.class, "users", "userId");
// create our table object
_utable = new Table<User>(User.class, "users", "userId");
}
/** A wrapper that provides access to the userstable. */
@@ -33,13 +33,13 @@ public class UserUtil
*/
public static String genAuthCode (User user)
{
// concatenate a bunch of secret stuff together
StringBuilder buf = new StringBuilder();
buf.append(user.password);
buf.append(System.currentTimeMillis());
buf.append(Math.random());
// concatenate a bunch of secret stuff together
StringBuilder buf = new StringBuilder();
buf.append(user.password);
buf.append(System.currentTimeMillis());
buf.append(Math.random());
// and MD5 hash it
// and MD5 hash it
return StringUtil.md5hex(buf.toString());
}
@@ -62,7 +62,7 @@ public class UserUtil
if (ignoreUserCase) {
username = username.toLowerCase();
}
return Crypt.crypt(StringUtil.truncate(username, 2), password);
return Crypt.crypt(StringUtil.truncate(username, 2), password);
}
public static void main (String[] args)
@@ -48,18 +48,18 @@ public class Username
protected void validateName (String username)
throws InvalidUsernameException
{
// check length
if (username.length() < MINIMUM_USERNAME_LENGTH) {
throw new InvalidUsernameException("error.username_too_short");
}
if (username.length() > MAXIMUM_USERNAME_LENGTH) {
throw new InvalidUsernameException("error.username_too_long");
}
// check length
if (username.length() < MINIMUM_USERNAME_LENGTH) {
throw new InvalidUsernameException("error.username_too_short");
}
if (username.length() > MAXIMUM_USERNAME_LENGTH) {
throw new InvalidUsernameException("error.username_too_long");
}
// check that it's only valid characters
if (!username.matches(NAME_REGEX)) {
throw new InvalidUsernameException("error.invalid_username");
}
// check that it's only valid characters
if (!username.matches(NAME_REGEX)) {
throw new InvalidUsernameException("error.invalid_username");
}
}
protected String _username;