Mo betta user management.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@71 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2001-03-02 02:08:50 +00:00
parent 998f929340
commit d33bd92c4d
7 changed files with 187 additions and 31 deletions
@@ -0,0 +1,12 @@
//
// $Id: InvalidPasswordException.java,v 1.1 2001/03/02 02:08:50 mdb Exp $
package com.samskivert.servlet.user;
public class InvalidPasswordException extends Exception
{
public InvalidPasswordException (String message)
{
super(message);
}
}
@@ -1,13 +1,16 @@
#
# $Id: Makefile,v 1.1 2001/03/02 01:21:06 mdb Exp $
# $Id: Makefile,v 1.2 2001/03/02 02:08:50 mdb Exp $
ROOT = ../../../..
SRCS = \
InvalidPasswordException.java \
InvalidUsernameException.java \
NoSuchUserException.java \
User.java \
UserExistsException.java \
UserManager.java \
UserRepository.java \
UserUtil.java \
include $(ROOT)/build/Makefile.java
@@ -0,0 +1,12 @@
//
// $Id: NoSuchUserException.java,v 1.1 2001/03/02 02:08:50 mdb Exp $
package com.samskivert.servlet.user;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String message)
{
super(message);
}
}
@@ -1,5 +1,5 @@
//
// $Id: User.java,v 1.1 2001/03/02 01:21:06 mdb Exp $
// $Id: User.java,v 1.2 2001/03/02 02:08:50 mdb Exp $
package com.samskivert.servlet.user;
@@ -53,7 +53,7 @@ public class User
*/
public void setPassword (String password)
{
this.password = UserRepository.encryptPassword(username, password);
this.password = UserUtil.encryptPassword(username, password);
}
/**
@@ -63,4 +63,16 @@ public class User
{
this.email = email;
}
/**
* Compares the supplied password with the password associated with
* this user record.
*
* @return true if the passwords match, false if they do not.
*/
public boolean passwordsMatch (String password)
{
String epasswd = UserUtil.encryptPassword(username, password);
return this.password.equals(epasswd);
}
}
@@ -1,20 +1,16 @@
//
// $Id: UserManager.java,v 1.1 2001/03/02 01:21:06 mdb Exp $
// $Id: UserManager.java,v 1.2 2001/03/02 02:08:50 mdb Exp $
package com.samskivert.servlet.user;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.Properties;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpUtils;
import javax.servlet.http.*;
import com.samskivert.Log;
import com.samskivert.servlet.RedirectException;
import com.samskivert.util.Interval;
import com.samskivert.util.IntervalManager;
import com.samskivert.util.StringUtil;
import com.samskivert.util.*;
/**
* The user manager provides easy access to user objects for servlets. It
@@ -99,9 +95,9 @@ public class UserManager
public User loadUser (HttpServletRequest req)
throws SQLException
{
String authcode = getUserAuthCookie(req);
String authcode = getAuthCode(req);
if (authcode != null) {
return _repository.getUserBySession(authcode);
return _repository.loadUserBySession(authcode);
} else {
return null;
}
@@ -136,7 +132,55 @@ public class UserManager
return user;
}
protected static String getUserAuthCookie (HttpServletRequest req)
/**
* Attempts to authenticate the requester and initiate an
* authenticated session for them. An authenticated session involves
* their receiving a cookie that provides them to be authenticated and
* an entry in the session database being created that maps their
* information to their userid. If this call completes, the session
* was established and the proper cookies were set in the supplied
* response object. If invalid authentication information is provided
* or some other error occurs, an exception will be thrown.
*/
public void login (String username, String password,
HttpServletResponse rsp)
throws SQLException, NoSuchUserException, InvalidPasswordException
{
// load up the requested user
User user = _repository.loadUser(username);
if (user == null) {
throw new NoSuchUserException("error.no_such_user");
}
if (!user.passwordsMatch(password)) {
throw new InvalidPasswordException("error.invalid_password");
}
// generate a new session for this user
String authcode = _repository.createNewSession(user);
// stick it into a cookie for their browsing convenience
Cookie acookie = new Cookie(USERAUTH_COOKIE, authcode);
acookie.setPath("/");
acookie.setMaxAge(24*60*60); // expire in two days
rsp.addCookie(acookie);
}
public void logout (HttpServletRequest req, HttpServletResponse rsp)
{
String authcode = getAuthCode(req);
// nothing to do if they don't already have an auth cookie
if (authcode == null) {
return;
}
// set them up the bomb
Cookie rmcookie = new Cookie(USERAUTH_COOKIE, authcode);
rmcookie.setPath("/");
rmcookie.setMaxAge(0);
rsp.addCookie(rmcookie);
}
protected static String getAuthCode (HttpServletRequest req)
{
Cookie[] cookies = req.getCookies();
if (cookies == null) {
@@ -1,9 +1,10 @@
//
// $Id: UserRepository.java,v 1.1 2001/03/02 01:21:06 mdb Exp $
// $Id: UserRepository.java,v 1.2 2001/03/02 02:08:50 mdb Exp $
package com.samskivert.servlet.user;
import java.sql.*;
import java.util.Calendar;
import java.util.Properties;
import org.apache.regexp.*;
@@ -11,7 +12,6 @@ import org.apache.regexp.*;
import com.samskivert.Log;
import com.samskivert.jdbc.MySQLRepository;
import com.samskivert.jdbc.jora.*;
import com.samskivert.util.Crypt;
public class UserRepository extends MySQLRepository
{
@@ -73,7 +73,7 @@ public class UserRepository extends MySQLRepository
// create a new user object and stick it into the database
final User user = new User();
user.username = username;
user.password = encryptPassword(username, password);
user.password = UserUtil.encryptPassword(username, password);
user.realname = realname;
user.email = email;
user.created = new Date(System.currentTimeMillis());
@@ -99,21 +99,13 @@ public class UserRepository extends MySQLRepository
return user.userid;
}
/**
* Encrypts the user's password according to our preferred scheme.
*/
public static String encryptPassword (String username, String password)
{
return Crypt.crypt(username.substring(0, 2), password);
}
/**
* Looks up a user by username.
*
* @return the user with the specified user id or null if no user with
* that id exists.
*/
public User getUser (String username)
public User loadUser (String username)
throws SQLException
{
// look up the user
@@ -135,7 +127,7 @@ public class UserRepository extends MySQLRepository
* @return the user with the specified user id or null if no user with
* that id exists.
*/
public User getUser (int userid)
public User loadUser (int userid)
throws SQLException
{
// look up the user
@@ -157,7 +149,7 @@ public class UserRepository extends MySQLRepository
* @return the user associated with the specified session or null of
* no session exists with the supplied identifier.
*/
public User getUserBySession (String sessionKey)
public User loadUserBySession (String sessionKey)
throws SQLException
{
// look up the user
@@ -203,6 +195,39 @@ public class UserRepository extends MySQLRepository
});
}
/**
* Creates a new session for the specified user and returns the
* randomly generated session identifier for that session. Sessions
* are set to expire in two days which prevents someone from being
* screwed if they log in at 11:59pm, but also prevents them from
* leaving their browser authenticated for too long.
*/
public String createNewSession (final User user)
throws SQLException
{
// generate a random session identifier
final String authcode = UserUtil.genAuthCode(user);
// figure out what 48 hours from now is
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 2);
final Date expires = new Date(cal.getTime().getTime());
// insert the session into the database
execute(new Operation () {
public void invoke () throws SQLException
{
_session.execute("insert into sessions " +
"(authcode, userid, expires) values('" +
authcode + "', " + user.userid + ", " +
expires + ")");
}
});
// and let the user know what the session identifier is
return authcode;
}
/**
* Prunes any expired sessions from the sessions table.
*/
@@ -229,8 +254,8 @@ public class UserRepository extends MySQLRepository
try {
UserRepository rep = new UserRepository(props);
System.out.println(rep.getUser("mdb"));
System.out.println(rep.getUserBySession("auth"));
System.out.println(rep.loadUser("mdb"));
System.out.println(rep.loadUserBySession("auth"));
rep.createUser("samskivert", "foobar", "Michael Bayne",
"mdb@samskivert.com");
@@ -246,8 +271,6 @@ public class UserRepository extends MySQLRepository
protected Table _utable;
protected static final int MINIMUM_USERNAME_LENGTH = 2;
/** Used to check usernames for invalid characteres. */
protected static RE _userre;
static {
@@ -257,4 +280,7 @@ public class UserRepository extends MySQLRepository
Log.warning("Unable to initialize user regexp?! " + rese);
}
}
/** The minimum allowable length of a username. */
protected static final int MINIMUM_USERNAME_LENGTH = 3;
}
@@ -0,0 +1,47 @@
//
// $Id: UserUtil.java,v 1.1 2001/03/02 02:08:50 mdb Exp $
package com.samskivert.servlet.user;
import java.security.*;
import com.samskivert.util.Crypt;
import com.samskivert.util.StringUtil;
/**
* User related utility functions.
*/
public class UserUtil
{
/**
* Generates a new random session identifier for the supplied user.
*/
public static String genAuthCode (User user)
{
// concatenate a bunch of secret stuff together
StringBuffer buf = new StringBuffer();
buf.append(user.password);
buf.append(System.currentTimeMillis());
buf.append(Math.random());
// and MD5 hash it
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] enc = digest.digest(buf.toString().getBytes());
return StringUtil.hexlate(enc);
} catch (NoSuchAlgorithmException nsae) {
throw new RuntimeException("JVM missing MD5 message digest " +
"algorithm implementation. User " +
"management facilities require MD5 " +
"encoding capabilities.");
}
}
/**
* Encrypts the user's password according to our preferred scheme.
*/
public static String encryptPassword (String username, String password)
{
return Crypt.crypt(username.substring(0, 2), password);
}
}