/* * Atricore IDBus * * Copyright (c) 2009, Atricore Inc. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.atricore.idbus.idojos.dbidentitystore; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.atricore.idbus.kernel.main.store.AbstractStore; import org.atricore.idbus.kernel.main.store.UserKey; import org.atricore.idbus.kernel.main.store.SimpleUserKey; import org.atricore.idbus.kernel.main.store.exceptions.NoSuchUserException; import org.atricore.idbus.kernel.main.store.exceptions.SSOIdentityException; import org.atricore.idbus.kernel.main.authn.*; import java.sql.Connection; import java.sql.SQLException; /** * DB implementation of an IdentityStore and CredentialStore. * Three querys have to be configured to the store : * <p/> * - UserQueryString : Used to validate user existence = "SELECT MY_USER FROM MY_USER_TABLE WHERE MY_USR = '?'" * - RolesQueryString : Used to retrieve user's roles = "SELECT MY_ROLE FROM MY_USER_ROLES_TABLE WHERE MY_USER = '?'"; * - CredentialQueryString : Used to retrieve known credentials for a user. * This query depends on the configured authentication scheme. For a user / password based scheme the query could be * "SELECT MY_USER AS USERNAME, MY_PWD AS PASSWORD FROM MY_USER_TABLE WHERE MY_USER ='?'; * The alias is important as is used to map the retrieved value to a specific credential type. * <p/> * Subclasses have to implement getDBConnection() method, this allows jdbc/datasource based stores. * * @author <a href="mailto:sgonzalez@josso.org">Sebastian Gonzalez Oyuela</a> * @version $Id: AbstractDBIdentityStore.java 1040 2009-03-05 00:56:52Z gbrigand $ */ public abstract class AbstractDBIdentityStore extends AbstractStore { private static final Log logger = LogFactory.getLog(AbstractDBIdentityStore.class); private String _userQueryString; private String _rolesQueryString; private String _credentialsQueryString; private String _userPropertiesQueryString; private String _resetCredentialDml; private String _relayCredentialQueryString; private boolean _useColumnsAsPropertyNames; // --------------------------------------------------------------- // AbstractStore extension. // --------------------------------------------------------------- public BaseUser loadUser(UserKey key) throws NoSuchUserException, SSOIdentityException { Connection c = null; try { if (!(key instanceof SimpleUserKey)) { throw new SSOIdentityException("Unsupported key type : " + key.getClass().getName()); } c = getDBConnection(); IdentityDAO dao = getIdentityDAO(c); BaseUser user = dao.selectUser((SimpleUserKey) key); // Optionally find user properties. if (getUserPropertiesQueryString() != null) { SSONameValuePair[] props = dao.selectUserProperties((SimpleUserKey) key); user.setProperties(props); } return user; } finally { closeDBConnection(c); } } public BaseRole[] findRolesByUserKey(UserKey key) throws SSOIdentityException { Connection c = null; try { if (!(key instanceof SimpleUserKey)) { throw new SSOIdentityException("Unsupported key type : " + key.getClass().getName()); } c = getDBConnection(); IdentityDAO dao = getIdentityDAO(c); BaseRole[] roles = dao.selectRolesByUserKey((SimpleUserKey) key); return roles; } finally { closeDBConnection(c); } } public Credential[] loadCredentials(CredentialKey key, CredentialProvider cp) throws SSOIdentityException { Connection c = null; try { if (!(key instanceof SimpleUserKey)) { throw new SSOIdentityException("Unsupported key type : " + key.getClass().getName()); } c = getDBConnection(); IdentityDAO dao = getIdentityDAO(c, cp); Credential[] credentials = dao.selectCredentials((SimpleUserKey) key); return credentials; } finally { closeDBConnection(c); } } // ----------------------------------------------------------------------------------- // Protected utils. // ----------------------------------------------------------------------------------- /** * Subclasses must implement getDBConnection() method. */ public abstract Connection getDBConnection() throws SSOIdentityException; protected IdentityDAO getIdentityDAO(Connection c, CredentialProvider cp) { return new IdentityDAO(c, cp, getUserQueryString(), getRolesQueryString(), getCredentialsQueryString(), getUserPropertiesQueryString(), getResetCredentialDml(), getRelayCredentialQueryString(), isUseColumnsAsPropertyNames()); } protected IdentityDAO getIdentityDAO(Connection c) { return new IdentityDAO(c, null, getUserQueryString(), getRolesQueryString(), getCredentialsQueryString(), getUserPropertiesQueryString(), getResetCredentialDml(), getRelayCredentialQueryString(), isUseColumnsAsPropertyNames()); } /** * Close the given db connection. * * @param dbConnection * @throws SSOIdentityException */ protected void closeDBConnection(Connection dbConnection) throws SSOIdentityException { try { if (dbConnection != null && !dbConnection.isClosed()) { try { dbConnection.commit(); } catch (SQLException e) { if (logger.isDebugEnabled()) { logger.debug("Error while committing connection"); } try { dbConnection.rollback(); } catch (SQLException e1) { if (logger.isDebugEnabled()) { logger.debug("Error while rollback connection"); } } } } if (dbConnection != null && !dbConnection.isClosed()) { dbConnection.close(); } } catch (SQLException se) { if (logger.isDebugEnabled()) { logger.debug("Error while clossing connection"); } throw new SSOIdentityException( "Error while clossing connection\n" + se.getMessage()); } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Error while clossing connection"); } throw new SSOIdentityException( "Error while clossing connection\n" + e.getMessage()); } } // --------------------------------------------------------------- // Configuration properties. // --------------------------------------------------------------- /** * The SQL query that returns a user name based on a user key. */ public String getUserQueryString() { return _userQueryString; } /** * The SQL query that returns the list of roles associated with a given user. */ public String getRolesQueryString() { return _rolesQueryString; } /** * The SQL query that returns the list of known credentials associated with a given user. */ public String getCredentialsQueryString() { return _credentialsQueryString; } /** * The SQL query that returns the list of properties associated with a given user. */ public String getUserPropertiesQueryString() { return _userPropertiesQueryString; } public void setUserQueryString(String userQueryString) { _userQueryString = userQueryString; } public void setRolesQueryString(String rolesQueryString) { _rolesQueryString = rolesQueryString; } public void setCredentialsQueryString(String credentialsQueryString) { _credentialsQueryString = credentialsQueryString; } public void setUserPropertiesQueryString(String userPropertiesQueryString) { _userPropertiesQueryString = userPropertiesQueryString; } public String getResetCredentialDml () { return _resetCredentialDml; } public void setResetCredentialDml ( String resetCredentialDml ) { this._resetCredentialDml = resetCredentialDml; } public String getRelayCredentialQueryString () { return _relayCredentialQueryString; } public void setRelayCredentialQueryString ( String relayCredentialQueryString ) { this._relayCredentialQueryString = relayCredentialQueryString; } public boolean isUseColumnsAsPropertyNames() { return _useColumnsAsPropertyNames; } public void setUseColumnsAsPropertyNames(boolean useColumnsAsPropertyNames) { this._useColumnsAsPropertyNames = useColumnsAsPropertyNames; } }