org.apache.wiki.auth.user
Class JDBCUserDatabase

java.lang.Object
  extended by org.apache.wiki.auth.user.AbstractUserDatabase
      extended by org.apache.wiki.auth.user.JDBCUserDatabase
All Implemented Interfaces:
UserDatabase

public class JDBCUserDatabase
extends AbstractUserDatabase

Implementation of UserDatabase that persists DefaultUserProfile objects to a JDBC DataSource, as might typically be provided by a web container. This implementation looks up the JDBC DataSource using JNDI. The JNDI name of the datasource, backing table and mapped columns used by this class can be overridden by adding settings in jspwiki.properties.

Configurable properties are these:

Property Default Definition
jspwiki.userdatabase.datasource jdbc/UserDatabase The JNDI name of the DataSource
jspwiki.userdatabase.table users The table that stores the user profiles
jspwiki.userdatabase.attributes attributes The CLOB column containing the profile's custom attributes, stored as key/value strings, each separated by newline.
jspwiki.userdatabase.created created The column containing the profile's creation timestamp
jspwiki.userdatabase.email email The column containing the user's e-mail address
jspwiki.userdatabase.fullName full_name The column containing the user's full name
jspwiki.userdatabase.loginName login_name The column containing the user's login id
jspwiki.userdatabase.password password The column containing the user's password
jspwiki.userdatabase.modified modified The column containing the profile's last-modified timestamp
jspwiki.userdatabase.uid uid The column containing the profile's unique identifier, as a long integer
jspwiki.userdatabase.wikiName wiki_name The column containing the user's wiki name
jspwiki.userdatabase.lockExpiry lock_expiry The column containing the date/time when the profile, if locked, should be unlocked.
jspwiki.userdatabase.roleTable roles The table that stores user roles. When a new user is created, a new record is inserted containing user's initial role. The table will have an ID column whose name and values correspond to the contents of the user table's login name column. It will also contain a role column (see next row).
jspwiki.userdatabase.role role The column in the role table that stores user roles. When a new user is created, this column will be populated with the value Authenticated. Once created, JDBCUserDatabase does not use this column again; it is provided strictly for the convenience of container-managed authentication services.

This class hashes passwords using SHA-1. All of the underying SQL commands used by this class are implemented using prepared statements, so it is immune to SQL injection attacks.

This class is typically used in conjunction with a web container's JNDI resource factory. For example, Tomcat provides a basic JNDI factory for registering DataSources. To give JSPWiki access to the JNDI resource named by , you would declare the datasource resource similar to this:

<Context ...>
  ...
  <Resource name="jdbc/UserDatabase" auth="Container"
    type="javax.sql.DataSource" username="dbusername" password="dbpassword"
    driverClassName="org.hsql.jdbcDriver" url="jdbc:HypersonicSQL:database"
    maxActive="8" maxIdle="4"/>
 ...
</Context>

To configure JSPWiki to use JDBC support, first create a database with a structure similar to that provided by the HSQL and PostgreSQL scripts in src/main/config/db. If you have different table or column names you can either alias them with a database view and have JSPWiki use the views, or alter the WEB-INF/jspwiki.properties file: the jspwiki.userdatabase.* and jspwiki.groupdatabase.* properties change the names of the tables and columns that JSPWiki uses.

A JNDI datasource (named jdbc/UserDatabase by default but can be configured in the jspwiki.properties file) will need to be created in your servlet container. JDBC driver JARs should be added, e.g. in Tomcat's lib directory. For more Tomcat JNDI configuration examples, see http://tomcat.apache.org/tomcat-7.0-doc/jndi-resources-howto.html. Once done, restart JSPWiki in the servlet container for it to read the new properties and switch to JDBC authentication.

JDBCUserDatabase commits changes as transactions if the back-end database supports them. If the database supports transactions, user profile changes are saved to permanent storage only when the AbstractUserDatabase.commit() method is called. If the database does not support transactions, then changes are made immediately (during the save(UserProfile) method), and the AbstractUserDatabase.commit() method no-ops. Thus, callers should always call the AbstractUserDatabase.commit() method after saving a profile to guarantee that changes are applied.

Since:
2.3

Field Summary
static String DEFAULT_DB_ATTRIBUTES
           
