added Admin Modify User functionality

This commit is contained in:
Eric J. Bowersox
2001-04-16 05:23:39 +00:00
parent acc7f06e66
commit d63681a0ad
16 changed files with 1747 additions and 27 deletions
@@ -21,8 +21,14 @@ import java.util.List;
public interface AdminOperations
{
public abstract boolean isGlobalAdmin();
public abstract List getAuditRecords(int offset, int count) throws DataException;
public abstract int getAuditRecordCount() throws DataException;
public abstract AdminUserContext getUserContext(int uid) throws DataException;
public abstract AdminUserContext getUserContext(String username) throws DataException;
} // end interface AdminOperations
@@ -0,0 +1,66 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public interface AdminUserContext
{
public abstract int getUID();
public abstract String getUserName();
public abstract int getContactID();
public abstract String getDescription();
public abstract void setDescription(String new_descr) throws DataException;
public abstract int getBaseLevel();
public abstract void setBaseLevel(int new_level) throws DataException;
public abstract boolean isEmailVerified();
public abstract void setEmailVerified(boolean flag) throws DataException;
public abstract boolean isLockedOut();
public abstract void setLockedOut(boolean flag) throws DataException;
public abstract ContactInfo getContactInfo() throws DataException;
public abstract void putContactInfo(ContactInfo ci) throws DataException;
public abstract void setPassword(String password, String reminder) throws DataException;
public abstract Locale getLocale();
public abstract void setLocale(Locale locale) throws DataException;
public abstract TimeZone getTimeZone();
public abstract void setTimeZone(TimeZone timezone) throws DataException;
public abstract Date getCreationDate();
public abstract Date getLastAccessDate();
} // end interface AdminUserContext
@@ -23,6 +23,7 @@ import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.security.SecLevels;
class AdminOperationsImpl implements AdminOperations
{
@@ -31,7 +32,7 @@ class AdminOperationsImpl implements AdminOperations
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(AdminOperationsImpl.class.getName());
private static Category logger = Category.getInstance(AdminOperationsImpl.class);
/*--------------------------------------------------------------------------------
* Attributes
@@ -60,6 +61,12 @@ class AdminOperationsImpl implements AdminOperations
*--------------------------------------------------------------------------------
*/
public boolean isGlobalAdmin()
{
return (user.realBaseLevel()==SecLevels.GLOBAL_BOFH);
} // end isGlobalAdmin
public List getAuditRecords(int offset, int count) throws DataException
{
Connection conn = null;
@@ -116,4 +123,16 @@ class AdminOperationsImpl implements AdminOperations
} // end getAuditRecordCount
public AdminUserContext getUserContext(int uid) throws DataException
{
return AdminUserContextImpl.getAdminUserContext(engine,user,datapool,uid);
} // end getUserContext
public AdminUserContext getUserContext(String username) throws DataException
{
return AdminUserContextImpl.getAdminUserContext(engine,user,datapool,username);
} // end getUserContext
} // end class AdminOperationsImpl
@@ -0,0 +1,650 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.LocaleFactory;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.security.PasswordHash;
import com.silverwrist.venice.security.AuditRecord;
class AdminUserContextImpl implements AdminUserContext
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(AdminUserContextImpl.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private EngineBackend engine; // the back end of the engine
private UserBackend user; // the controlling administrative user
private DataPool datapool; // the data pool used by this object
private int uid; // the user ID of this user
private int contactid; // ID of associated contact information
private int level; // base security level for this user
private boolean email_verified; // has email address been verified?
private boolean lockout; // is this account locked out?
private String username; // the user name we're using
private java.util.Date created; // when was this user created? (GMT)
private java.util.Date last_access; // when did we last log in? (GMT)
private String description; // personal description
private Locale my_locale; // my default locale (cached)
private TimeZone my_tz; // my default timezone (cached)
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
protected AdminUserContextImpl(EngineBackend engine, UserBackend user, DataPool datapool, ResultSet rs)
throws SQLException
{
this.engine = engine;
this.user = user;
this.datapool = datapool;
this.uid = rs.getInt("uid");
this.contactid = rs.getInt("contactid");
this.level = rs.getInt("base_lvl");
this.email_verified = rs.getBoolean("verify_email");
this.lockout = rs.getBoolean("lockout");
this.username = rs.getString("username");
this.created = SQLUtil.getFullDateTime(rs,"created");
this.last_access = SQLUtil.getFullDateTime(rs,"lastaccess");
this.description = rs.getString("description");
this.my_locale = LocaleFactory.createLocale(rs.getString("localeid"));
this.my_tz = TimeZone.getTimeZone(rs.getString("tzid"));
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface AdminUserContext
*--------------------------------------------------------------------------------
*/
public int getUID()
{
return uid;
} // end getUID
public String getUserName()
{
return username;
} // end getUserName
public int getContactID()
{
return contactid;
} // end getContactID
public String getDescription()
{
return description;
} // end getDescription
public void setDescription(String new_descr) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
if (new_descr.equals(description))
return;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("UPDATE users SET description = '");
sql.append(SQLUtil.encodeString(new_descr)).append("' WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString());
description = new_descr; // change stored information
ar = new AuditRecord(AuditRecord.ADMIN_ACCOUNT_CHANGE,user.realUID(),user.userRemoteAddress(),0,
"uid=" + uid,"field=description");
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error changing description: " + e.getMessage(),e);
throw new DataException("Unable to set user description: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setDescription
public int getBaseLevel()
{
return level;
} // end getBaseLevel
public void setBaseLevel(int new_level) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
if (level==new_level)
return;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("UPDATE users SET base_lvl = ");
sql.append(new_level).append(" WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString());
level = new_level;
ar = new AuditRecord(AuditRecord.ADMIN_SET_SECURITY,user.realUID(),user.userRemoteAddress(),0,
"uid=" + uid,"level=" + new_level);
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error changing base level: " + e.getMessage(),e);
throw new DataException("Unable to set user base level: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setBaseLevel
public boolean isEmailVerified()
{
return email_verified;
} // end isEmailVerified
public void setEmailVerified(boolean flag) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
if (flag==email_verified)
return;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("UPDATE users SET verify_email = ");
sql.append(flag ? '1' : '0').append(" WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString());
email_verified = flag;
ar = new AuditRecord(AuditRecord.ADMIN_ACCOUNT_CHANGE,user.realUID(),user.userRemoteAddress(),0,
"uid=" + uid,"field=verify_email");
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error changing verify flag: " + e.getMessage(),e);
throw new DataException("Unable to set user verify flag: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setEmailVerified
public boolean isLockedOut()
{
return lockout;
} // end isLockedOut
public void setLockedOut(boolean flag) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
if (flag==lockout)
return;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("UPDATE users SET lockout = ");
sql.append(flag ? '1' : '0').append(" WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString());
lockout = flag;
ar = new AuditRecord(AuditRecord.ADMIN_LOCK_OUT,user.realUID(),user.userRemoteAddress(),0,
"uid=" + uid,flag ? "locked" : "unlocked");
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error changing lockout flag: " + e.getMessage(),e);
throw new DataException("Unable to set user lockout flag: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setLockedOut
public ContactInfo getContactInfo() throws DataException
{
if (logger.isDebugEnabled())
logger.debug("getContactInfo() for UID " + uid);
ContactInfoImpl rc;
if (contactid>=0)
rc = new ContactInfoImpl(datapool,contactid);
else
rc = new ContactInfoImpl(uid);
return rc;
} // end getContactInfo
public void putContactInfo(ContactInfo ci) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("putContactInfo() for UID " + uid);
if ((ci.getOwnerUID()!=uid) || (ci.getOwnerSIGID()>=0))
{ // the contact information is not owned correctly
logger.error("ContactInfo ownership wrong (it's " + ci.getOwnerUID() + ", " + ci.getOwnerSIGID()
+ "), should be (" + uid + ", -1)");
throw new DataException("invalid contact information record");
} // end if
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
try
{ // get a database connection
conn = datapool.getConnection();
Stashable obj = (Stashable)ci;
// save the contact information
obj.stash(conn);
if (contactid<0)
{ // contact being established for the first time
contactid = ci.getContactID();
if (logger.isDebugEnabled())
logger.debug("...established initial contact (" + contactid + ") for user");
} // end if
ar = new AuditRecord(AuditRecord.ADMIN_USER_CONTACT_INFO,user.realUID(),user.userRemoteAddress(),
"uid=" + uid,"contactid=" + contactid);
} // end try
catch (ClassCastException cce)
{ // we need to be able to coerce the ContactInfo to a Stashable
logger.error("ContactInfo needs to be a Stashable for this to work");
throw new DataException("improper contact information record");
} // end catch
catch (SQLException e)
{ // database error - this is a DataException
logger.error("DB error updating contact info: " + e.getMessage(),e);
throw new DataException("unable to access user contact data: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end if
} // end putContactInfo
public void setPassword(String password, String reminder) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
PasswordHash phash = new PasswordHash(password);
StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '");
sql.append(phash.toString()).append("', passreminder = '").append(SQLUtil.encodeString(reminder));
sql.append("', access_tries = 0 WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString());
// record an audit record for this user
ar = new AuditRecord(AuditRecord.ADMIN_PASSWORD_CHANGE,user.realUID(),user.userRemoteAddress(),
"uid=" + uid);
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error changing password: " + e.getMessage(),e);
throw new DataException("Unable to set user password: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setPassword
public Locale getLocale()
{
return my_locale;
} // end getLocale
public void setLocale(Locale locale) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// create the update statement
StringBuffer sql = new StringBuffer("UPDATE userprefs SET localeid = '");
sql.append(SQLUtil.encodeString(locale.toString())).append("' WHERE uid = ").append(uid).append(';');
// execute the statement
stmt.executeUpdate(sql.toString());
// replace the locale here
my_locale = locale;
ar = new AuditRecord(AuditRecord.ADMIN_ACCOUNT_CHANGE,user.realUID(),user.userRemoteAddress(),0,
"uid=" + uid,"field=localeid");
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error setting user locale: " + e.getMessage(),e);
throw new DataException("unable to set user locale: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setLocale
public TimeZone getTimeZone()
{
return my_tz;
} // end getTimeZone
public void setTimeZone(TimeZone timezone) throws DataException
{
Connection conn = null;
AuditRecord ar = null;
try
{ // retrieve a connection from the data pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// create the update statement
StringBuffer sql = new StringBuffer("UPDATE userprefs SET tzid = '");
sql.append(SQLUtil.encodeString(timezone.getID())).append("' WHERE uid = ").append(uid).append(';');
// execute the statement
stmt.executeUpdate(sql.toString());
// replace the locale here
my_tz = timezone;
ar = new AuditRecord(AuditRecord.ADMIN_ACCOUNT_CHANGE,user.realUID(),user.userRemoteAddress(),0,
"uid=" + uid,"field=tzid");
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error setting user timezone: " + e.getMessage(),e);
throw new DataException("unable to set user timezone: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setTimeZone
public java.util.Date getCreationDate()
{
return created;
} // end getCreationDate
public java.util.Date getLastAccessDate()
{
return last_access;
} // end getLastAccessDate
/*--------------------------------------------------------------------------------
* Package-level static operations
*--------------------------------------------------------------------------------
*/
static AdminUserContext getAdminUserContext(EngineBackend engine, UserBackend user, DataPool datapool,
int uid) throws DataException
{
Connection conn = null;
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users INNER JOIN userprefs "
+ "ON users.uid = userprefs.uid WHERE users.uid = " + uid + ";");
if (!(rs.next()))
throw new DataException("The user with UID #" + uid + " was not found.");
if (rs.getBoolean("is_anon"))
throw new DataException("Cannot modify the defaults for the anonymous user.");
return new AdminUserContextImpl(engine,user,datapool,rs);
} // end try
catch (SQLException e)
{ // we encountered an error!
logger.error("DB exception in getAdminUserContext: " + e.getMessage(),e);
throw new DataException("Unable to load context for user: " + e.getMessage());
} // end catch
finally
{ // release the connection where necessary
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end getAdminUserContext
static AdminUserContext getAdminUserContext(EngineBackend engine, UserBackend user, DataPool datapool,
String username) throws DataException
{
Connection conn = null;
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users INNER JOIN userprefs "
+ "ON users.uid = userprefs.uid WHERE users.username = '"
+ SQLUtil.encodeString(username) + "';");
if (!(rs.next()))
throw new DataException("The user '" + username + "' was not found.");
if (rs.getBoolean("is_anon"))
throw new DataException("Cannot modify the defaults for the anonymous user.");
return new AdminUserContextImpl(engine,user,datapool,rs);
} // end try
catch (SQLException e)
{ // we encountered an error!
logger.error("DB exception in getAdminUserContext: " + e.getMessage(),e);
throw new DataException("Unable to load context for user: " + e.getMessage());
} // end catch
finally
{ // release the connection where necessary
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end getAdminUserContext
} // end class AdminUserContextImpl
@@ -38,7 +38,7 @@ class UserContextImpl implements UserContext, UserBackend
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(UserContextImpl.class.getName());
private static Category logger = Category.getInstance(UserContextImpl.class);
private static final String AUTH_TOKEN_PREFIX = "VQAT:";
private static final char AUTH_TOKEN_SEP = '|';
@@ -66,7 +66,7 @@ class UserContextImpl implements UserContext, UserBackend
private String full_name = null; // my full name (cached)
private Locale my_locale = null; // my default locale (cached)
private TimeZone my_tz = null; // my default timezone (cached)
private Hashtable mru_cache = new Hashtable(); // MRU cache for ReferencedData objects
private HashMap mru_cache = new HashMap(); // MRU cache for ReferencedData objects
/*--------------------------------------------------------------------------------
* Constructor