/*
* (C) Copyright IBM Corp. 2008
*
* LICENSE: Eclipse Public License v1.0
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.ibm.gaiandb.policyframework;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.derby.iapi.types.DataValueDescriptor;
import com.ibm.gaiandb.Util;
public class PolicyRowFilter implements SQLResultFilter {
// Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice.
public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2008";
private static final String MISSION_TASKS_LOGICAL_TABLE = "LTLBB"; //"LT0"; //"MISSION_TASKS";
private static final int MISSION_TASKS_DECOY_TARGET_COLUMN = 2;
// Mapping of:: Data source -> HashSet of authorized users
private static ConcurrentMap<String, Set<String>> authorizedDataSourceUsers = new ConcurrentHashMap<String, Set<String>>();
static {
String[] ds = { "jdbc:derby:gaiandb;create=true::MYTABLE", "./datafile.dat" }; // example data sources
String[] u = { "Alfred", "Bob", "Chris" }; // example users
// Alfred can only access MYTABLE and Chris can only access datafile.dat
// Bob can access both data sources...
authorizedDataSourceUsers.put(ds[0], new HashSet<String>( Arrays.asList( new String[] { u[0], u[1] } ) ) );
authorizedDataSourceUsers.put(ds[1], new HashSet<String>( Arrays.asList( new String[] { u[1], u[2] } ) ) );
// ...
// To query the configured data sources from GaianDB, use the API procedures:
// call listds(): Returns DataSource handle (DSHANDLE) and
// Connection ID (DSCID) for each node - will be implemented in the new version of GaianDB... -
// call listrdbc(): Returns Connection IDs for each node and associated User (CUSR).
}
private String logicalTable = null;
private ResultSetMetaData logicalTableRSMD = null;
private int logicalTableColumnCount = -1;
private int rowCount = 0;
private int[] queriedColumns = null;
private String forwardingNode;
public boolean setForwardingNode( String node ) {
forwardingNode = node;
System.out.println("Forwarding node: " + forwardingNode);
return true;
}
public int nextQueriedDataSource(String dataSource, int[] columnMappings) {
// TODO Auto-generated method stub
return -1; // Allow an unlimited number of rows to be extracted for this data source
}
public boolean setUserCredentials(String credentialsData) {
// TODO Auto-generated method stub
return true;
}
// private boolean setAuthenticatedUserCredentials(String[] userFields) { // to be called from setUserCredentials() once byte[] is decrypted
// // TODO Auto-generated method stub
// return true;
// }
public boolean setLogicalTable(String logicalTableName, ResultSetMetaData logicalTableResultSetMetaData) {
this.logicalTable = logicalTableName;
this.logicalTableRSMD = logicalTableResultSetMetaData;
System.out.println( "Preparing PolicyRowFilter for Logical Table: " +
logicalTable + ", columns: " + logicalTableRSMD.toString() );
try {
logicalTableColumnCount = logicalTableRSMD.getColumnCount();
} catch (SQLException e) {
System.out.println("Could not get logical table column count, cause: " + e);
e.printStackTrace();
}
rowCount = 0;
return true;
}
public boolean setQueriedColumns(int[] queriedColumns) {
this.queriedColumns = queriedColumns;
System.out.println("Queried columns: " + Util.intArrayAsString(this.queriedColumns));
return true;
}
// public int nextQueriedDataSource(String dataSource, int[] columnMappings, String[] userFields) {
// // Check if the user is authorized to query this back-end data source.
// if ( authorizedDataSourceUsers.containsKey(dataSource) )
// if ( ((HashSet<String>) authorizedDataSourceUsers.get(dataSource)).contains(userFields[0]) )
// return -1;
//
// return 0;
// }
protected void applyPolicyHandlerAccessTimeDelay() {
try {
Thread.sleep(10); // 10ms time delay to access the policy service for record filtering
}
catch (Exception e) { e.printStackTrace(); }
}
public boolean filterRow( DataValueDescriptor[] row ) {
applyPolicyHandlerAccessTimeDelay();
// System.out.println("row: " + Arrays.asList(row));
return applyRowFilter(row);
}
protected boolean applyRowFilter( DataValueDescriptor[] row ) {
rowCount++;
// System.out.println("Apply row Filter - rowCount = " + rowCount);
try {
if ( row.length < logicalTableColumnCount ) {
System.out.println("Invalid Fetched Row: Expecting " + logicalTableColumnCount + " columns, not " + row.length);
// System.out.println("-> " + Arrays.asList(row));
return false;
}
if ( 0 == rowCount % 3 ) return false; // Reject every 3rd row
// if ( row[0].toString().compareTo("II") > 0 ) return false; // Reject rows whose first column string value is > 'I'
if ( MISSION_TASKS_LOGICAL_TABLE.equals(logicalTable) ) {
DataValueDescriptor column = row[MISSION_TASKS_DECOY_TARGET_COLUMN-1];
column.setValue("Commander Restricted Information");
if ( 1 == rowCount )
System.out.println("Successfully applied restriction policy for Decoy Target column on 1st result row");
}
} catch ( Exception e ) {
System.out.println("Could not apply restriction policy (invalidating row " +
rowCount + "), cause: " + e);
return false;
}
return true;
}
public void close() {
rowCount = 0;
}
}