static String DEFAULT_DB_CREATED
           
static String DEFAULT_DB_EMAIL
           
static String DEFAULT_DB_FULL_NAME
           
static String DEFAULT_DB_JNDI_NAME
           
static String DEFAULT_DB_LOCK_EXPIRY
           
static String DEFAULT_DB_LOGIN_NAME
           
static String DEFAULT_DB_MODIFIED
           
static String DEFAULT_DB_PASSWORD
           
static String DEFAULT_DB_ROLE
           
static String DEFAULT_DB_ROLE_TABLE
           
static String DEFAULT_DB_TABLE
           
static String DEFAULT_DB_UID
           
static String DEFAULT_DB_WIKI_NAME
           
static String PROP_DB_ATTRIBUTES
           
static String PROP_DB_CREATED
           
static String PROP_DB_DATASOURCE
           
static String PROP_DB_EMAIL
           
static String PROP_DB_FULL_NAME
           
static String PROP_DB_LOCK_EXPIRY
           
static String PROP_DB_LOGIN_NAME
           
static String PROP_DB_MODIFIED
           
static String PROP_DB_PASSWORD
           
static String PROP_DB_ROLE
           
static String PROP_DB_ROLE_TABLE
           
static String PROP_DB_TABLE
           
static String PROP_DB_UID
           
static String PROP_DB_WIKI_NAME
           
 
Fields inherited from class org.apache.wiki.auth.user.AbstractUserDatabase
log, SHA_PREFIX, SSHA_PREFIX
 
Constructor Summary
JDBCUserDatabase()
           
 
Method Summary
 void deleteByLoginName(String loginName)
          Looks up and deletes the first UserProfile in the user database that matches a profile having a given login name.
 UserProfile findByEmail(String index)
          Looks up and returns the first UserProfile in the user database that matches a profile having a given e-mail address.
 UserProfile findByFullName(String index)
          Looks up and returns the first UserProfile in the user database that matches a profile having a given full name.
 UserProfile findByLoginName(String index)
          Looks up and returns the first UserProfile in the user database that matches a profile having a given login name.
 UserProfile findByUid(String uid)
          Looks up and returns the first UserProfile in the user database that matches a profile having a given unique ID (uid).
 UserProfile findByWikiName(String index)
          Looks up and returns the first UserProfile in the user database that matches a profile having a given wiki name.
 Principal[] getWikiNames()
          Returns all WikiNames that are stored in the UserDatabase as an array of WikiPrincipal objects.
 void initialize(WikiEngine engine, Properties props)
          Initializes the user database based on values from a Properties object.
 void rename(String loginName, String newName)
          Renames a UserProfile in the user database by changing the profile's login name.
 void save(UserProfile profile)
           Saves a UserProfileto the user database, overwriting the existing profile if it exists.
 
Methods inherited from class org.apache.wiki.auth.user.AbstractUserDatabase
commit, find, generateUid, getHash, getOldHash, getPrincipals, newProfile, parseLong, validatePassword
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_DB_ATTRIBUTES

public static final String DEFAULT_DB_ATTRIBUTES
See Also:
Constant Field Values

DEFAULT_DB_CREATED

public static final String DEFAULT_DB_CREATED
See Also:
Constant Field Values

DEFAULT_DB_EMAIL

public static final String DEFAULT_DB_EMAIL
See Also:
Constant Field Values

DEFAULT_DB_FULL_NAME

public static final String DEFAULT_DB_FULL_NAME
See Also:
Constant Field Values

DEFAULT_DB_JNDI_NAME

public static final String DEFAULT_DB_JNDI_NAME
See Also:
Constant Field Values

DEFAULT_DB_LOCK_EXPIRY

public static final String DEFAULT_DB_LOCK_EXPIRY
See Also:
Constant Field Values

DEFAULT_DB_MODIFIED

public static final String DEFAULT_DB_MODIFIED
See Also:
Constant Field Values

DEFAULT_DB_ROLE

public static final String DEFAULT_DB_ROLE
See Also:
Constant Field Values

DEFAULT_DB_ROLE_TABLE

public static final String DEFAULT_DB_ROLE_TABLE
See Also:
Constant Field Values

DEFAULT_DB_TABLE

public static final String DEFAULT_DB_TABLE
See Also:
Constant Field Values

