All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kawanfw.sql.api.server.SqlConfigurator Maven / Gradle / Ivy

/*
 * This file is part of AceQL. 
 * AceQL: Remote JDBC access over HTTP.                                     
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * AceQL 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.            
 *                                                                               
 * AceQL 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 library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.kawanfw.sql.api.server;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import org.kawanfw.commons.api.server.CommonsConfigurator;

/**
 * 
 * Interface that defines the User Security Configuration for the KawanSoft SQL
 * Framework on the server side.
 * 

* The implemented methods will be called by the framework server programs when * a client program, referred by a user username, asks for a JDBC operation from * the Client side. *

* A concrete implementation should be developed on the server side in order to: *

    *
  • Define if a client user has the right to call a * Statement.execute / PreparedStatement.execute.
  • *
  • Define if a client user has the right to call a * Statement.execute / PreparedStatement.execute.
  • *
  • Define if a client user has the right to call a * Statement.executeUpdate / * PreparedStatement.executeUpdate.
  • *
  • Define if a client user has the right to call a raw * Statement that is not a PreparedStatement.
  • *
  • Define if a client user has the right to query the database catalog * through {@link Connection#getMetaData()}.
  • *
  • Define if a client user has the right query the ResultSet * properties through {@link ResultSet#getMetaData()}.
  • *
  • Define a specific piece of Java code to analyze the source code of the * SQL statement before allowing or not it's execution.
  • *
  • Execute a specific piece of Java code if a SQL statement is not allowed.
  • *
  • Define the maximum number of rows that may be returned to the client.
  • *
  • Define if the Result Set rows returned to the client must be * encrypted/obfuscated.
  • *
  • Define some Java code to execute before/after a * Connection.close(). *
  • Define the maximum number of seconds a Connection can live * before it's released and closed.
  • *
*

* Note that the helper class {@link StatementAnalyser} allows to do some simple * tests on the SQL statement string representation. *

* Note that the framework comes with a Default SqlConfigurator * implementation that is *not* secured and should be extended: * {@link DefaultSqlConfigurator}. *

* * @author Nicolas de Pomereu * @since 1.0 */ public interface SqlConfigurator { /** * Allows to define if the passed username is allowed to call a * {@link Statement#execute(String)} or {@link PreparedStatement#execute()} * * @param username * the client username to check the rule for. * @param connection * The current SQL/JDBC Connection * * @return true if the user has the right to call a raw * execute *

* @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs * @since 1.1 */ public boolean allowExecute(String username, Connection connection) throws IOException, SQLException; /** * Allows to define if the passed username is allowed to call a * {@link Statement#executeUpdate(String)} or * {@link PreparedStatement#executeUpdate()} * * @param username * the client username to check the rule for. * @param connection * The current SQL/JDBC Connection * * @return true if the user has the right to call a raw * execute *

* @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs * @since 1.1 */ public boolean allowExecuteUpdate(String username, Connection connection) throws IOException, SQLException; /** * Allows to define if the passed username is allowed to create and use a * {@link Statement} instance that is not a PreparedStatement * * @param username * the client username to check the rule for. * @param connection * The current SQL/JDBC Connection * * @return true if the user has the right to call a raw * execute *

* @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs * @since 1.1 */ public boolean allowStatementClass(String username, Connection connection) throws IOException, SQLException; /** * Allows to define if the passed username is allowed to query the database * catalog through {@link Connection#getMetaData()}. * * @param username * the client username to check the rule for. * @param connection * The current SQL/JDBC Connection * * @return true if the user has the right to query the Database * catalog. *

* @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs */ public boolean allowGetMetaData(String username, Connection connection) throws IOException, SQLException; /** * Allows to define if the passed username is allowed to query the * ResultSet properties through {@link ResultSet#getMetaData()} * . * * @param username * the client username to check the rule for. * @param connection * The current SQL/JDBC Connection * * @return true if the user has the right to query ResultSet * properties *

* @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs */ public boolean allowResultSetGetMetaData(String username, Connection connection) throws IOException, SQLException; /** * Allows, for the passed client username, to analyze the string * representation of the SQL statement that is received on the server.
* If the analysis defined by the method returns false, the SQL statement * won't be executed. * * @param username * the client username to check the rule for. * @param connection * The current SQL/JDBC Connection * @param sql * the SQL statement * @param parameterValues * the parameter values of a prepared statement in the natural * order, empty list for a (non prepared) statement * * @return true if the analyzed statement or prepared statement * is validated. *

* @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs */ public boolean allowStatementAfterAnalysis(String username, Connection connection, String sql, List parameterValues) throws IOException, SQLException; /** * Allows to define how to close the Connection acquired with * {@link CommonsConfigurator#getConnection()} and return it to the pool.
*
* Most connection pool implementations just require to call * Connection.close() to release the connection, but it is * sometimes necessary for applications to add some operation before/after * the close. This method allows you to add specific code before or after * the close.
*
* It is not required to implement this method, because the default * implementation {@link DefaultSqlConfigurator#close(Connection)} closes * the connection with an explicit call to Connection.close(). * If you implement this method, you *must* close the connection. * * @param connection * a connection to the data source * @throws SQLException */ public void close(Connection connection) throws SQLException; /** * Allows to implement specific a Java rule immediately after a SQL * statement has been refused because one of the * SqlConfigurator.allowXxx method returned false.
*
* Examples: *
    *
  • Delete the user from the username SQL table so that he never comes * back.
  • *
  • Log the IP address.
  • *
  • Log the info.
  • *
  • Send an alert message/email to a Security Officer.
  • *
  • Etc.
  • *
*

* * @param username * the discarded client username * @param connection * The current SQL/JDBC Connection * @param ipAddress * the IP address of the client user * @param sql * the SQL statement * @param parameterValues * the parameter values of a prepared statement in the natural * order, empty list for a (non prepared) statement * * @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs */ public void runIfStatementRefused(String username, Connection connection, String ipAddress, String sql, List parameterValues) throws IOException, SQLException; /** * Allows to define the maximum rows per request to be returned to the * client. If this limit is exceeded, the excess rows are silently dropped. * * @return the maximum rows per request to be returned to the client; zero * means there is no limit * @throws IOException * @throws SQLException */ public int getMaxRowsToReturn() throws IOException, SQLException; /** * Says it the result sets returned to client must be encrypted with the * encryption password provided in * {@link CommonsConfigurator#getEncryptionPassword() }. * * @return true if the result set returned to the client side will be * encrypted * * @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs */ public boolean encryptResultSet() throws IOException, SQLException; /** * Allows to define the maximum number of seconds a Connection * can live before it's released and closed.
*
* This concerns connections that were not correctly closed by the client * side with Connection.close().
*
* 0 means connections are never released and closed. * * @return the maximum number of seconds a Connection can live * before it's released and closed. * * @throws IOException * if an IOException occurs * @throws SQLException * if a SQLException occurs */ public int getMaxAge() throws IOException, SQLException; }