/*
* Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
*
* This file is part of TransferCM.
*
* TransferCM is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* TransferCM 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.methodhead.reg;
import com.methodhead.persistable.Persistable;
import com.methodhead.persistable.Key;
import com.methodhead.aikp.AutoIntKeyPersistable;
import com.methodhead.aikp.IntKey;
import com.methodhead.sitecontext.SiteContext;
import com.methodhead.auth.AuthUser;
import com.methodhead.util.MhfStringUtils;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.BasicDynaClass;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.methodhead.persistable.ConnectionSingleton;
import org.apache.commons.lang.exception.ExceptionUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.log4j.Logger;
import org.apache.commons.lang.exception.ExceptionUtils;
/**
* A User. The following fields are defined:
* <ul>
* <li><tt>int id = 0</tt></li>
* <li><tt>String password = ""</tt></li>
* <li><tt>int contact_id = 0</tt></li>
* </ul>
*/
public class User
extends
AutoIntKeyPersistable
implements
AuthUser,
Comparable {
private static DynaClass dynaClass_ = null;
private static DynaClass roleDynaClass_ = null;
private static DynaClass siteContextDynaClass_ = null;
static {
//
// user
//
DynaProperty[] dynaProperties =
new DynaProperty[] {
new DynaProperty( "id", Integer.class ),
new DynaProperty( "password", String.class ),
new DynaProperty( "contact_id", Integer.class )
};
dynaClass_ =
new BasicDynaClass(
"reg_user", User.class, dynaProperties );
//
// role
//
dynaProperties =
new DynaProperty[] {
new DynaProperty( "user_id", Integer.class ),
new DynaProperty( "sitecontext_id", Integer.class ),
new DynaProperty( "name", String.class )
};
roleDynaClass_ =
new BasicDynaClass(
"reg_role", Persistable.class, dynaProperties );
}
// constructors /////////////////////////////////////////////////////////////
public User() {
super( dynaClass_ );
init();
}
public User( DynaClass dynaClass ) {
super( dynaClass );
init();
}
// constants ////////////////////////////////////////////////////////////////
// classes //////////////////////////////////////////////////////////////////
// methods //////////////////////////////////////////////////////////////////
public int compareTo(
Object o ) {
if ( o == null ) {
throw new NullPointerException();
}
User user = ( User )o;
return this.getContact().getFullName().compareTo( user.getContact().getFullName() );
}
protected void init() {
setInt( "id", 0 );
setString( "password", "" );
setInt( "contact_id", 0 );
}
public String toString() {
if ( "".equals( getContact().getString( "email" ) ) )
return "User (no email address)";
else
return getContact().getString( "email" );
}
/**
* Extends default behaviour to handle password encryption if
* passwordEncrypted flag is set.
*/
public void set(
String name,
Object value ) {
if ( !loading_ ) {
if ( "password".equals( name ) ) {
if ( getPasswordEncrypted() ) {
super.set( "password", encryptPassword( ( String )value ) );
return;
}
}
}
super.set( name, value );
}
public boolean authenticate(
String password ) {
if ( getPasswordEncrypted() ) {
return getString( "password" ).equals( encryptPassword( password ) );
}
else {
return getString( "password" ).equals( password );
}
}
public String getLogin() {
return getContact().getString( "email" );
}
public String getPublicSecret() {
return encryptPassword( getString( "password" ) );
}
public boolean loadForLogin(
String login ) {
ResultSet rs = null;
try {
String sql =
"SELECT " +
" reg_user.id AS id " +
"FROM " +
" reg_user " +
"LEFT JOIN " +
" reg_contact ON " +
" reg_user.contact_id = reg_contact.id " +
"WHERE " +
" reg_contact.email=" + getSqlLiteral( login );
rs = ConnectionSingleton.runQuery( sql );
if ( rs == null ) {
throw new SQLException( "Null result set." );
}
if ( !rs.next() ) {
return false;
}
load( new IntKey( rs.getInt( "id" ) ) );
return true;
}
catch ( SQLException e ) {
String msg = "Doing something. " + ExceptionUtils.getStackTrace( e );
logger_.error( msg );
throw new RuntimeException( msg );
}
finally {
ConnectionSingleton.close( rs );
}
}
/**
* Returns true if this user has the role <tt>name</tt> for the site
* <tt>siteContext</tt>.
*/
public boolean hasRole(
SiteContext siteContext,
String name ) {
for ( Iterator iter = roles_.iterator(); iter.hasNext(); ) {
Role role = ( Role )iter.next();
if ( role.getSiteContext().equals( siteContext ) &&
role.getName().equals( name ) )
return true;
}
return false;
}
private SiteContext getSiteContext(
int id ) {
SiteContext siteContext = new SiteContext();
siteContext.load( new IntKey( id ) );
return siteContext;
}
private void saveRoles() {
Persistable p = new Persistable( roleDynaClass_ );
p.setInt( "user_id", getInt( "id" ) );
for ( Iterator iter = roles_.iterator(); iter.hasNext(); ) {
Role role = ( Role )iter.next();
p.setString( "name", role.getName() );
p.setInt( "sitecontext_id", role.getSiteContext().getInt( "id" ) );
p.saveNew();
}
}
private void loadRoles() {
List l =
Persistable.loadAll( roleDynaClass_, "user_id=" + getInt( "id" ), null );
roles_.clear();
for ( Iterator iter = l.iterator(); iter.hasNext(); ) {
Persistable p = ( Persistable )iter.next();
Role role = new Role();
role.setSiteContext( getSiteContext( p.getInt( "sitecontext_id" ) ) );
role.setName( p.getString( "name" ) );
roles_.add( role );
}
}
private void deleteRoles() {
Persistable p = new Persistable( roleDynaClass_ );
p.deleteAll( roleDynaClass_, "user_id=" + getInt( "id" ) );
}
public void saveNew() {
contact_.saveNew();
setInt( "contact_id", contact_.getInt( "id" ) );
super.saveNew();
saveRoles();
}
public void load(
Key key ) {
loading_ = true;
super.load( key );
contact_.load( new IntKey( getInt( "contact_id" ) ) );
loadRoles();
loading_ = false;
}
public void save() {
deleteRoles();
saveRoles();
super.save();
contact_.save();
}
public void delete() {
deleteRoles();
super.delete();
contact_.delete();
}
/**
* Returns a list of all {@link com.methodhead.reg.User User}s associated
* with <tt>siteContext</tt>.
*/
public List loadAllForSiteContext(
SiteContext siteContext ) {
ResultSet rs = null;
List list = new ArrayList();
try {
rs = ConnectionSingleton.runQuery(
"SELECT DISTINCT user_id FROM reg_role WHERE sitecontext_id=" +
siteContext.getInt( "id" ) );
while ( rs.next() ) {
User user = new User();
user.load( new IntKey( rs.getInt( "user_id" ) ) );
list.add( user );
}
ConnectionSingleton.close( rs );
}
catch ( SQLException e ) {
ConnectionSingleton.close( rs );
throw new RuntimeException(
"Unexpected SQLException while loading all users for site context " +
siteContext + ":\n" + ExceptionUtils.getStackTrace( e ) );
}
return list;
}
/**
* Encrypts <tt>password</tt> by MD5 hashing it and Base64 encoding the
* result.
*/
protected String encryptPassword(
String password ) {
return MhfStringUtils.hashAndEncode( password );
}
// properties ///////////////////////////////////////////////////////////////
/**
* Returns a list of {@link Role Role}s for the user.
*/
public List getRoles() {
return roles_;
}
public Contact getContact() {
return contact_;
}
public boolean getPasswordEncrypted() {
return passwordEncrypted_;
}
/**
* Sets the password encrypted flag. When this flag is set, passwords are
* hashed with MD5 and Base64 encoded before being saved in the database or
* used in {@link #authenticate authenticate()}.
*/
public void setPasswordEncrypted(
boolean passwordEncrypted ) {
passwordEncrypted_ = passwordEncrypted;
}
// attributes ///////////////////////////////////////////////////////////////
private List roles_ = new ArrayList();
private Contact contact_ = new Contact();
private boolean passwordEncrypted_ = false;
private boolean loading_ = false;
private static Logger logger_ = Logger.getLogger( User.class );
}
|