DEFAULT_DB_LOGIN_NAME

public static final String DEFAULT_DB_LOGIN_NAME
See Also:
Constant Field Values

DEFAULT_DB_PASSWORD

public static final String DEFAULT_DB_PASSWORD
See Also:
Constant Field Values

DEFAULT_DB_UID

public static final String DEFAULT_DB_UID
See Also:
Constant Field Values

DEFAULT_DB_WIKI_NAME

public static final String DEFAULT_DB_WIKI_NAME
See Also:
Constant Field Values

PROP_DB_ATTRIBUTES

public static final String PROP_DB_ATTRIBUTES
See Also:
Constant Field Values

PROP_DB_CREATED

public static final String PROP_DB_CREATED
See Also:
Constant Field Values

PROP_DB_EMAIL

public static final String PROP_DB_EMAIL
See Also:
Constant Field Values

PROP_DB_FULL_NAME

public static final String PROP_DB_FULL_NAME
See Also:
Constant Field Values

PROP_DB_DATASOURCE

public static final String PROP_DB_DATASOURCE
See Also:
Constant Field Values

PROP_DB_LOCK_EXPIRY

public static final String PROP_DB_LOCK_EXPIRY
See Also:
Constant Field Values

PROP_DB_LOGIN_NAME

public static final String PROP_DB_LOGIN_NAME
See Also:
Constant Field Values

PROP_DB_MODIFIED

public static final String PROP_DB_MODIFIED
See Also:
Constant Field Values

PROP_DB_PASSWORD

public static final String PROP_DB_PASSWORD
See Also:
Constant Field Values

PROP_DB_UID

public static final String PROP_DB_UID
See Also:
Constant Field Values

PROP_DB_ROLE

public static final String PROP_DB_ROLE
See Also:
Constant Field Values

PROP_DB_ROLE_TABLE

public static final String PROP_DB_ROLE_TABLE
See Also:
Constant Field Values

PROP_DB_TABLE

public static final String PROP_DB_TABLE
See Also:
Constant Field Values

PROP_DB_WIKI_NAME

public static final String PROP_DB_WIKI_NAME
See Also:
Constant Field Values
Constructor Detail

JDBCUserDatabase

public JDBCUserDatabase()
Method Detail

deleteByLoginName

public void deleteByLoginName(String loginName)
                       throws NoSuchPrincipalException,
                              WikiSecurityException
Looks up and deletes the first UserProfile in the user database that matches a profile having a given login name. If the user database does not contain a user with a matching attribute, throws a NoSuchPrincipalException. This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state appropriately. Implementing classes that persist to the file system may wish to make this method synchronized.

Parameters:
loginName - the login name of the user profile that shall be deleted
Throws:
NoSuchPrincipalException
WikiSecurityException

findByEmail

public UserProfile findByEmail(String index)
                        throws NoSuchPrincipalException
Description copied from class: AbstractUserDatabase
Looks up and returns the first UserProfile in the user database that matches a profile having a given e-mail address. If the user database does not contain a user with a matching attribute, throws a NoSuchPrincipalException.

Specified by:
findByEmail in interface UserDatabase
Specified by:
findByEmail in class AbstractUserDatabase
Parameters:
index - the e-mail address of the desired user profile
Returns:
the user profile
Throws:
NoSuchPrincipalException
See Also:
UserDatabase.findByEmail(java.lang.String)

findByFullName

public UserProfile findByFullName(String index)
                           throws NoSuchPrincipalException
Description copied from class: AbstractUserDatabase
Looks up and returns the first UserProfile in the user database that matches a profile having a given full name. If the user database does not contain a user with a matching attribute, throws a NoSuchPrincipalException.

Specified by:
findByFullName in interface UserDatabase
Specified by:
findByFullName in class AbstractUserDatabase
Parameters:
index - the fill name of the desired user profile
Returns:
the user profile
Throws:
NoSuchPrincipalException
See Also:
UserDatabase.findByFullName(java.lang.String)

findByLoginName

public UserProfile findByLoginName(String index)
                            throws NoSuchPrincipalException
Description copied from class: AbstractUserDatabase
Looks up and returns the first UserProfile in the user database that matches a profile having a given login name. If the user database does not contain a user with a matching attribute, throws a NoSuchPrincipalException.

