/** * '$RCSfile$' * Purpose: A Class that manages database access of xml access * information. * Copyright: 2009 Regents of the University of California and the * National Center for Ecological Analysis and Synthesis * Authors: Michael Daigle * * '$Author: daigle $' * '$Date: 2009-03-23 13:56:56 -0800 (Mon, 23 Mar 2009) $' * '$Revision: 4854 $' * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package edu.ucsb.nceas.metacat.accesscontrol; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Vector; import org.apache.log4j.Logger; import edu.ucsb.nceas.metacat.database.DBConnection; import edu.ucsb.nceas.metacat.database.DBConnectionPool; import edu.ucsb.nceas.metacat.shared.AccessException; import edu.ucsb.nceas.metacat.shared.BaseAccess; import edu.ucsb.nceas.utilities.access.AccessControlInterface; import edu.ucsb.nceas.utilities.access.XMLAccessDAO; public class XMLAccessAccess extends BaseAccess { private Logger logMetacat = Logger.getLogger(XMLAccessAccess.class); // Constructor public XMLAccessAccess() throws AccessException {} /** * Get all xml access for a document * * @param id * the id of the document * @return an xml access DAO list */ public Vector getXMLAccessForDoc(String guid) throws AccessException { Vector xmlAccessList = new Vector(); if (guid == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForDoc - doc id " + "must be specified when selecting xml_access record"); } // first get the xml access from the db and put it into a DAO list PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { conn = DBConnectionPool.getDBConnection("XMLAccessAccess.getXMLAccessForDoc"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "SELECT * FROM xml_access WHERE guid = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, guid); String sqlReport = "XMLAccessAccess.getXMLAccessForDoc - SQL: " + sql; sqlReport += " [" + guid + "]"; logMetacat.info(sqlReport); pstmt.execute(); ResultSet resultSet = pstmt.getResultSet(); while (resultSet.next()) { XMLAccessDAO xmlAccessDAO = populateDAO(resultSet); xmlAccessList.add(xmlAccessDAO); } // make sure permission orders do not conflict in the database validateDocXMLAccessList(xmlAccessList); return xmlAccessList; } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.getXMLAccessForDoc - SQL error when getting access " + " for id: " + guid + " : " + sqle.getMessage()); } catch (PermOrderException poe) { String errorStr = "XMLAccessAccess.getXMLAccessForDoc - Permission order error when getting " + "access record for doc id: " + guid + " : " + poe.getMessage(); logMetacat.error(errorStr); throw new AccessException(errorStr); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Get all xml access for a principal for a certain document * * @param id * the id of the document * @param principalName * the credentials of the principal in the database * @return an xml access DAO list */ public Vector getXMLAccessForPrincipal(String guid, String principalName) throws AccessException { Vector xmlAccessList = new Vector(); if (guid == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + "must be specified when selecting xml_access record"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + "must be specified when selecting xml_access record"); } // first get the xml access for this principal from the db and put it into a DAO list PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { conn = DBConnectionPool.getDBConnection("XMLAccessAccess.getXMLAccessForPrincipal"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "SELECT * FROM xml_access WHERE guid = ? AND principal_name = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, guid); pstmt.setString(2, principalName); String sqlReport = "XMLAccessAccess.getXMLAccessForPrincipal - SQL: " + sql; sqlReport += " [" + guid + "," + principalName + "]"; logMetacat.info(sqlReport); pstmt.execute(); ResultSet resultSet = pstmt.getResultSet(); while (resultSet.next()) { XMLAccessDAO xmlAccessDAO = populateDAO(resultSet); xmlAccessList.add(xmlAccessDAO); } // make sure permission orders do not conflict in the database validatePrincipalXMLAccessList(xmlAccessList); return xmlAccessList; } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - SQL error when getting access " + " for id: " + guid + ", principal: " + principalName + " : " + sqle.getMessage()); } catch (PermOrderException poe) { String errorStr = "XMLAccessAccess.getXMLAccessForPrincipal - Permission order error when getting " + "access record for id: " + guid + ", principal: " + principalName + " : " + poe.getMessage(); logMetacat.error(errorStr); throw new AccessException(errorStr); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Get all xml access for a principal/permType/permOrder for a certain document * * @param guid * the id of the document * @param principalName * the credentials of the principal in the database * @return an xml access DAO list */ public Vector getXMLAccessForPrincipal(String guid, String principalName, String permType, String permOrder) throws AccessException { Vector xmlAccessList = new Vector(); if (guid == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + "must be specified when selecting xml_access record"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + "must be specified when selecting xml_access record"); } if (permType == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - permission type " + "must be specified when selecting xml_access record"); } if (permOrder == null) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - permission order " + "must be specified when selecting xml_access record"); } // first get the xml access for this principal from the db and put it into a DAO list PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { conn = DBConnectionPool.getDBConnection("XMLAccessAccess.getXMLAccessForPrincipal"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "SELECT * FROM xml_access WHERE guid = ? AND principal_name = ? " + "AND perm_type = ? AND perm_order = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, guid); pstmt.setString(2, principalName); pstmt.setString(3, permType); pstmt.setString(4, permOrder); String sqlReport = "XMLAccessAccess.getXMLAccessForPrincipal - SQL: " + sql; sqlReport += " [" + guid + "," + principalName + "," + permType + "," + permOrder + "]"; logMetacat.info(sqlReport); pstmt.execute(); ResultSet resultSet = pstmt.getResultSet(); while (resultSet.next()) { XMLAccessDAO xmlAccessDAO = populateDAO(resultSet); xmlAccessList.add(xmlAccessDAO); } validatePrincipalXMLAccessList(xmlAccessList); return xmlAccessList; } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - SQL error when getting access " + " for id: " + guid + ", principal: " + principalName + " : " + sqle.getMessage()); } catch (PermOrderException poe) { String errorStr = "XMLAccessAccess.getXMLAccessForPrincipal - Permission order error when getting " + "access record for id: " + guid + ", principal: " + principalName + " : " + poe.getMessage(); logMetacat.error(errorStr); throw new AccessException(errorStr); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Add permissions for a given principal on a given document. If the * principal already exists, bitwise OR the permission to the existing * permission and update. * * @param guid * document id * @param principalName * principal credentials * @param permission * permission bitmap * @param permType * permission type * @param permOrder * permission order */ public void addXMLAccess(String guid, String principalName, Long permission, String permType, String permOrder, String accessFileId, String subTreeId) throws AccessException, PermOrderException { permOrderConflict(guid, permOrder); Vector xmlAccessList = getXMLAccessForPrincipal(guid, principalName, permType, permOrder); // if more than one record exists for this principal on this document with the same // access type / access order combination, call cleanup to combine common access and then // re-retrieve the access list. if (xmlAccessList.size() == 0) { insertXMLAccess(guid, principalName, permission, permType, permOrder, accessFileId, subTreeId); return; } if (xmlAccessList.size() > 1) { cleanupXMLAccessForPrincipal(xmlAccessList); xmlAccessList = getXMLAccessForPrincipal(guid, principalName, permType, permOrder); } if (xmlAccessList.size() == 0) { throw new AccessException("XMLAccessAccess.addXMLAccess - xml access list is empty when " + "it shouldn't be for id: " + guid + ", prinicpal name: " + principalName + ", perm type " + permType + ", perm order: " + permOrder); } XMLAccessDAO xmlAccessDAO = xmlAccessList.get(0); // if the permission on the xml access dao does not already contain the permission we are //trying to add, update the access record with the existing permission bitwis OR-ed with our // new permission if ((xmlAccessDAO.getPermission() & permission) != permission) { updateXMLAccessPermission(guid, principalName, xmlAccessDAO.getPermission() | permission); } } /** * Set permissions for a given document. This means first removing all access control for the * document and then adding the given rules. * * @param id * document id * @param xmlAccessList * list of xml access dao objects that hold new access for the document */ public void replaceAccess(String guid, List xmlAccessList) throws AccessException { deleteXMLAccessForDoc(guid); insertAccess(guid, xmlAccessList); } /** * Set permissions for a given document. This means first removing all access control for the * document and then adding the given rules. * * @param id * document id * @param xmlAccessList * list of xml access dao objects that hold new access for the document */ public void insertAccess(String guid, List xmlAccessList) throws AccessException { // if more than one record exists for this principal on this document with the same // access type / access order combination, call cleanup to combine common access and then // re-retrieve the access list. for(XMLAccessDAO xmlAccessDAO : xmlAccessList) { insertXMLAccess(guid, xmlAccessDAO.getPrincipalName(), xmlAccessDAO.getPermission(), xmlAccessDAO.getPermType(), xmlAccessDAO.getPermOrder(), xmlAccessDAO.getAccessFileId(), xmlAccessDAO.getSubTreeId()); } } /** * Insert an xml access record. It is assumed that the checks have already been made to * make sure the principal does not already have an access record for this document. If * one does already exist, that record should be updated and this insert not called. * * @param id * document id * @param principal * principal credentials * @param permission * permission bitmap * @param permType * permission type * @param permOrder * permission order */ private void insertXMLAccess(String guid, String principalName, Long permission, String permType, String permOrder, String accessFileId, String subTreeId) throws AccessException { //System.out.println("permission in insertXMLAccess: " + permission); try { if(permission == -1) { throw new Exception("Permission is -1 in XMLAccessAccess.insertXMLAccess()."); } } catch(Exception e) { e.printStackTrace(); logMetacat.warn(e.getMessage()); } if (guid == null) { throw new AccessException("XMLAccessAccess.insertXMLAccess - id is required when " + "inserting XML access record"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.insertXMLAccess - principal is required when " + "inserting XML access record"); } if (permission == null) { throw new AccessException("XMLAccessAccess.insertXMLAccess - permission is required when " + "inserting XML access record"); } if (permType == null) { throw new AccessException("XMLAccessAccess.insertXMLAccess - permType is required when " + "inserting XML access record"); } if (permOrder == null) { permOrder = AccessControlInterface.ALLOWFIRST; } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.insertXMLAccess"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "INSERT INTO xml_access " + "(guid, principal_name, permission, perm_type, perm_order, accessfileid, subtreeid ) " + "VALUES (?,?,?,?,?,?,?)"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setString(1, guid); pstmt.setString(2, principalName); pstmt.setLong(3, permission); pstmt.setString(4, permType); pstmt.setString(5, permOrder); pstmt.setString(6, accessFileId); pstmt.setString(7, subTreeId); String sqlReport = "XMLAccessAccess.insertXMLAccess - SQL: " + sql; sqlReport += " [" + guid + "," + principalName + "," + permission + "," + permType + "," + permOrder + "]"; logMetacat.info(sqlReport); pstmt.execute(); } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.insertXMLAccess - SQL error when inserting" + "xml access permissions for id: " + guid + ", principal: " + principalName + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Update existing xml access permissions in the db. The permission value should be the combined * value of pre-existing permissions plus new permissions. * * @param guid * document id * @param principalName * principal credentials * @param permission * permission bitmap */ private void updateXMLAccessPermission(String guid, String principalName, Long permission) throws AccessException { if (guid == null) { throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - id is required when " + "updating XML access record"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - principal is required when " + "updating XML access record"); } if (permission == null) { throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - permission is required when " + "updating XML access record"); } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.updateXMLAccessPermission"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "UPDATE xml_access SET permission = ?" + "WHERE guid = ? AND principal_name = ?"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setLong(1, permission); pstmt.setString(2, guid); pstmt.setString(3, principalName); String sqlReport = "XMLAccessAccess.updateXMLAccessPermission - SQL: " + sql; sqlReport += " [" + permission + "," + guid + "," + principalName + "]"; logMetacat.info(sqlReport); pstmt.execute(); } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - SQL error when updating" + "xml access permissions for id: " + guid + ", principal: " + principalName + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Remove xml access. This modifies the access in the database for a principal * for a given document. If the provided permission is exactly the same as what * the principal has, the record is deleted from the database. * * @param guid * document id * @param principalName * principal credentials */ public void removeXMLAccessForPrincipal(String guid, String principalName, Long permission) throws AccessException { if (guid == null) { throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - id is required when " + "removing XML access"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - principal is required when " + "deleting XML access"); } if (permission == null) { throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - permission is required when " + "updating XML access"); } Vector xmlAccessList = getXMLAccessForPrincipal(guid, principalName); if (xmlAccessList.size() == 0) { logMetacat.warn("XMLAccessAccess.removeXMLAccessForPrincipal - attempting to remove access when no " + "access record exists for id: " + guid + ", principal: " + principalName); } else { long permissionMask = 0; for (XMLAccessDAO xmlAccessDAO : xmlAccessList) { permissionMask |= xmlAccessDAO.getPermission(); } permissionMask |= permission; // in this case, the only existing permissions are the ones we want to remove, so // delete the record(s) for this principal on this document if ((permissionMask & permission) == permission) { deleteXMLAccessForPrincipal(guid, principalName); } if (xmlAccessList.size() > 1) { } else { updateXMLAccessPermission(guid, principalName, permission); } } } /** * Delete xml access. This removes all access records from the database for a given document * * @param id * document id */ public void deleteXMLAccessForDoc(String guid) throws AccessException { if (guid == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - id is required when " + "deleting XML access record"); } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForDoc"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "DELETE FROM xml_access WHERE guid = ?"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setString(1, guid); String sqlReport = "XMLAccessAccess.deleteXMLAccessForDoc - SQL: " + sql; sqlReport += " [" + guid + "]"; logMetacat.info(sqlReport); pstmt.execute(); } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForDoc - SQL error when deleting" + "xml access permissions for id: " + guid + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Delete xml access. This removes all access records from the database for a principal * for a given document * * @param guid * document id * @param principal * principal credentials */ private void deleteXMLAccessForPrincipal(String guid, String principalName) throws AccessException { if (guid == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - id is required when " + "deleting XML access record"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - principal is required when " + "deleting XML access record"); } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForPrincipal"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "DELETE FROM xml_access WHERE guid = ? AND principal_name = ?"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setString(1, guid); pstmt.setString(2, principalName); String sqlReport = "XMLAccessAccess.deleteXMLAccessForPrincipal - SQL: " + sql; sqlReport += " [" + guid + "," + principalName + "]"; logMetacat.info(sqlReport); pstmt.execute(); } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when deleting" + "xml access permissions for id: " + guid + ", principal: " + principalName + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Delete xml access. This removes all access records from the database for a principal * for a given document * * @param guid * document id * @param principal * principal credentials */ public void deleteXMLAccessForDoc(String guid, String permType) throws AccessException { if (guid == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForDoc - id is required when " + "deleting XML access record"); } if (permType == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForDoc - permType is required when " + "deleting XML access record"); } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForDoc"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "DELETE FROM xml_access WHERE guid = ? AND perm_type = ?"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setString(1, guid); pstmt.setString(2, permType); String sqlReport = "XMLAccessAccess.deleteXMLAccessForDoc - SQL: " + sql; sqlReport += " [" + guid + "," + permType + "]"; logMetacat.info(sqlReport); pstmt.execute(); } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForDoc - SQL error when deleting" + "xml access permissions for id: " + guid + ", permType: " + permType + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Checks to see if there is a permission order conflict for a given document. Each * document is only allowed to have a single permission order * * @param guid * document id * @param principal * principal credentials */ private void permOrderConflict(String guid, String permOrder) throws AccessException, PermOrderException { if (guid == null) { throw new AccessException("XMLAccessAccess.permOrderConflict - id is required when " + "determining perm order conflict"); } if (permOrder == null) { throw new AccessException("XMLAccessAccess.permOrderConflict - perm order is required when " + "determining perm order conflict"); } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.permOrderConflict"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "SELECT * FROM xml_access WHERE guid = ? AND perm_order != ?"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setString(1, guid); pstmt.setString(2, permOrder); String sqlReport = "XMLAccessAccess.permOrderConflict - SQL: " + sql; sqlReport += " [" + guid + "," + permOrder + "]"; logMetacat.info(sqlReport); pstmt.execute(); ResultSet resultSet = pstmt.getResultSet(); if (resultSet.next()) { throw new PermOrderException("XMLAccessAccess.addXMLAccess - cannot add permission " + "record for id: " + guid + "with permOrder: " + permOrder + " due to permOrder conflict"); } } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.permOrderConflict - SQL error when checking" + "for perm order conflict on: " + guid + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Delete xml access. This removes all access records from the database for a principal * for a given document, perm type and perm order * * @param guid * document id * @param principal * principal credentials */ private void deleteXMLAccessForPrincipal(String guid, String principalName, String permType, String permOrder) throws AccessException { if (guid == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - id is required when " + "deleting XML access record"); } if (principalName == null) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - principal is required when " + "deleting XML access record"); } if (permType == null) { throw new AccessException( "XMLAccessAccess.deleteXMLAccessForPrincipal - perm type is required when " + "deleting XML access record"); } if (permOrder == null) { throw new AccessException( "XMLAccessAccess.deleteXMLAccessForPrincipal - perm order is required when " + "deleting XML access record"); } PreparedStatement pstmt = null; DBConnection conn = null; int serialNumber = -1; try { // check out DBConnection conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForPrincipal"); serialNumber = conn.getCheckOutSerialNumber(); String sql = "DELETE FROM xml_access WHERE guid = ? AND principal_name = ? " + "AND perm_type = ? AND perm_order = ?"; pstmt = conn.prepareStatement(sql); // Bind the values to the query pstmt.setString(1, guid); pstmt.setString(2, principalName); pstmt.setString(3, permType); pstmt.setString(4, permOrder); String sqlReport = "XMLAccessAccess.deleteXMLAccessForPrincipal - SQL: " + sql; sqlReport += " [" + guid + "," + principalName + "," + permType + "," + permOrder + "]"; logMetacat.info(sqlReport); pstmt.execute(); } catch (SQLException sqle) { throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when deleting" + "xml access permissions for id: " + guid + ", principal: " + principalName + ":" + sqle.getMessage()); } finally { closeDBObjects(pstmt, conn, serialNumber, logMetacat); } } /** * Make sure that only one record exists per principal/permType/document. If * more than one record exists, delete the existing records, consolidate the * permissions insert the new record. * * @param xmlAccessList the access dao list */ private void cleanupXMLAccessForPrincipal(Vector xmlAccessList) throws AccessException{ int numAllowRecords = 0; int numDenyRecords = 0; long allowPermissionMask = 0; long denyPermissionMask = 0; String guid = null; String principalName = null; String permType = null; String permOrder = null; // TODO: handle these fields String accessFileId = null; String subTreeId = null; // iterate through the list of access dao objects and bttwise or the permissions. Most // of this is just doing some error checking to make sure each record is valid. for (XMLAccessDAO xmlAccessDAO : xmlAccessList) { String daoId = xmlAccessDAO.getGuid(); if (guid == null) { guid = daoId; } else { if (!guid.equals(daoId)) { throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + " Conflicting ids " + daoId + " and " + guid); } } if (principalName == null) { principalName = xmlAccessDAO.getPrincipalName(); } else { if (!principalName.equals(xmlAccessDAO.getPrincipalName())) { throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + " Conflicting prinicpal names " + xmlAccessDAO.getPrincipalName() + " and principalName " + principalName); } } if (permType == null) { permType = xmlAccessDAO.getPermType(); } else { if (!permType.equals(xmlAccessDAO.getPermType())) { throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + " Conflicting permission orders for document " + daoId + "principalName " + principalName + ". Database intervention required "); } } if (permOrder == null) { permOrder = xmlAccessDAO.getPermOrder(); } else { if (!permOrder.equals(xmlAccessDAO.getPermOrder())) { throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + " Conflicting permission types for document " + daoId + "principalName " + principalName + ". Database intervention required "); } } if (permType == null) { permType = xmlAccessDAO.getPermType(); } else { if (!permType.equals(xmlAccessDAO.getPermType())) { throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + " Conflicting permission orders for document " + daoId + "principalName " + principalName + ". Database intervention required "); } } if (permType.equals(AccessControlInterface.ALLOW)) { numAllowRecords++; allowPermissionMask |= xmlAccessDAO.getPermission(); } else if (permType.equals(AccessControlInterface.DENY)) { numDenyRecords++; denyPermissionMask |= xmlAccessDAO.getPermission(); } if (accessFileId == null) { accessFileId = xmlAccessDAO.getAccessFileId(); } if (subTreeId == null) { subTreeId = xmlAccessDAO.getSubTreeId(); } } // if there was more than one allow record, remove all allow records for this user on this doc // with this perm type and perm order then insert a single record if (numAllowRecords > 1) { deleteXMLAccessForPrincipal(guid, principalName, AccessControlInterface.ALLOW, permOrder); insertXMLAccess(guid, principalName, allowPermissionMask, AccessControlInterface.ALLOW, permOrder, accessFileId, subTreeId); } // if there was more than one deny record, remove all deny records for this user on this doc // with this perm type and perm order then insert a single record if (numDenyRecords > 1) { deleteXMLAccessForPrincipal(guid, principalName, AccessControlInterface.DENY, permOrder); insertXMLAccess(guid, principalName, denyPermissionMask, AccessControlInterface.DENY, permOrder, accessFileId, subTreeId); } } /** * Make sure for a given list of access DAOs that only one perm order * exists. It is assumed that all the DAOs are for the same doc * * @param xmlAccessList * the access dao list */ private void validateDocXMLAccessList(Vector xmlAccessList) throws PermOrderException { String permOrder = null; for(XMLAccessDAO xmlAccessDAO : xmlAccessList) { String daoId = xmlAccessDAO.getGuid(); if (permOrder == null) { permOrder = xmlAccessDAO.getPermOrder(); } else { if(!permOrder.equals(xmlAccessDAO.getPermOrder())) { throw new PermOrderException("XMLAccessAccess.validateXMLAccessList - " + " Conflicting permission orders for document " + daoId + ". Database intervention required "); } } } } /** * Check that only one permOrder exists for each principal. * TODO add check that one of each permType exists as well * * @param xmlAccessList * the access dao list */ private void validatePrincipalXMLAccessList(Vector xmlAccessList) throws PermOrderException { boolean allowFirst = false; boolean denyFirst = false; String guid = null; // These vectors will hold all combinations of access DAOs with different permission // orders and permission types. Vector allowFirstAllows = new Vector(); Vector allowFirstDenys = new Vector(); Vector denyFirstAllows = new Vector(); Vector denyFirstDenys = new Vector(); // sort the access dao records into the appropriate vector for(XMLAccessDAO xmlAccessDAO : xmlAccessList) { String daoId = xmlAccessDAO.getGuid(); if (guid == null) { guid = daoId; } if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.ALLOWFIRST)) { allowFirst = true; if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) { allowFirstAllows.add(xmlAccessDAO); } else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) { allowFirstDenys.add(xmlAccessDAO); } else { throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + " Invalid permission type: " + xmlAccessDAO.getPermType() + " for document " + daoId + ". Database intervention required "); } } else if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.DENYFIRST)) { denyFirst = true; if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) { denyFirstAllows.add(xmlAccessDAO); } else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) { denyFirstDenys.add(xmlAccessDAO); } else { throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + " Invalid permission type: " + xmlAccessDAO.getPermType() + " for document " + daoId + ". Database intervention required "); } } else { throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + " Invalid permission order: " + xmlAccessDAO.getPermOrder() + " for document " + daoId + ". Database intervention required "); } } // for a given user, there cannot be allowfirst and denyfirst records on the same // document if(allowFirst && denyFirst) { throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + " Conflicting permission orders for document " + guid + ". Database intervention required "); } } /** * Populate a job data object with the current row in a resultset * * @param resultSet * the result set which is already pointing to the desired row. * @return a scheduled job data object */ protected XMLAccessDAO populateDAO(ResultSet resultSet) throws SQLException { XMLAccessDAO xmlAccessDAO = new XMLAccessDAO(); xmlAccessDAO.setGuid(resultSet.getString("guid")); xmlAccessDAO.setAccessFileId(resultSet.getString("accessfileid")); xmlAccessDAO.setPrincipalName(resultSet.getString("principal_name")); xmlAccessDAO.setPermission(resultSet.getLong("permission")); xmlAccessDAO.setPermType(resultSet.getString("perm_type")); xmlAccessDAO.setPermOrder(resultSet.getString("perm_order")); xmlAccessDAO.setBeginTime(resultSet.getDate("begin_time")); xmlAccessDAO.setEndTime(resultSet.getDate("end_time")); xmlAccessDAO.setTicketCount(resultSet.getLong("ticket_count")); xmlAccessDAO.setSubTreeId(resultSet.getString("subtreeid")); xmlAccessDAO.setStartNodeId(resultSet.getString("startnodeid")); xmlAccessDAO.setEndNodeId(resultSet.getString("endnodeid")); return xmlAccessDAO; } }