-----Original Message-----
From: Rafal Krzewski [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, September 06, 2000 10:42 AM
To: Turbine
Subject: Re: Moving user validation into User interface from UserFactory
class
> It would be great if you made changes to User/UserFactory and to the
current
> TurbineUser implementation to take advantage of the new validation scheme.
> Create diffs against the cvs version (use cvs diff -u) and post them to
> the list. We'll discuss them, and if agreement is reached, I'll check them
> in for you. Sounds good?
Sounds great. Proposed diffs follow; comments are welcome. Rafal, please
keep me in the loop if/when you check this stuff in. And thanks again!
====
? turbine/bin
Index: turbine/src/java/org/apache/turbine/om/user/TurbineNoDbUser.java
===================================================================
RCS file:
/products/cvs/turbine/turbine/src/java/org/apache/turbine/om/user/TurbineNoD
bUser.java,v
retrieving revision 1.2
diff -u -r1.2 TurbineNoDbUser.java
--- turbine/src/java/org/apache/turbine/om/user/TurbineNoDbUser.java
2000/08/29 20:00:20 1.2
+++ turbine/src/java/org/apache/turbine/om/user/TurbineNoDbUser.java
2000/09/08 21:28:26
@@ -78,6 +78,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Jon S. Stevens</a>
* @author <a href="mailto:[EMAIL PROTECTED]">John D. McNally</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Frank Y. Kim</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Craig D. Berry</a>
* @version $Id: TurbineNoDbUser.java,v 1.2 2000/08/29 20:00:20 gonzalo Exp
$
*/
public class TurbineNoDbUser
@@ -115,6 +116,16 @@
}
/**
+ * Checks the entered password against the stored version.
+ *
+ * @return 0 on success; 1 on bad username; 2 on bad password; 3 on
other error.
+ */
+ public int validate()
+ {
+ return 0; // with no db, this always succeeds
+ }
+
+ /**
* Gets the access counter for a user during a session.
*
* @return The access counter for the user for the session.
@@ -425,6 +436,21 @@
* @exception Exception, a generic exception.
*/
public User retrieveFromStorage( String username )
+ throws Exception
+ {
+ return this;
+ }
+
+ /*
+ * This function returns a TurbineUser which has been upcast to a
+ * User.
+ *
+ * @param username The name of the user.
+ * @param password The password of the user.
+ * @return A User.
+ * @exception Exception, a generic exception.
+ */
+ public User retrieveFromStorage( String username, String password )
throws Exception
{
return this;
Index: turbine/src/java/org/apache/turbine/om/user/TurbineUser.java
===================================================================
RCS file:
/products/cvs/turbine/turbine/src/java/org/apache/turbine/om/user/TurbineUse
r.java,v
retrieving revision 1.3
diff -u -r1.3 TurbineUser.java
--- turbine/src/java/org/apache/turbine/om/user/TurbineUser.java
2000/08/29 20:00:20 1.3
+++ turbine/src/java/org/apache/turbine/om/user/TurbineUser.java
2000/09/08 21:28:34
@@ -61,6 +61,9 @@
import java.sql.*;
import java.io.*;
+import javax.mail.internet.MimeUtility;
+import java.security.MessageDigest;
+
// Java Servlet Classes
import javax.servlet.*;
import javax.servlet.http.*;
@@ -69,7 +72,9 @@
import com.workingdogs.village.*;
import org.apache.turbine.om.BaseObject;
import org.apache.turbine.om.user.peer.TurbineUserPeer;
+import org.apache.turbine.util.*;
import org.apache.turbine.util.db.Criteria;
+import org.apache.turbine.services.resources.TurbineResources;
/**
* The User class describes a user in the system. This object is
@@ -79,6 +84,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Jon S. Stevens</a>
* @author <a href="mailto:[EMAIL PROTECTED]">John D. McNally</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Frank Y. Kim</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Craig D. Berry</a>
* @version $Id: TurbineUser.java,v 1.3 2000/08/29 20:00:20 gonzalo Exp $
*/
public class TurbineUser
@@ -103,6 +109,9 @@
/** This is data that will not survive a servlet engine restart. */
private Hashtable tempStorage = null;
+ /** Remember the user-supplied password, given through the
retrieveFromStorage
+ method, for use in the validate() method. */
+ public String enteredPassword = null;
/**
* Constructor.
@@ -117,6 +126,52 @@
}
/**
+ * Checks the entered password against the stored version.
+ *
+ * @return 0 on success; 1 on bad username; 2 on bad password; 3 on
other error.
+ */
+ public int validate()
+ {
+ if (TurbineResources.getBoolean("secure.passwords", false))
+ {
+ try
+ {
+ MessageDigest md = MessageDigest.getInstance("SHA");
+ byte[] digest = md.digest(enteredPassword.getBytes());
+ byte[] digestPlus = new byte[digest.length +
+ digest.length % 3];
+ for (int i=0; i<digest.length; i++)
+ {
+ digestPlus[i] = digest[i];
+ }
+ ByteArrayOutputStream baos = new
ByteArrayOutputStream(digestPlus.length);
+ OutputStream encodedStream = MimeUtility.encode(baos,
"base64");
+ encodedStream.write(digestPlus);
+ enteredPassword = baos.toString();
+ }
+ catch (Exception e)
+ {
+ Log.error("Unable to validate encrypted password.", e);
+ return 2;
+ }
+ }
+
+ if ( getUserName() != null) {
+ if ( (getPassword() != null) &&
getPassword().equals(enteredPassword) )
+ {
+ return 0;
+ }
+ else
+ {
+ return 2;
+ }
+ }
+
+ return 1;
+ }
+
+
+ /**
* Gets the access counter for a user during a session.
*
* @return The access counter for the user for the session.
@@ -418,17 +473,20 @@
return tempStorage.remove (name);
}
- /*
+ /**
* This function returns a TurbineUser which has been upcast to a
* User.
*
* @param username The name of the user.
+ * @param password The password of the user.
* @return A User.
* @exception Exception, a generic exception.
*/
- public User retrieveFromStorage( String username )
+ public User retrieveFromStorage( String username, String password )
throws Exception
{
+ enteredPassword = password; // Store for later use in validate()
+
Criteria criteria = new Criteria();
criteria.add( TurbineUserPeer.USERNAME, username );
Vector users = TurbineUserPeer.doSelect(criteria, this);
@@ -443,7 +501,21 @@
return null;
}
- /*
+ /**
+ * This function returns a TurbineUser which has been upcast to a
+ * User.
+ *
+ * @param username The name of the user.
+ * @return A User.
+ * @exception Exception, a generic exception.
+ */
+ public User retrieveFromStorage( String username )
+ throws Exception
+ {
+ return retrieveFromStorage(username, null);
+ }
+
+ /**
* This function returns a TurbineUser which has been upcast to a
* User.
*
Index: turbine/src/java/org/apache/turbine/om/user/User.java
===================================================================
RCS file:
/products/cvs/turbine/turbine/src/java/org/apache/turbine/om/user/User.java,
v
retrieving revision 1.3
diff -u -r1.3 User.java
--- turbine/src/java/org/apache/turbine/om/user/User.java 2000/09/05
14:07:31 1.3
+++ turbine/src/java/org/apache/turbine/om/user/User.java 2000/09/08
21:28:35
@@ -73,6 +73,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Frank Y. Kim</a>
* @author <a href="mailto:[EMAIL PROTECTED]">John D. McNally</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Jon S. Stevens</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Craig D. Berry</a>
* @version $Id: User.java,v 1.3 2000/09/05 14:07:31 gonzalo Exp $
*/
public interface User
@@ -85,6 +86,18 @@
public static final String SESSION_KEY = "turbine.user";
/**
+ * Validates that the stored username and password authenticate
correctly
+ * Note that user classes which validate to obtain access to the user
data
+ * (e.g., LDAP-based) will actually validate during object retrieval
from
+ * data, while SQL-based user classes can store the password at that
time
+ * and check it during this call, if desired.
+ *
+ * @return 0 on success, 1 on bad username, 2 on bad password, 3 on
other
+ * authentication failure.
+ */
+ public int validate();
+
+ /**
* Gets the access counter for a user from perm storage.
*
* @return The access counter for the user.
@@ -245,6 +258,18 @@
/**
* Retrieve a user from persistent storage using username as the
+ * key and (if required) the password to authenticate.
+ *
+ * @param username The name of the user.
+ * @param password The password of the user.
+ * @return A User.
+ * @exception Exception, a generic exception.
+ */
+ public User retrieveFromStorage( String username, String password )
+ throws Exception;
+
+ /**
+ * Retrieve a user from persistent storage using username as the
* key.
*
* @param username The name of the user.
@@ -253,6 +278,8 @@
*/
public User retrieveFromStorage( String username )
throws Exception;
+
+
/**
* Retrieve a user from persistent storage using visitorid as the
Index: turbine/src/java/org/apache/turbine/om/user/peer/UserFactory.java
===================================================================
RCS file:
/products/cvs/turbine/turbine/src/java/org/apache/turbine/om/user/peer/UserF
actory.java,v
retrieving revision 1.2
diff -u -r1.2 UserFactory.java
--- turbine/src/java/org/apache/turbine/om/user/peer/UserFactory.java
2000/08/29 20:00:22 1.2
+++ turbine/src/java/org/apache/turbine/om/user/peer/UserFactory.java
2000/09/08 21:28:37
@@ -72,6 +72,7 @@
* authentication should be done here.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Craig D. Berry</a>
* @version $Id: UserFactory.java,v 1.2 2000/08/29 20:00:22 gonzalo Exp $
*/
public class UserFactory
@@ -89,9 +90,19 @@
String password )
throws LoginFailedException
{
- User user = getUser( username );
+ String userClassName = TurbineResources
+ .getString("user.class",
"org.apache.turbine.om.user.TurbineUser");
+
+ User user = null;
- if ( validateUser(user, password) > 0 ) {
+ try {
+ user = (User) Class.forName(userClassName).newInstance();
+ user.retrieveFromStorage( username, password );
+ } catch (Exception e) {
+ throw new LoginFailedException( e.getMessage() );
+ }
+
+ if ( user.validate() > 0 ) {
throw new LoginFailedException(
TurbineResources.getString("login.error") );
} else {
return user;
@@ -108,15 +119,7 @@
public static User getUser( String username )
throws LoginFailedException
{
- String userClassName = TurbineResources
- .getString("user.class",
"org.apache.turbine.om.user.TurbineUser");
-
- User user = null;
- try {
- return user =
((User)Class.forName(userClassName).newInstance()).retrieveFromStorage(
username );
- } catch (Exception e) {
- throw new LoginFailedException( e.getMessage() );
- }
+ return getUser(username, null);
}
/**
@@ -133,6 +136,7 @@
.getString("user.class",
"org.apache.turbine.om.user.TurbineUser");
User user = null;
+
try {
return user =
((User)Class.forName(userClassName).newInstance()).retrieveFromStorage( id
);
} catch (Exception e) {
@@ -162,51 +166,4 @@
}
}
- /**
- * Validate a user, return a status for the validation.
- *
- * @param user The User object.
- * @param password The user password.
- * @return 0 if username and password are valid, 1 if username is
- * not valid, 2 if password is not valid.
- */
- static int validateUser(User user,
- String password)
- {
- if (TurbineResources.getBoolean("secure.passwords", false))
- {
- try
- {
- MessageDigest md = MessageDigest.getInstance("SHA");
- byte[] digest = md.digest(password.getBytes());
- byte[] digestPlus = new byte[digest.length +
- digest.length % 3];
- for (int i=0; i<digest.length; i++)
- {
- digestPlus[i] = digest[i];
- }
- ByteArrayOutputStream baos = new
ByteArrayOutputStream(digestPlus.length);
- OutputStream encodedStream = MimeUtility.encode(baos,
"base64");
- encodedStream.write(digestPlus);
- password = baos.toString();
- }
- catch (Exception e)
- {
- Log.error("Unable to validate encrypted password.", e);
- return 2;
- }
- }
- if ( user != null )
- {
- if ( (user.getPassword() != null) &&
user.getPassword().equals(password) )
- {
- return 0;
- }
- else
- {
- return 2;
- }
- }
- return 1;
- }
}
------------------------------------------------------------
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Search: <http://www.mail-archive.com/turbine%40list.working-dogs.com/>
Problems?: [EMAIL PROTECTED]