Specified by:
findByLoginName in interface UserDatabase
Specified by:
findByLoginName in class AbstractUserDatabase
Parameters:
index - the login name of the desired user profile
Returns:
the user profile
Throws:
NoSuchPrincipalException
See Also:
UserDatabase.findByLoginName(java.lang.String)

findByUid

public UserProfile findByUid(String uid)
                      throws NoSuchPrincipalException
Description copied from interface: UserDatabase
Looks up and returns the first UserProfile in the user database that matches a profile having a given unique ID (uid). If the user database does not contain a user with a unique ID, it throws a NoSuchPrincipalException.

Parameters:
uid - the unique identifier of the desired user profile
Returns:
the user profile
Throws:
NoSuchPrincipalException
See Also:
UserDatabase.findByWikiName(String)

findByWikiName

public UserProfile findByWikiName(String index)
                           throws NoSuchPrincipalException
Description copied from class: AbstractUserDatabase
Looks up and returns the first UserProfile in the user database that matches a profile having a given wiki name. If the user database does not contain a user with a matching attribute, throws a NoSuchPrincipalException.

Specified by:
findByWikiName in interface UserDatabase
Specified by:
findByWikiName in class AbstractUserDatabase
Parameters:
index - the wiki name of the desired user profile
Returns:
the user profile
Throws:
NoSuchPrincipalException
See Also:
UserDatabase.findByWikiName(String)

getWikiNames

public Principal[] getWikiNames()
                         throws WikiSecurityException
Returns all WikiNames that are stored in the UserDatabase as an array of WikiPrincipal objects. If the database does not contain any profiles, this method will return a zero-length array.

Returns:
the WikiNames
Throws:
WikiSecurityException

initialize

public void initialize(WikiEngine engine,
                       Properties props)
                throws NoRequiredPropertyException,
                       WikiSecurityException
Description copied from class: AbstractUserDatabase
Initializes the user database based on values from a Properties object.

Specified by:
initialize in interface UserDatabase
Specified by:
initialize in class AbstractUserDatabase
Throws:
NoRequiredPropertyException
WikiSecurityException
See Also:
UserDatabase.initialize(org.apache.wiki.WikiEngine, java.util.Properties)

rename

public void rename(String loginName,
                   String newName)
            throws NoSuchPrincipalException,
                   DuplicateUserException,
                   WikiSecurityException
Description copied from interface: UserDatabase

Renames a UserProfile in the user database by changing the profile's login name. Because the login name is the profile's unique identifier, implementations should verify that the identifier is "safe" to change before actually changing it. Specifically: the profile with the supplied login name must already exist, and the proposed new name must not be in use by another profile.

This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state appropriately. Implementing classes that persist to the file system may wish to make this method synchronized.

Parameters:
loginName - the existing login name for the profile
newName - the proposed new login name
Throws:
NoSuchPrincipalException - if the user profile identified by loginName does not exist
DuplicateUserException - if another user profile with the proposed new login name already exists
WikiSecurityException - if the profile cannot be renamed for any reason, such as an I/O error, database connection failure or lack of support for renames.
See Also:
UserDatabase.rename(String, String)

save

public void save(UserProfile profile)
          throws WikiSecurityException
Description copied from class: AbstractUserDatabase

Saves a UserProfileto the user database, overwriting the existing profile if it exists. The user name under which the profile should be saved is returned by the supplied profile's UserProfile.getLoginName() method.

The database implementation is responsible for detecting potential duplicate user profiles; specifically, the login name, wiki name, and full name must be unique. The implementation is not required to check for validity of passwords or e-mail addresses. Special case: if the profile already exists and the password is null, it should retain its previous value, rather than being set to null.

Implementations are required to time-stamp the creation or modification fields of the UserProfile./p>

This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state appropriately. Implementing classes that persist to the file system may wish to make this method synchronized.

Specified by:
save in interface UserDatabase
Specified by:
save in class AbstractUserDatabase
Parameters:
profile - the user profile to save
Throws:
WikiSecurityException - if the profile cannot be saved
See Also:
UserDatabase.save(org.apache.wiki.auth.user.UserProfile)


Copyright © {inceptionYear}-2014 The Apache Software Foundation. All rights reserved.