JResourceDS.java

00001 
00027 package org.objectweb.jonas.security.realm.factory;
00028 
00029 import java.security.NoSuchAlgorithmException;
00030 import java.sql.Connection;
00031 import java.sql.DriverManager;
00032 import java.sql.PreparedStatement;
00033 import java.sql.ResultSet;
00034 import java.sql.SQLException;
00035 import java.util.ArrayList;
00036 
00037 import javax.naming.Context;
00038 import javax.naming.InitialContext;
00039 import javax.naming.NamingException;
00040 import javax.naming.Reference;
00041 import javax.naming.StringRefAddr;
00042 import javax.sql.DataSource;
00043 
00044 import org.objectweb.jonas.dbm.ConnectionManager;
00045 import org.objectweb.jonas.security.realm.lib.HashHelper;
00046 import org.objectweb.jonas.security.realm.principals.User;
00047 
00048 import org.objectweb.util.monolog.api.BasicLevel;
00049 
00054 public class JResourceDS extends JResource implements JResourceDSMBean {
00055 
00059     private static final String FACTORY_TYPE = "org.objectweb.jonas.security.realm.factory.JResourceDS";
00060 
00064     private static final String FACTORY_NAME = "org.objectweb.jonas.security.realm.factory.JResourceDSFactory";
00065 
00069     private String dsName = null;
00070 
00074     private String userTable = null;
00075 
00079     private String userTableUsernameCol = null;
00080 
00084     private String userTablePasswordCol = null;
00085 
00089     private String roleTable = null;
00090 
00094     private String roleTableUsernameCol = null;
00095 
00099     private String roleTableRolenameCol = null;
00100 
00104     private String algorithm = null;
00105 
00109     private DataSource dataSource = null;
00110 
00114     private String userPrincipalsQuery = null;
00115 
00119     private String userRolesQuery = null;
00120 
00125     public JResourceDS() throws Exception {
00126         super();
00127 
00128     }
00129 
00134     public void setDsName(String dsName) {
00135         this.dsName = dsName;
00136     }
00137 
00142     public void setUserTable(String userTable) {
00143         this.userTable = userTable;
00144     }
00145 
00151     public void setUserTableUsernameCol(String userTableUsernameCol) {
00152         this.userTableUsernameCol = userTableUsernameCol;
00153     }
00154 
00160     public void setUserTablePasswordCol(String userTablePasswordCol) {
00161         this.userTablePasswordCol = userTablePasswordCol;
00162     }
00163 
00168     public void setRoleTable(String roleTable) {
00169         this.roleTable = roleTable;
00170     }
00171 
00177     public void setRoleTableUsernameCol(String roleTableUsernameCol) {
00178         this.roleTableUsernameCol = roleTableUsernameCol;
00179     }
00180 
00186     public void setRoleTableRolenameCol(String roleTableRolenameCol) {
00187         this.roleTableRolenameCol = roleTableRolenameCol;
00188     }
00189 
00194     public void setAlgorithm(String algorithm) {
00195         this.algorithm = algorithm;
00196     }
00197 
00203     public void setUserPrincipalsQuery(String userPrincipalsQuery) {
00204         this.userPrincipalsQuery = userPrincipalsQuery;
00205     }
00206 
00211     public void setUserRolesQuery(String userRolesQuery) {
00212         this.userRolesQuery = userRolesQuery;
00213     }
00214 
00219     public String getDsName() {
00220         return dsName;
00221     }
00222 
00227     public String getUserTable() {
00228         return userTable;
00229     }
00230 
00235     public String getUserTableUsernameCol() {
00236         return userTableUsernameCol;
00237     }
00238 
00243     public String getUserTablePasswordCol() {
00244         return userTablePasswordCol;
00245     }
00246 
00251     public String getRoleTable() {
00252         return roleTable;
00253     }
00254 
00259     public String getRoleTableUsernameCol() {
00260         return roleTableUsernameCol;
00261     }
00262 
00267     public String getRoleTableRolenameCol() {
00268         return roleTableRolenameCol;
00269     }
00270 
00275     public String getAlgorithm() {
00276         return algorithm;
00277     }
00278 
00283     public String setUserPrincipalsQuery() {
00284         return userPrincipalsQuery;
00285     }
00286 
00291     public String setUserRolesQuery() {
00292         return userRolesQuery;
00293     }
00294 
00301     public User findUser(String username) throws JResourceException {
00302 
00303         if (username == null) {
00304             return null;
00305         }
00306 
00307         // Build new user
00308         User user = new User();
00309 
00310         Connection connection = getConnection();
00311 
00312         user.setName(username);
00313 
00314         // Get the password of the user
00315         ResultSet rs = null;
00316         String password = null;
00317         try {
00318             PreparedStatement usrStmt = userStatement(connection, username);
00319             rs = usrStmt.executeQuery();
00320             if (rs == null || !rs.next()) {
00321                 throw new JResourceException("No user found with username '" + username + "'.");
00322             }
00323 
00324             int records = rs.getRow();
00325             if (records > 1) {
00326                 getLogger().log(BasicLevel.ERROR, "There are more than one user with the name" + username);
00327             }
00328             password = rs.getString(1).trim();
00329             rs.close();
00330             usrStmt.close();
00331         } catch (SQLException sqle) {
00332             closeConnection(connection);
00333             throw new JResourceException(sqle.getMessage());
00334         }
00335 
00336         if (password == null) {
00337             closeConnection(connection);
00338             return null;
00339         }
00340         user.setPassword(password);
00341 
00342         // Get the roles of the user
00343         try {
00344             PreparedStatement rlStmt = roleStatement(connection, username);
00345             rs = rlStmt.executeQuery();
00346 
00347             while (rs.next()) {
00348                 String role = rs.getString(1).trim();
00349                 user.addRole(role);
00350             }
00351             rs.close();
00352             rlStmt.close();
00353         } catch (SQLException sqle) {
00354             closeConnection(connection);
00355             throw new JResourceException(sqle.getMessage());
00356         }
00357 
00358         // Commit the connection if it is not automatic
00359         try {
00360             if (!connection.getAutoCommit()) {
00361                 connection.commit();
00362             }
00363         } catch (SQLException sqle) {
00364             getLogger().log(BasicLevel.DEBUG, "Cannot commit on the current connection :  : '"
00365                             + sqle.getMessage() + "'");
00366         }
00367         closeConnection(connection);
00368         return user;
00369     }
00370 
00377     public boolean isValidUser(User user, String credentials) {
00378 
00379         boolean validated = false;
00380 
00381         //Get algorithm and hashpassword
00382         String pass = user.getHashPassword().getPassword();
00383         String algo = user.getHashPassword().getAlgorithm();
00384 
00385         // Crypt password ?
00386         if (algo != null) {
00387             try {
00388                 validated = HashHelper.hashPassword(credentials, algo)
00389                         .equalsIgnoreCase(pass);
00390             } catch (NoSuchAlgorithmException nsae) {
00391                 getLogger().log(
00392                         BasicLevel.ERROR,
00393                         "Can't make a password with the algorithm " + algo
00394                                 + ". " + nsae.getMessage());
00395             }
00396         } else if ((algorithm != null) && (!algorithm.equals(""))) {
00397             // Encode password with the specified algorithm (no clear)
00398             try {
00399                 validated = HashHelper.hashPassword(credentials, algorithm)
00400                         .equalsIgnoreCase(pass);
00401             } catch (NoSuchAlgorithmException nsae) {
00402                 getLogger().log(
00403                         BasicLevel.ERROR,
00404                         "Can't make a password with the algorithm " + algorithm
00405                                 + ". " + nsae.getMessage());
00406             }
00407         } else {
00408             // clear password
00409             validated = credentials.equals(pass);
00410         }
00411         return validated;
00412     }
00413 
00420     public ArrayList getArrayListCombinedRoles(User user)
00421             throws JResourceException {
00422 
00423         ArrayList allCombinedRoles = new ArrayList();
00424 
00425         // Return empty array if user null
00426         if (user == null) {
00427             return allCombinedRoles;
00428         }
00429         // Add all user roles
00430         String[] userRoles = user.getArrayRoles();
00431         for (int r = 0; r < userRoles.length; r++) {
00432             String roleName = userRoles[r];
00433             if (!allCombinedRoles.contains(roleName)) {
00434                 allCombinedRoles.add(roleName);
00435             }
00436         }
00437         user.setCombinedRoles(allCombinedRoles);
00438 
00439         return allCombinedRoles;
00440     }
00441 
00446     public String toXML() {
00447         StringBuffer xml = new StringBuffer("    <dsrealm name=\"");
00448         xml.append(getName());
00449         xml.append("\"\n             dsName=\"");
00450         if (dsName != null) {
00451             xml.append(dsName);
00452         }
00453         xml.append("\"\n             userTable=\"");
00454         if (userTable != null) {
00455             xml.append(userTable);
00456         }
00457         xml.append("\" userTableUsernameCol=\"");
00458         if (userTableUsernameCol != null) {
00459             xml.append(userTableUsernameCol);
00460         }
00461         xml.append("\" userTablePasswordCol=\"");
00462         if (userTablePasswordCol != null) {
00463             xml.append(userTablePasswordCol);
00464         }
00465         xml.append("\"\n             roleTable=\"");
00466         if (roleTable != null) {
00467             xml.append(roleTable);
00468         }
00469         xml.append("\" roleTableUsernameCol=\"");
00470         if (roleTableUsernameCol != null) {
00471             xml.append(roleTableUsernameCol);
00472         }
00473         xml.append("\" roleTableRolenameCol=\"");
00474         if (roleTableRolenameCol != null) {
00475             xml.append(roleTableRolenameCol);
00476         }
00477 
00478         if ((userPrincipalsQuery != null) && (!userPrincipalsQuery.equals(""))) {
00479             xml.append("\"\n             userPrincipalsQuery=\"");
00480             xml.append(userPrincipalsQuery);
00481         }
00482 
00483         if ((userRolesQuery != null) && (!userRolesQuery.equals(""))) {
00484             xml.append("\"\n             userRolesQuery=\"");
00485             xml.append(userRolesQuery);
00486         }
00487 
00488         if ((algorithm != null) && (!algorithm.equals(""))) {
00489             xml.append("\"\n             algorithm=\"");
00490             xml.append(algorithm);
00491         }
00492 
00493         xml.append("\" />");
00494         return xml.toString();
00495     }
00496 
00501     public String toString() {
00502         return this.toXML();
00503     }
00504 
00513     public Reference getReference() throws NamingException {
00514 
00515         // Build the reference to the factory FACTORY_TYPE
00516         Reference reference = new Reference(FACTORY_TYPE, FACTORY_NAME, null);
00517 
00518         // Add ref addr
00519         reference.add(new StringRefAddr("name", getName()));
00520         reference.add(new StringRefAddr("dsName", dsName));
00521         reference.add(new StringRefAddr("userTable", userTable));
00522         reference.add(new StringRefAddr("userTableUsernameCol",
00523                 userTableUsernameCol));
00524         reference.add(new StringRefAddr("userTablePasswordCol",
00525                 userTablePasswordCol));
00526         reference.add(new StringRefAddr("roleTable", roleTable));
00527         reference.add(new StringRefAddr("roleTableUsernameCol",
00528                 roleTableUsernameCol));
00529         reference.add(new StringRefAddr("roleTableRolenameCol",
00530                 roleTableRolenameCol));
00531         reference.add(new StringRefAddr("userPrincipalsQuery",
00532                 userPrincipalsQuery));
00533         reference.add(new StringRefAddr("userRolesQuery", userRolesQuery));
00534         reference.add(new StringRefAddr("algorithm", algorithm));
00535 
00536         return reference;
00537     }
00538 
00543     private void closeConnection(Connection c) {
00544         if (c == null) {
00545             return;
00546         }
00547         try {
00548             c.close();
00549         } catch (Exception e) {
00550             getLogger().log(BasicLevel.DEBUG, "Can not close the connection");
00551         }
00552 
00553     }
00554 
00561     private Connection getConnection() throws JResourceException {
00562 
00563         // If no dataSource, get an instance
00564         if (dataSource == null) {
00565             // Finds DataSource from JNDI
00566             Context initialContext = null;
00567             try {
00568                 initialContext = new InitialContext();
00569                 dataSource = (DataSource) initialContext.lookup(dsName);
00570             } catch (Exception e) {
00571                 String err = "Could not found resource " + dsName
00572                         + " in the registry" + e.getMessage();
00573                 getLogger().log(BasicLevel.ERROR, err);
00574                 throw new JResourceException(err);
00575             }
00576         }
00577 
00578         Connection c = null;
00579 
00580         // Check if the request come from a client or inside the server
00581         // Required until a dbm datasource can be called from a client
00582         if (dataSource instanceof ConnectionManager) {
00583             ConnectionManager cm = (ConnectionManager) dataSource;
00584             // Client or server case ?
00585             if (cm.isClientCase()) {
00586                 // Build a JDBC connection with getting parameters from the object
00587                 // ConnectionManager
00588                 try {
00589                     // Load driver
00590                     Class.forName(cm.getClassName());
00591                     // create the connection
00592                     c = DriverManager.getConnection(cm.getUrl(), cm.getUserName(),
00593                             cm.getPassword());
00594                 } catch (Exception de) {
00595                     getLogger().log(BasicLevel.ERROR, de.getMessage());
00596                     throw new JResourceException(
00597                             "Can not build a connection using the jdbc parameters :"
00598                                     + de.getMessage());
00599                 }
00600             }
00601         }
00602 
00603         if (c == null) {
00604             //Use the datasource
00605             // Retrieve connection from the datasource
00606             try {
00607                 c = dataSource.getConnection();
00608             } catch (SQLException sqle) {
00609                 getLogger().log(BasicLevel.ERROR, sqle.getMessage());
00610                 throw new JResourceException(sqle.getMessage());
00611             }
00612 
00613         }
00614 
00615         return c;
00616     }
00617 
00622     private String userQuery() {
00623 
00624         if (userPrincipalsQuery != null) {
00625             if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00626                 getLogger().log(
00627                         BasicLevel.DEBUG,
00628                         "Return user defined SQL query for user"
00629                                 + userPrincipalsQuery);
00630             }
00631             return userPrincipalsQuery;
00632         } else {
00633 
00634             /*
00635              * SELECT userTablePasswordCol FROM userTable WHERE
00636              * userTableUsernameCol = ?
00637              */
00638             StringBuffer stringBuffer = new StringBuffer("SELECT ");
00639             stringBuffer.append(userTablePasswordCol);
00640             stringBuffer.append(" FROM ");
00641             stringBuffer.append(userTable);
00642             stringBuffer.append(" WHERE ");
00643             stringBuffer.append(userTableUsernameCol);
00644             stringBuffer.append(" = ?");
00645             return (stringBuffer.toString());
00646         }
00647     }
00648 
00653     private String rolesOfUserQuery() {
00654 
00655         if (userRolesQuery != null) {
00656             if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00657                 getLogger().log(
00658                         BasicLevel.DEBUG,
00659                         "Return user defined SQL query for roles"
00660                                 + userRolesQuery);
00661             }
00662             return userRolesQuery;
00663         } else {
00664 
00665             /*
00666              * SELECT r.roleTableRolenameCol FROM userTable u, roleTable r WHERE
00667              * u.userTableUsernameCol = r.roleTableUsernameCol AND
00668              * u.userTableUsernameCol = ?
00669              */
00670 
00671             StringBuffer stringBuffer = new StringBuffer("SELECT r.");
00672             stringBuffer.append(roleTableRolenameCol);
00673             stringBuffer.append(" FROM ");
00674             stringBuffer.append(userTable);
00675             stringBuffer.append(" u, ");
00676             stringBuffer.append(roleTable);
00677             stringBuffer.append(" r WHERE u.");
00678             stringBuffer.append(userTableUsernameCol);
00679             stringBuffer.append(" = r.");
00680             stringBuffer.append(roleTableUsernameCol);
00681             stringBuffer.append(" AND u.");
00682             stringBuffer.append(userTableUsernameCol);
00683             stringBuffer.append(" = ?");
00684             return stringBuffer.toString();
00685         }
00686     }
00687 
00695     private PreparedStatement userStatement(Connection connection,
00696             String username) throws SQLException {
00697 
00698         if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00699             getLogger().log(BasicLevel.DEBUG,
00700                     "Creating user statement for the user '" + username + "'");
00701         }
00702 
00703         PreparedStatement userStatement = connection.prepareStatement(userQuery());
00704 
00705         userStatement.setString(1, username);
00706         return userStatement;
00707     }
00708 
00717     private PreparedStatement roleStatement(Connection connection,
00718             String username) throws SQLException {
00719 
00720         if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00721             getLogger().log(BasicLevel.DEBUG,
00722                     "Creating role statement for the user " + username + "'");
00723         }
00724         PreparedStatement roleStatement = connection.prepareStatement(rolesOfUserQuery());
00725 
00726         roleStatement.setString(1, username);
00727 
00728         return roleStatement;
00729     }
00730 
00735     public void removeMBeans() throws JResourceException {
00736         //no MBeans
00737     }
00738 
00739 }

Generated on Tue Feb 15 15:05:22 2005 for JOnAS by  doxygen 1.3.9.1