org.hsqldb.auth.HsqldbSlaveAuthBean Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sqltool Show documentation
Show all versions of sqltool Show documentation
HSQLDB - Lightweight 100% Java SQL Database Engine
/* Copyright (c) 2001-2019, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.auth;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Set;
import org.hsqldb.lib.FrameworkLogger;
/**
* Delegates authentication decisions, and optionally determination of user
* roles and schema, to a different HyperSQL catalog, which may be in the same
* JVM or remote.
*
* For now, at least, this class uses DriverManager to make the ephemeral
* database connections.
*
* @see AuthFunctionBean
* @author Blaine Simpson (blaine dot simpson at admc dot com)
* @since 2.0.1
*/
public class HsqldbSlaveAuthBean implements AuthFunctionBean {
private static FrameworkLogger logger =
FrameworkLogger.getLog(HsqldbSlaveAuthBean.class);
private String masterJdbcUrl, validationUser, validationPassword;
private boolean delegateRolesSchema = true;
protected boolean initialized;
/**
* Use this method and setValidationPassword if you want access to the
* master database to be verified upon instance initialization.
*/
public void setValidationUser(String validationUser) {
this.validationUser = validationUser;
}
/**
* Use this method and setValidationUser if you want access to the
* master database to be verified upon instance initialization.
*/
public void setValidationPassword(String validationPassword) {
this.validationPassword = validationPassword;
}
public void setMasterJdbcUrl(String masterJdbcUrl) {
this.masterJdbcUrl = masterJdbcUrl;
}
/**
* Defaults to true.
*
* Whether roles and initial schema for the new session will be determined
* by what they are for this user in the master database.
*/
public void setDelegateRolesSchema(boolean doDelegateRolesSchema) {
delegateRolesSchema = doDelegateRolesSchema;
}
public HsqldbSlaveAuthBean() {
// Intentionally empty
}
/**
* @throws IllegalStateException if any required setting has not been set.
* @throws SQLException if properties 'validationUser' and
* 'validationPassword' have been set, but we fail to connect to the
* master database.
*/
public void init() throws SQLException {
if (masterJdbcUrl == null) {
throw new IllegalStateException(
"Required property 'masterJdbcUrl' not set");
}
if (validationUser != null || validationPassword != null) {
if (validationUser == null || validationPassword == null) {
throw new IllegalStateException(
"If you set one property of 'validationUser' or "
+ "'validationPassword', then you must set both.");
}
Connection c = null;
SQLException problem = null;
try {
c = DriverManager.getConnection(
masterJdbcUrl, validationUser, validationPassword);
} catch (SQLException se) {
logger.error("Master/slave Connection validation failure", se);
problem = se; // Just indicates to let the original exception
// percolate through in the finally block, to prevent an
// exception in the finally block from obscuring the ultimate
// cause of the problem.
} finally {
if (c != null) try {
c.close();
c = null; // Encourage GC
} catch (SQLException nestedSe) {
logger.error(
"Failed to close test master/slave Connection",
nestedSe);
if (problem == null) {
throw nestedSe;
}
}
}
}
initialized = true;
}
/**
* @see AuthFunctionBean#authenticate(String, String)
*/
public String[] authenticate(String userName, String password)
throws DenyException {
if (!initialized) {
throw new IllegalStateException(
"You must invoke the 'init' method to initialize the "
+ HsqldbSlaveAuthBean.class.getName() + " instance.");
}
Connection c = null;
try {
c = DriverManager.getConnection(masterJdbcUrl, userName, password);
if (delegateRolesSchema) {
Set schemaAndRoles = AuthUtils.getEnabledRoles(c);
String schemaOnMaster = AuthUtils.getInitialSchema(c);
if (schemaOnMaster != null) {
schemaAndRoles.add(schemaOnMaster);
}
logger.finer("Slave delegating schema+roles: "
+ schemaAndRoles);
return schemaAndRoles.toArray(new String[0]);
}
return null;
} catch (SQLException se) {
throw new DenyException();
} finally {
if (c != null) try {
c.close();
c = null; // Encourage GC
} catch (SQLException nestedSe) {
logger.severe(
"Failed to close master/slave Connection", nestedSe);
}
}
}
}