Re: WOA, Building a Login form
Re: WOA, Building a Login form
- Subject: Re: WOA, Building a Login form
- From: Nathan Hampton <email@hidden>
- Date: Sun, 3 Apr 2005 14:30:24 -0700
I guess I'll toss my two cents worth in here, too... :)
Like Drew, I'm far from an expert, but I have a WOComponent named
LoginPanel and a class named AccessControl that work together to handle
this in much the way Jean-François suggests. I've pasted the key
portions of the code below, but I can email you the complete component
off-list if you'd like.
Good luck!
--NCH
Action from component LoginPanel:
public WOComponent processLogin() // Triggered by submit button
{
// 'username' and 'password' are user input
if (AccessControl.login((Session)session(), username, password))
{
// 'destination' is a required binding
return pageWithName(destination);
}
else
{
// I show a pre-specified non-specific error message for security
// reasons, but it's easy enough to change this to something
// more detailed
showErrorMessage = true;
password = null;
return null;
}
}
From class AccessControl:
// I completely ignore Java naming conventions here...
public static final int minimumValueToAllowLogin = 1; // Set this to
whatever makes sense for you.
// Process Login Requests
public static boolean login(Session session, String username, String
password)
{
boolean result = false;
// Were arguments properly passed? (prevents loads of exceptions)
if (session != null && username != null && password != null)
{
WebUser newUser = null;
EOEditingContext ec = session.defaultEditingContext();
try // to get user from DB
{
if (username.indexOf("@") > 0) //FIXME: use email validity checker?
{
newUser = (WebUser)EOUtilities.objectMatchingKeyAndValue(ec,
"WebUser", "email", username); // get by email
}
else
{
newUser = (WebUser)EOUtilities.objectMatchingKeyAndValue(ec,
"WebUser", "username", username); // get by username
}
}
catch (EOUtilities.MoreThanOneException e)
{
// See "Practical WebObjects" (aka "Chuck's Book") for a more
complete discussion of logging
//FIXME: Log error: WebUser.username should be unique
//System.out.println("DATA INTEGRITY ERROR: There are multiple
WebUser objects which have the username or email address " + username);
// FIXME: In addition to logging error, send email to sysadmin
}
catch (Exception e)
{
// Most likely an EOObjectNotAvailableException
// This isn't a big deal because we check for null value next
}
// Was fetch successful?
if (newUser != null)
{
// Get login access authorized for user (see access code reference)
// Parse to int for comparison with minimum login value specified
above
int accessLevelForUser =
Integer.parseInt(newUser.accessCode().substring(0,1));
// I use a kind of screwy permissions system that relies on a
string of digits
// (the aforementioned "access code" to indicate what a user may
or may not do.
if (password.length() > 0 // password input exists
&& accessLevelForUser >= minimumValueToAllowLogin // user is
allowed to log in
&& password.equals(newUser.password()) ) // password is correct
{
result = true;
session.setUser(newUser);
}
}
}
return result;
}
On 03 Apr 2005, at 10:53 AM, Jean-François Veillette wrote:
Note that WO propose to the developer to use a very clean design,
where logic code is somewhere, in the business layer, and the display
related code is in WOComponent subclasses.
In most code snippets you can find on the web and mail archives, you
will be guided with an all-in-one implementation, where you get
display and logic related code all in one. This is for simplicity
purposes, to deliver a simple answer to a simple question. I'm
inclined to think that this is one of the factor that could explain
why newcomer do not get the 'power of wo' so quickly. If public code
snippets could both give a simple solution with a clean design, it
would reminds newcomers of the clean design of wo and of how to
approach it.
Note that 'all-in-one' is fine for quick implementation to 'make it
works'. But mid-term / long-term you want to re-factor the sample
code and separate display logic from business logic.
Consider the two options :
1- Should a ' display widget ' (a subclass of WOComponent) execute the
login action ?
and know all about it's implementation details.
2- Should a ' display widget ' (a subclass of WOComponent) _trigger_ a
login action ?
which action is implemented somewhere in the business layer (a
'black box' from the display perspective).
Here you have a nice piece of code, it will most likely work (I didn't
test myself).
Do not hesitate to take any public code apart and separate the login
mechanics from the display mechanics.
This is not a wo-specific issue, but you will gain the max from wo if
you get the wo mind-set as soon as possible.
- jfv
Le 05-04-03, à 12:14, Drew Thoeni a écrit :
First, I'm not, by any stretch, an expert WO/Java programmer. Given
that, here's some code I use that others on the list might have
improvement suggestions on.
/**
* Checks for null email address and password. If not null then
* This user is retrieved from the database and their encrypted
password
* of record is compared to what they entered. All methods calculating
the password
* or comparing the password add the user's email address before the
password
* as a salt to ensure no two password digests are the same.
* Requires import java.security.*
* @throws NoSuchAlgorithmException
*/
public WOComponent login() throws NoSuchAlgorithmException {
if (enteredPassword == null) { // User did not enter password
errorMsg = "Error: Password can not be empty.";
return context().page();
}
User tempUser = fetchUser();
if (tempUser == null) {return context().page();}
String encryptedPassword =
Converter.encryptPassword(enteredEmail.trim()+enteredPassword);
if (encryptedPassword.equals(tempUser.password())) { //
passwords match, user is authenticated
tempUser.setLastLogIn(new NSTimestamp());
tempUser.setTimesLoggedIn( new
Integer(tempUser.timesLoggedIn().intValue() + 1) );
ec.saveChanges();
}
else {
errorMsg = "Error: Password or email invalid.";
return context().page();
}
}
/**
* Fecths a single user from the database whose email address
* macthes the one input by the user attempting to login
*/
private User fetchUser() {
if (enteredEmail == null) {
errorMsg = "Error: Email address appears invalid.";
return null;
}
// fetch user from database
NSDictionary bindings = new NSDictionary(enteredEmail.trim(),
"primaryEmailIn");
User u = null;
try {
u = (User)EOUtilities.objectWithFetchSpecificationAndBindings(
ec, "User", "FetchSingleUser", bindings);
}
catch (Exception e) {
NSLog.debug.appendln("Unknown user with email " + enteredEmail +
" generated this login exception: " + e);
errorMsg = User.staticExceptionHandler(e);
ec.revert();
return null;
}
return u;
}
/**
* This static method (from Converter class) takes a string and
encrypts it using one-way encryption.
* @param String passwordIn is any string, but typically will be
* a clear text password to be encrpyted.
*/
public static String encryptPassword(String passwordIn) throws
NoSuchAlgorithmException {
String encryptedPassword;
MessageDigest md = MessageDigest.getInstance("SHA"); // Can be
"MD5" or "SHA" (MD5 is weaker)
md.reset();
md.update(passwordIn.getBytes());
byte[]arr = md.digest();
encryptedPassword = (new BASE64Encoder()).encode(arr);
return encryptedPassword;
}
On Apr 3, 2005, at 11:46 AM, Amedeo Mantica wrote:
I' looking for a code example
Thanks
Amedeo
On 03/apr/05, at 17:38, Drew Thoeni wrote:
Amedeo,
There are many apps on the web that show user authentication (the
Apple Store being an example). Are you looking for code or is there
a specific part of authentication you have a question about?
Drew
On Apr 3, 2005, at 11:30 AM, Amedeo Mantica wrote:
Hi,
I'm new to webojects applications, and I see that webobjects is
really nice and I want to switch from PHP!
Just a question, does anyone have a web example with user
authentication ?
Thanks
Best Regards
Amedeo Mantica
Insigno Design Studio
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden
This email sent to email@hidden
Amedeo Mantica
Insigno Design Studio
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden
This email sent to email@hidden
______________________________________________________________________
Post your free ad now! http://personals.yahoo.ca
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden