james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From charl...@apache.org
Subject cvs commit: jakarta-james/src/java/org/apache/james/core AvalonUsersStore.java
Date Sun, 10 Jun 2001 13:19:57 GMT
charlesb    01/06/10 06:19:57

  Modified:    .        build.xml
               proposals/v1.3/conf james-config.xml
               proposals/v1.3/java/org/apache/james/userrepository
                        DefaultUser.java
               src/java/org/apache/james/core AvalonUsersStore.java
  Added:       lib      junit-3.2.jar mysql-2.0.4.jar
               proposals/v1.3/java/org/apache/james/userrepository
                        AbstractUsersRepository.java
                        UsersJDBCRepository.java
  Log:
  Added JDBC support for UsersStore, contributed by Darrell DeBoer
  
  Revision  Changes    Path
  1.71      +14 -0     jakarta-james/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-james/build.xml,v
  retrieving revision 1.70
  retrieving revision 1.71
  diff -u -r1.70 -r1.71
  --- build.xml	2001/05/21 12:13:15	1.70
  +++ build.xml	2001/06/10 13:19:56	1.71
  @@ -326,6 +326,7 @@
           <include name="activation.jar"/>
           <include name="mail_1_2.jar"/>
           <include name="jakarta-oro-2.0.1.jar"/>
  +        <include name="mysql-2.0.4.jar"/>
         </zipfileset>
   
         <zipfileset dir="${build.conf}" fullpath="conf/config.xml">
  @@ -685,6 +686,19 @@
     -->
     <target name="distributions" depends="dist, src-dist">
   
  +  </target>
  +
  +  <!-- 
  +       ===================================================================
  +                 Unit test targets
  +       ===================================================================
  +  -->
  +  <target name="testUserRepos">
  +    <junit printsummary="yes">
  +      <classpath refid="project.class.path"/>
  +      <formatter type="plain" usefile="no"/>
  +      <test name="org.apache.james.testing.TestUsersJDBCRepository"/>
  +    </junit>
     </target>
   
   </project>
  
  
  
  1.1                  jakarta-james/lib/junit-3.2.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-james/lib/mysql-2.0.4.jar
  
  	<<Binary file>>
  
  
  1.5       +50 -6     jakarta-james/proposals/v1.3/conf/james-config.xml
  
  Index: james-config.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/v1.3/conf/james-config.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- james-config.xml	2001/06/06 10:50:15	1.4
  +++ james-config.xml	2001/06/10 13:19:56	1.5
  @@ -488,6 +488,7 @@
          
     <!-- The User Storage block -->
     <users-store>
  +      <!-- File-based user repository  -->
         <repository name="LocalUsers"
                     class="org.apache.james.userrepository.UsersFileRepository">
           <destination URL="file://var/users/"/>
  @@ -501,14 +502,57 @@
           <table>Users</table>
         </repository>
         -->
  -      <!-- Uncomment this to store users in an RDBMS
  +      <!-- The following are examples of database connections which have been tested.
  +           Theses should provided a guide to setting up other databases as well.
  +           The driver.class and destination.URL properties are require,
  +           but destination.user and destination.password are optional. -->
  +      <!-- Mssql server with Inet Sprinta
  +            <destination>
  +                <driver class="com.inet.tds.TdsDriver"/>
  +                <datasource>
  +                    <dburl>jdbc:inetdae7:127.0.0.1?database=mail</dburl>
  +                    <user>user</user>
  +                    <password>password</password>
  +                </datasource>
  +            </destination>
  +      </repository>
  +      -->
  +      
  +      <!-- MySQL server via ODBC
         <repository name="LocalUsers"
                     class="org.apache.james.userrepository.UsersJDBCRepository">
  -        <driver class="org.gjt.mm.mysql.Driver"/>
  -        <database URL="jdbc:mysql://localhost/james">
  -        <dbUser name="james"/>
  -        <dbPassword value="james"/>
  -        <table>Users</table>
  +            <destination>
  +                <driver class="sun.jdbc.odbc.JdbcOdbcDriver"/>
  +                <datasource>
  +                    <dburl>jdbc:odbc:mail-mysql</dburl>
  +                </datasource>
  +            </destination>
  +      </repository>
  +      -->
  +      <!-- MySQL server via mm mysql driver
  +      <repository name="LocalUsers"
  +                  class="org.apache.james.userrepository.UsersJDBCRepository">
  +            <destination>
  +                <driver class="org.gjt.mm.mysql.Driver"/>
  +                <datasource>
  +                    <dburl>jdbc:mysql://127.0.0.1/mail</dburl>
  +                    <user>user</user>
  +                    <password>password</password>
  +                </datasource>
  +            </destination>
  +      </repository>
  +      -->
  +      <!-- Oracle8i server via thin driver
  +      <repository name="LocalUsers"
  +                  class="org.apache.james.userrepository.UsersJDBCRepository">
  +            <destination>
  +                <driver class="oracle.jdbc.driver.OracleDriver"/>
  +                <datasource>
  +                    <dburl>jdbc:oracle:thin:@127.0.0.1:1521:mail</dburl>
  +                    <user>user</user>
  +                    <password>password</password>
  +                </datasource>
  +            </destination>
         </repository>
         -->
   
  
  
  
  1.4       +8 -2      jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/DefaultUser.java
  
  Index: DefaultUser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/DefaultUser.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultUser.java	2001/06/07 10:39:46	1.3
  +++ DefaultUser.java	2001/06/10 13:19:57	1.4
  @@ -20,8 +20,8 @@
    *
    * @author Charles Benett <charles@benett1.demon.co.uk>
    *
  - * Last changed by: $Author: charlesb $ on $Date: 2001/06/07 10:39:46 $
  - * $Revision: 1.3 $
  + * Last changed by: $Author: charlesb $ on $Date: 2001/06/10 13:19:57 $
  + * $Revision: 1.4 $
    */
   
   public class DefaultUser implements User, Serializable {
  @@ -105,6 +105,12 @@
   	return hashedPassword;
       }
   
  +    /**
  +     * Method to access the hashing algorithm of the password.
  +     */
  +    protected String getHashAlgorithm() {
  +        return algorithm;
  +    }
   
   
   }
  
  
  
  1.1                  jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/AbstractUsersRepository.java
  
  Index: AbstractUsersRepository.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.userrepository;
  
  import java.util.*;
  import org.apache.james.services.*;
  import org.apache.avalon.framework.logger.AbstractLoggable;
  
  /**
   * A partial implementation of a Repository to store users on the File System.
   * <p>This implements common functionality found in different UsersRespository 
   * implementations, and makes it easier to create new User repositories.</p>
   *
   * @author Darrell DeBoer <dd@bigdaz.com>
   * @author Charles Benett <charles@benett1.demon.co.uk>
   */
  public abstract class AbstractUsersRepository
      extends AbstractLoggable
      implements UsersRepository
  {
      //
      // Core Abstract methods - override these for a functional UserRepository.
      //
      /**
       * Returns a list populated with all of the Users in the repository.
       * @return an <code>Iterator</code> of <code>JamesUser</code>s.
       */
      protected abstract Iterator listAllUsers();
  
      /**
       * Adds a user to the underlying Repository.
       * The user name must not clash with an existing user.
       */
      protected abstract void doAddUser(DefaultJamesUser user);
  
      /**
       * Removes a user from the underlying repository.
       * If the user doesn't exist, returns ok.
       */
      protected abstract void doRemoveUser(DefaultJamesUser user);
  
      //
      // Extended protected methods.
      // These provide very basic default implementations, which will work,
      // but may need to be overridden by subclasses for performance reasons.
      //
      /**
       * Updates a user record to match the supplied User.
       * This is a very basic, remove-then-insert implementation,
       * which should really be overridden, but will work.
       */
      protected void doUpdateUser(DefaultJamesUser user)
      {
          doRemoveUser(user);
          doAddUser(user);
      }
  
      /**
       * Produces the complete list of User names, with correct case.
       * @return a <code>List</code> of <code>String</code>s representing
       *         user names.
       */
      protected List listUserNames()
      {
          Iterator users = listAllUsers();
          List userNames = new LinkedList();
          while ( users.hasNext() ) {
              JamesUser user = (JamesUser)users.next();
              userNames.add(user.getUserName());
          }
  
          return userNames;
      }
  
      /**
       * Gets a user by name, ignoring case if specified.
       * This implementation gets the entire set of users,
       *  and scrolls through searching for one matching <code>name</code>.
       */
      protected User getUserByName(String name, boolean ignoreCase)
      {
          // Just iterate through all of the users until we find one matching.
          Iterator users = listAllUsers();
          while ( users.hasNext() ) 
          {
              JamesUser user = (JamesUser)users.next();
              String username = user.getUserName();
              if (( !ignoreCase && username.equals(name) ) ||
                  ( ignoreCase && username.equalsIgnoreCase(name) )) {
                  return user;
              }
          }
          // Not found - return null
          return null;
      }
  
      //
      // User conversion.
      //
      /**
       * This method is hackery to get JamesUser instances, regardless of what 
       * user implementation is passed.
       * Ideally, the UsersRepository interface would be updated to accept only 
       *  JamesUsers, or we could combine the 2.
       */
      protected DefaultJamesUser getJamesUser(User user)
      {
          // Return JamesUser instances directly.
          if ( user instanceof DefaultJamesUser ) {
              return (DefaultJamesUser)user;
          }
          // Build a JamesUser with a DefaultUser.
          else if ( user instanceof DefaultUser ) {
              DefaultUser defaultUser = (DefaultUser)user;
              return new DefaultJamesUser(defaultUser.getUserName(), 
                                          defaultUser.getHashedPassword(), 
                                          defaultUser.getHashAlgorithm());
          }
          // Shouldn't be any other implementations.
          else {
              throw new RuntimeException("An unknown implementation of User was found. This
implementation cannot be persisted to a UsersJDBCRepsitory.");
          }
  
      }
  
      //
      // UsersRepository interface implementation.
      //
      /**
       * Adds a user to the repository with the specified User object.
       * Users names must be unique-case-insensitive in the repository.
       *
       * @returns true if succesful, false otherwise
       * @since James 1.2.2
       */
      public boolean addUser(User user)
      {
          String username = user.getUserName();
  
          if ( containsCaseInsensitive(username) ) {
              return false;
          }
          
          doAddUser(getJamesUser(user));
          return true;
      }
  
      /**
       * Adds a user to the repository with the specified attributes.  In current
       * implementations, the Object attributes is generally a String password.
       */
      public void addUser(String name, Object attributes) 
      {
          throw new RuntimeException("Improper use of deprecated method - read javadocs");
      }
  
      /**
       * Update the repository with the specified user object. A user object
       * with this username must already exist.
       *
       * @returns true if successful.
       */
      public boolean updateUser(User user)
      {
          // Return false if it's not found.
          if ( ! contains(user.getUserName()) ) {
              return false;
          }
          else {
              doUpdateUser(getJamesUser(user));
              return true;
          }
      }
  
      /**
       * Removes a user from the repository
       */
      public void removeUser(String name)
      {
          User user = getUserByName(name);
          if ( user != null ) {
              doRemoveUser(getJamesUser(user));
          }
      }
  
      /**
       * Gets the attribute for a user.  Not clear on behavior.
       *
       * @deprecated As of James 1.2.2 . Use the {@link #getUserByName(String) getUserByName}
method.
       */
      public Object getAttributes(String name)
      {
          throw new RuntimeException("Improper use of deprecated method - read javadocs");
      }
  
      /**
       * Get the user object with the specified user name.  Return null if no
       * such user.
       *
       * @since James 1.2.2
       */
      public User getUserByName(String name)
      {
          return getUserByName(name, false);
      }
  
      /**
       * Get the user object with the specified user name. Match user naems on
       * a case insensitive basis.  Return null if no such user.
       *
       * @since James 1.2.2
       */
      public User getUserByNameCaseInsensitive(String name)
      {
          return getUserByName(name, true);
      }
  
      /**
       * Returns the user name of the user matching name on an equalsIgnoreCase
       * basis. Returns null if no match.
       */
      public String getRealName(String name)
      {
          // Get the user by name, ignoring case, and return the correct name.
          User user = getUserByName(name, true);
          if ( user == null ) {
              return null;
          }
          else {
              return user.getUserName();
          }
      }
  
      /**
       * Returns whether or not this user is in the repository
       */
      public boolean contains(String name)
      {
          User user = getUserByName(name, false);
          return ( user != null );
      }
  
      /**
       * Returns whether or not this user is in the repository. Names are
       * matched on a case insensitive basis.
       */
      public boolean containsCaseInsensitive(String name)
      {
          User user = getUserByName( name, true );
          return ( user != null );
      }
  
      /**
       * Tests a user with the appropriate attributes.  In current implementations,
       * this typically means "check the password" where a String password is passed
       * as the Object attributes.
       *
       * @deprecated As of James 1.2.2, use {@link #test(String, String) test(String name,
String password)}
       */
      public boolean test(String name, Object attributes)
      {
          throw new RuntimeException("Improper use of deprecated method - read javadocs");
      }
  
      /**
       * Test if user with name 'name' has password 'password'.
       *
       * @since James 1.2.2
       */
      public boolean test(String name, String password)
      {
          User user = getUserByName(name, false);
          if ( user == null ) {
              return false;
          }
          else {
              return user.verifyPassword(password);
          }
      }
  
      /**
       * Returns a count of the users in the repository.
       */
      public int countUsers()
      {
          List usernames = listUserNames();
          return usernames.size();
      }
  
      /**
       * List users in repository.
       *
       * @returns Iterator over a collection of Strings, each being one user in the repository.
       */
      public Iterator list()
      {
          return listUserNames().iterator();
      }
  }
  
  
  
  1.1                  jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java
  
  Index: UsersJDBCRepository.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.userrepository;
  
  import org.apache.james.services.*;
  import org.apache.mailet.MailAddress;
  import org.apache.avalon.framework.activity.*;
  import org.apache.avalon.framework.component.*;
  import org.apache.avalon.framework.configuration.*;
  import org.apache.avalon.framework.logger.*;
  import org.apache.avalon.excalibur.datasource.*;
  
  import java.sql.*;
  import java.util.*;
  
  /**
   * An implementation of a UsersRepository which is backed by a database.<br>
   * This implementation has been tested successfully on:
   * <TABLE BORDER="1" WIDTH="100%">
   * <TR><TH>Database Product</TH><TH>versions</TH><TH>drivers</TH></TR>
   * <TR><TD>MySQL Server</TD><TD>3.23</TD><TD>MM MySQL
2.0.3</TD></TR>
   * <TR><TD>MySQL Server</TD><TD>3.23</TD><TD>JDBC-ODBC
bridge</TD></TR>
   * <TR><TD>Oracle8i</TD><TD>8.1.6</TD><TD>Oracle Thin
Driver</TD></TR>
   * <TR><TD>Microsoft SQL Server</TD><TD>7</TD><TD>Inet
Sprinta</TD></TR>
   * </TABLE>
   * <br>
   * This implementation is known to fail on:
   * <TABLE BORDER="1" WIDTH="100%">
   * <TR><TH>Database Product</TH><TH>versions</TH><TH>drivers</TH></TR>
   * <TR><TD>Microsoft SQL Server</TD><TD>7</TD><TD>JDBC-ODBC
bridge.</TD></TR>
   * </TABLE>
   * 
   * @author Darrell DeBoer <dd@bigdaz.com>
   */
  public class UsersJDBCRepository extends AbstractUsersRepository
      implements UsersRepository, Loggable, Component, Configurable, Initializable
  {
      /*
      TODO
          - allow configurable SQL statements.
          - use Connection pooling and management from Avalon framework.
      */
      private String m_dbUrl;
      private String m_dbUser;
      private String m_dbPassword;
  
      private String m_tableName = "JamesUsers";
      
      // Fetches all Users from the db.
      private String m_getUsersSql = "SELECT username, pwdHash, pwdAlgorithm, useForwarding,
forwardDestination, useAlias, alias FROM " + m_tableName;
      
      // This statement guarantees that we'll get a case-insensitive match - otherwise it's
database dependent.
      private String m_userByNameCaseInsensitiveSql = m_getUsersSql + " WHERE LOWER(username)
= ?";
  
      // Insert, update and delete are not guaranteed to be case-insensitive
      // this is handled in code.
      private String m_insertUserSql = "INSERT INTO " + m_tableName + " (username, pwdHash,
pwdAlgorithm, useForwarding, forwardDestination, useAlias, alias) VALUES (?,?,?,?,?,?,?)";
      private String m_updateUserSql = "UPDATE " + m_tableName + " SET pwdHash = ?, pwdAlgorithm
= ?, useForwarding = ?, forwardDestination = ?, useAlias = ?, alias = ? WHERE username = ?";
      private String m_deleteUserSql = "DELETE FROM " + m_tableName + " WHERE username = ?";
  
      // Creates a single table with "username" the Primary Key.
      private String m_createUserTableSql = "CREATE TABLE " + m_tableName + " (username VARCHAR(50)
NOT NULL, pwdHash VARCHAR(50), pwdAlgorithm VARCHAR(20), useForwarding SMALLINT, forwardDestination
VARCHAR(250), useAlias SMALLINT, alias VARCHAR(250), PRIMARY KEY(username))";
  
      /**
       * Configures the UserRepository for JDBC access.
       * Required parameters in the config file are:
       * <UL>
       *     <LI>destination.driver.class - the class of the JDBC driver to load.</LI>
       *     <LI>destination.datasource.dburl - the database connection string.</LI>
       * </UL>
       * Optional parameters are:
       * <UL>
       *     <LI>destination.datasource.user - username to connect to the database.</LI>
       *     <LI>destination.datasource.password - password to connect to the database.</LI>
       * </UL>
       */
      public void configure(Configuration configuration) throws ConfigurationException 
      {
          // Load the driver.
  
          String driverName = configuration.getChild("destination").getChild("driver").getAttribute("class");
  	getLogger().debug("Loading driver :" + driverName);
          try {
              Class.forName(driverName);
  	    getLogger().info("Database driver " + driverName + " loaded");
          } 
          catch ( ClassNotFoundException cnfe ) {
              throw new ConfigurationException("Could not load specified driver - " + driverName);
          }
  
          // Get the database connection configuration.
          Configuration dbConfig = configuration.getChild("destination").getChild("datasource");
          m_dbUrl = dbConfig.getChild("dburl").getValue();
          m_dbUser = dbConfig.getChild("user").getValue(null);
          m_dbPassword = dbConfig.getChild("password").getValue(null);
      }
  
      /**
       * Initialises the JDBC repository.
       * 1) Tests the connection to the database.
       * 2) Initialises the database with the required tables, if necessary.
       * 
       * @exception Exception if a database access error occurs.
       */
      public void initialize() throws Exception {
          // Test the connection to the database, by getting the DatabaseMetaData.
          Connection conn = getConnection();
          try{
              DatabaseMetaData dbMetaData = conn.getMetaData();
  
              // Make sure that the Users table is there, if not create it.
  
              // Need to ask in the case that identifiers are stored, ask the DatabaseMetaInfo.
              // NB this should work, but some drivers (eg mm MySQL) 
              // don't return the right details, hence the hackery below.
              /*
              String tableName = m_tableName;
              if ( dbMetaData.storesLowerCaseIdentifiers() ) {
                  tableName = tableName.toLowerCase();
              }
              else if ( dbMetaData.storesUpperCaseIdentifiers() ) {
                  tableName = tableName.toUpperCase();
              }
              */
  
              // Try UPPER, lower, and MixedCase, to see if the table is there.
              if (! ( tableExists(dbMetaData, m_tableName) ||
                      tableExists(dbMetaData, m_tableName.toUpperCase()) ||
                      tableExists(dbMetaData, m_tableName.toLowerCase()) )) 
              {
                  // Users table doesn't exist - create it.
                  PreparedStatement createStatement = conn.prepareStatement(m_createUserTableSql);
                  createStatement.execute();
                  createStatement.close();
  		getLogger().info("Created \'JamesUsers\' table.");
                  System.out.println("UsersStore - UsersJDBCRepository : Created \'JamesUsers\'
table.");
              }
          }
          finally {
              conn.close();
          }
      }
  
      private boolean tableExists(DatabaseMetaData dbMetaData, String tableName)
          throws SQLException
      {
          ResultSet rsTables = dbMetaData.getTables(null, null, tableName, null);
          boolean found = rsTables.next();
          rsTables.close();
          return found;
      }
  
      //
      // Superclass methods.
      //
      /**
       * Returns a list populated with all of the Users in the repository.
       * @return an <code>Iterator</code> of <code>DefaultJamesUser</code>s.
       */
      protected Iterator listAllUsers() 
      {
          List userList = new LinkedList(); // Build the users into this list.
  
          Connection conn = getConnection();
          try {
              // Get a ResultSet containing all users.
              PreparedStatement getUsersStatement = 
                  getConnection().prepareStatement(m_getUsersSql);
              ResultSet rsUsers = getUsersStatement.executeQuery();
  
              // Loop through and build a JamesUser for every row.
              while ( rsUsers.next() ) {
                  DefaultJamesUser user = readUserFromResultSet(rsUsers);
                  userList.add(user);
              }
  
              rsUsers.close();
              getUsersStatement.close();
          }
          catch ( SQLException sqlExc) {
              sqlExc.printStackTrace();
              throw new RuntimeException("Error accessing database");
          }
          finally {
              try {
                  conn.close();
              }
              catch (SQLException sqlExc) {
                  sqlExc.printStackTrace();
                  throw new RuntimeException("Error closing connection");
              }
          }
  
          return userList.iterator();
      }
  
      /**
       * Adds a user to the underlying Repository.
       * The user name must not clash with an existing user.
       */
      protected void doAddUser(DefaultJamesUser user)
      {
          // Get the user details to save.
          String username = user.getUserName();
          String pwdHash = user.getHashedPassword();
          String pwdAlgorithm = user.getHashAlgorithm();
          boolean useForwarding = user.getForwarding();
          MailAddress forwardAddress = user.getForwardingDestination();
          String forwardDestination = null;
          if ( forwardAddress != null ) {
              forwardDestination = forwardAddress.toString();
          }
          boolean useAlias = user.getAliasing();
          String alias = user.getAlias();
  
          Connection conn = getConnection();
  
          // Insert into the database.
          try {
              PreparedStatement addUserStatement = conn.prepareStatement(m_insertUserSql);
              
              addUserStatement.setString(1, username);
              addUserStatement.setString(2, pwdHash);
              addUserStatement.setString(3, pwdAlgorithm);
              addUserStatement.setBoolean(4, useForwarding);
              addUserStatement.setString(5, forwardDestination);
              addUserStatement.setBoolean(6, useAlias);
              addUserStatement.setString(7, alias);
  
              addUserStatement.execute();
  
              addUserStatement.close();
          }
          catch ( SQLException sqlExc ) {
              sqlExc.printStackTrace();
              throw new RuntimeException("Error accessing database");
          }
          finally {
              try {
                  conn.close();
              }
              catch (SQLException sqlExc) {
                  sqlExc.printStackTrace();
                  throw new RuntimeException("Error closing connection");
              }
          }
      }
  
      /**
       * Removes a user from the underlying repository.
       * If the user doesn't exist, returns ok.
       */
      protected void doRemoveUser(DefaultJamesUser user)
      {
          String username = user.getUserName();
  
          Connection conn = getConnection();
          // Delete from the database.
          try {
              PreparedStatement removeUserStatement = conn.prepareStatement(m_deleteUserSql);
              removeUserStatement.setString(1, username);
              removeUserStatement.execute();
              removeUserStatement.close();
          }
          catch ( SQLException sqlExc ) {
              sqlExc.printStackTrace();
              throw new RuntimeException("Error accessing database");
          }
          finally {
              try {
                  conn.close();
              }
              catch (SQLException sqlExc) {
                  sqlExc.printStackTrace();
                  throw new RuntimeException("Error closing connection");
              }
          }
      }
  
      /**
       * Gets a user by name, ignoring case if specified.
       * This overrides the basic implementation in AbstractUsersRepository
       * to increase performance.
       */
      protected User getUserByName(String name, boolean ignoreCase)
      {
          // Always get the user via case-insensitive SQL,
          // then check case if necessary.
          Connection conn = getConnection();
          try {
              // Get a ResultSet containing all users.
              String sql = m_userByNameCaseInsensitiveSql;
              PreparedStatement getUsersStatement = 
                  getConnection().prepareStatement(sql);
  
              getUsersStatement.setString(1, name.toLowerCase());
  
              ResultSet rsUsers = getUsersStatement.executeQuery();
  
              // For case-insensitive matching, the first matching user will be returned.
              DefaultJamesUser user = null;
              while ( rsUsers.next() ) {
                  DefaultJamesUser rowUser = readUserFromResultSet(rsUsers);
                  String actualName = rowUser.getUserName();
                      
                  // Check case before we assume it's the right one.
                  if ( ignoreCase || actualName.equals(name) ) {
                      user = rowUser;
                      break;
                  }
              }
              return user;
          }
          catch ( SQLException sqlExc ) {
              sqlExc.printStackTrace();
              throw new RuntimeException("Error accessing database");
          }
          finally {
              try {
                  conn.close();
              }
              catch (SQLException sqlExc) {
                  sqlExc.printStackTrace();
                  throw new RuntimeException("Error closing connection");
              }
          }
      }
  
      /**
       * Updates a user record to match the supplied User.
       * This is a very basic, remove-then-insert implementation,
       * which should really be overridden, but will work.
       */
      protected void doUpdateUser(DefaultJamesUser user)
      {
          // Get the user details to save.
          String username = user.getUserName();
          String pwdHash = user.getHashedPassword();
          String pwdAlgorithm = user.getHashAlgorithm();
          boolean useForwarding = user.getForwarding();
          MailAddress forwardAddress = user.getForwardingDestination();
          String forwardDestination = null;
          if ( forwardAddress != null ) {
              forwardDestination = forwardAddress.toString();
          }
          boolean useAlias = user.getAliasing();
          String alias = user.getAlias();
  
          Connection conn = getConnection();
  
          // Insert into the database.
          try {
              PreparedStatement updateUserStatement = conn.prepareStatement(m_updateUserSql);
              
              updateUserStatement.setString(1, pwdHash);
              updateUserStatement.setString(2, pwdAlgorithm);
              updateUserStatement.setBoolean(3, useForwarding);
              updateUserStatement.setString(4, forwardDestination);
              updateUserStatement.setBoolean(5, useAlias);
              updateUserStatement.setString(6, alias);
              updateUserStatement.setString(7, username);
  
              updateUserStatement.execute();
  
              updateUserStatement.close();
          }
          catch ( SQLException sqlExc ) {
              sqlExc.printStackTrace();
              throw new RuntimeException("Error accessing database");
          }
          finally {
              try {
                  conn.close();
              }
              catch (SQLException sqlExc) {
                  sqlExc.printStackTrace();
                  throw new RuntimeException("Error closing connection");
              }
          }
      }
  
      //
      // Private methods
      //
      /**
       * Opens a database connection.
       */
      private Connection getConnection()
      {
          try {
              if ( m_dbUser == null ) {
                  return DriverManager.getConnection(m_dbUrl);
              }
              else {
                  return DriverManager.getConnection(m_dbUrl, m_dbUser, m_dbPassword);
              }
          }
          catch ( SQLException sqlExc ) {
              sqlExc.printStackTrace();
              throw new RuntimeException("Error connecting to database");
          }
      }
  
      /**
       * Reads a user from the current row in a ResultSet.
       */
      private DefaultJamesUser readUserFromResultSet(ResultSet rsUsers)
          throws SQLException
      {
          // Get the column values
          String username = rsUsers.getString(1);
          String pwdHash = rsUsers.getString(2);
          String pwdAlgorithm = rsUsers.getString(3);
          boolean useForwarding = rsUsers.getBoolean(4);
          String forwardingDestination = rsUsers.getString(5);
          boolean useAlias = rsUsers.getBoolean(6);
          String alias = rsUsers.getString(7);
  
          MailAddress forwardAddress = null;
          if ( forwardingDestination != null ) {
              try {
                  forwardAddress = new MailAddress(forwardingDestination);
              }
              catch (javax.mail.internet.ParseException pe) {
                  throw new RuntimeException("Invalid mail address in database: " + forwardingDestination
+ ", for user " + username + ".");
              }
          }
  
          // Build a DefaultJamesUser with these values, and add to the list.
          DefaultJamesUser user = new DefaultJamesUser(username, pwdHash, pwdAlgorithm);
          user.setForwarding(useForwarding);
          user.setForwardingDestination(forwardAddress);
          user.setAliasing(useAlias);
          user.setAlias(alias);
  
          return user;
      }
  }
  
  
  
  1.2       +1 -0      jakarta-james/src/java/org/apache/james/core/AvalonUsersStore.java
  
  Index: AvalonUsersStore.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/core/AvalonUsersStore.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AvalonUsersStore.java	2001/05/11 09:15:43	1.1
  +++ AvalonUsersStore.java	2001/06/10 13:19:57	1.2
  @@ -59,6 +59,7 @@
               String repName = repConf.getAttribute("name");
               String repClass = repConf.getAttribute("class");
   
  +	    getLogger().debug("Starting " + repClass);
               UsersRepository rep = (UsersRepository) Class.forName(repClass).newInstance();
   
               setupLogger((Component)rep);
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Mime
View raw message