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
00308 User user = new User();
00309
00310 Connection connection = getConnection();
00311
00312 user.setName(username);
00313
00314
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
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
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
00382 String pass = user.getHashPassword().getPassword();
00383 String algo = user.getHashPassword().getAlgorithm();
00384
00385
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
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
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
00426 if (user == null) {
00427 return allCombinedRoles;
00428 }
00429
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
00516 Reference reference = new Reference(FACTORY_TYPE, FACTORY_NAME, null);
00517
00518
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
00564 if (dataSource == null) {
00565
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
00581
00582 if (dataSource instanceof ConnectionManager) {
00583 ConnectionManager cm = (ConnectionManager) dataSource;
00584
00585 if (cm.isClientCase()) {
00586
00587
00588 try {
00589
00590 Class.forName(cm.getClassName());
00591
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
00605
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
00636
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
00667
00668
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
00737 }
00738
00739 }