Revision 5098
Added by daigle over 14 years ago
XMLAccessAccess.java | ||
---|---|---|
1 | 1 |
/** |
2 | 2 |
* '$RCSfile$' |
3 |
* Purpose: A Class that manages database access of scheduled task
|
|
3 |
* Purpose: A Class that manages database access of xml access
|
|
4 | 4 |
* information. |
5 | 5 |
* Copyright: 2009 Regents of the University of California and the |
6 | 6 |
* National Center for Ecological Analysis and Synthesis |
... | ... | |
259 | 259 |
} |
260 | 260 |
|
261 | 261 |
/** |
262 |
* Add permissions for a given prinicpal on a given document. If the
|
|
263 |
* prinicpal already exists, bitwise OR the permission to the existing
|
|
262 |
* Add permissions for a given principal on a given document. If the
|
|
263 |
* principal already exists, bitwise OR the permission to the existing
|
|
264 | 264 |
* permission and update. |
265 | 265 |
* |
266 | 266 |
* @param docId |
... | ... | |
310 | 310 |
} |
311 | 311 |
|
312 | 312 |
/** |
313 |
* Insert an xml access record |
|
313 |
* Set permissions for a given document. This means first removing all access control for the |
|
314 |
* document and then adding the given rules. |
|
315 |
* |
|
314 | 316 |
* @param docId |
315 | 317 |
* document id |
318 |
* @param xmlAccessList |
|
319 |
* list of xml access dao objects that hold new access for the document |
|
320 |
*/ |
|
321 |
public void setXMLAccess(String docId, Vector<XMLAccessDAO> xmlAccessList) throws AccessException { |
|
322 |
deleteXMLAccessForDoc(docId); |
|
323 |
|
|
324 |
// if more than one record exists for this principal on this document with the same |
|
325 |
// access type / access order combination, call cleanup to combine common access and then |
|
326 |
// re-retrieve the access list. |
|
327 |
for(XMLAccessDAO xmlAccessDAO : xmlAccessList) { |
|
328 |
insertXMLAccess(docId, xmlAccessDAO.getPrincipalName(), xmlAccessDAO.getPermission(), |
|
329 |
xmlAccessDAO.getPermType(), xmlAccessDAO.getPermOrder()); |
|
330 |
} |
|
331 |
} |
|
332 |
|
|
333 |
/** |
|
334 |
* Insert an xml access record. It is assumed that the checks have already been made to |
|
335 |
* make sure the principal does not already have an access record for this document. If |
|
336 |
* one does already exist, that record should be updated and this insert not called. |
|
337 |
* |
|
338 |
* @param docId |
|
339 |
* document id |
|
316 | 340 |
* @param principal |
317 | 341 |
* principal credentials |
318 | 342 |
* @param permission |
... | ... | |
389 | 413 |
} |
390 | 414 |
|
391 | 415 |
/** |
392 |
* Update existing xml access permissions in the db |
|
416 |
* Update existing xml access permissions in the db. The permission value should be the combined |
|
417 |
* value of pre-existing permissions plus new permissions. |
|
418 |
* |
|
393 | 419 |
* @param docId |
394 | 420 |
* document id |
395 | 421 |
* @param principalName |
... | ... | |
455 | 481 |
} |
456 | 482 |
|
457 | 483 |
/** |
458 |
* Delete xml access. This modifies the access in the database for a principal
|
|
484 |
* Remove xml access. This modifies the access in the database for a principal
|
|
459 | 485 |
* for a given document. If the provided permission is exactly the same as what |
460 |
* the principal has, the record is removed from the database. |
|
486 |
* the principal has, the record is deleted from the database. |
|
487 |
* |
|
461 | 488 |
* @param docId |
462 | 489 |
* document id |
463 | 490 |
* @param principalName |
464 | 491 |
* principal credentials |
465 | 492 |
*/ |
466 |
private void removeXMLAccessForPrincipal(String docId, String principalName, Long permission) throws AccessException {
|
|
493 |
public void removeXMLAccessForPrincipal(String docId, String principalName, Long permission) throws AccessException {
|
|
467 | 494 |
if (docId == null) { |
468 | 495 |
throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - docid is required when " + |
469 | 496 |
"removing XML access"); |
... | ... | |
504 | 531 |
} |
505 | 532 |
|
506 | 533 |
/** |
534 |
* Delete xml access. This removes all access records from the database for a given document |
|
535 |
* |
|
536 |
* @param docId |
|
537 |
* document id |
|
538 |
*/ |
|
539 |
private void deleteXMLAccessForDoc(String docId) throws AccessException { |
|
540 |
if (docId == null) { |
|
541 |
throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - docid is required when " + |
|
542 |
"deleting XML access record"); |
|
543 |
} |
|
544 |
|
|
545 |
PreparedStatement pstmt = null; |
|
546 |
DBConnection conn = null; |
|
547 |
int serialNumber = -1; |
|
548 |
try { |
|
549 |
// check out DBConnection |
|
550 |
conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForDoc"); |
|
551 |
String sql = "DELETE FROM xml_access WHERE docid = ?"; |
|
552 |
pstmt = conn.prepareStatement(sql); |
|
553 |
|
|
554 |
// Bind the values to the query |
|
555 |
pstmt.setString(1, docId); |
|
556 |
|
|
557 |
String sqlReport = "XMLAccessAccess.deleteXMLAccessForDoc - SQL: " + sql; |
|
558 |
sqlReport += " [" + docId + "]"; |
|
559 |
|
|
560 |
logMetacat.info(sqlReport); |
|
561 |
|
|
562 |
pstmt.execute(); |
|
563 |
} catch (SQLException sqle) { |
|
564 |
throw new AccessException("XMLAccessAccess.deleteXMLAccessForDoc - SQL error when deleting" |
|
565 |
+ "xml access permissions for doc id: " + docId + ":" + sqle.getMessage()); |
|
566 |
} finally { |
|
567 |
try { |
|
568 |
if (pstmt != null) { |
|
569 |
pstmt.close(); |
|
570 |
} |
|
571 |
} catch (SQLException sqle) { |
|
572 |
logMetacat.error("XMLAccessAccess.deleteXMLAccessForDoc - SQL error when closing prepared " + |
|
573 |
"statement after deleting xml access permissions for doc id: " + ":" + sqle.getMessage()); |
|
574 |
} finally { |
|
575 |
DBConnectionPool.returnDBConnection(conn, serialNumber); |
|
576 |
} |
|
577 |
} |
|
578 |
} |
|
579 |
|
|
580 |
/** |
|
507 | 581 |
* Delete xml access. This removes all access records from the database for a principal |
508 | 582 |
* for a given document |
583 |
* |
|
509 | 584 |
* @param docId |
510 | 585 |
* document id |
511 | 586 |
* @param principal |
... | ... | |
628 | 703 |
} |
629 | 704 |
|
630 | 705 |
} |
631 |
|
|
706 |
|
|
707 |
/** |
|
708 |
* Make sure that only one record exists per principal/permType/document. If |
|
709 |
* more than one record exists, delete the existing records, consolidate the |
|
710 |
* permissions insert the new record. |
|
711 |
* |
|
712 |
* @param xmlAccessList |
|
713 |
* @throws AccessException |
|
714 |
*/ |
|
632 | 715 |
private void cleanupXMLAccessForPrincipal(Vector<XMLAccessDAO> xmlAccessList) throws AccessException{ |
633 | 716 |
|
634 |
long permissionMask = 0; |
|
717 |
int numAllowRecords = 0; |
|
718 |
int numDenyRecords = 0; |
|
719 |
long allowPermissionMask = 0; |
|
720 |
long denyPermissionMask = 0; |
|
635 | 721 |
String docId = null; |
636 | 722 |
String principalName = null; |
637 | 723 |
String permType = null; |
638 | 724 |
String permOrder = null; |
639 | 725 |
|
640 |
if (xmlAccessList.size() == 1) { |
|
641 |
return; |
|
642 |
} |
|
643 | 726 |
|
644 | 727 |
// iterate through the list of access dao objects and bttwise or the permissions. Most |
645 | 728 |
// of this is just doing some error checking to make sure each record is valid. |
... | ... | |
689 | 772 |
"principalName " + principalName + ". Database intervention required "); |
690 | 773 |
} |
691 | 774 |
} |
692 |
permissionMask |= xmlAccessDAO.getPermission(); |
|
775 |
if (permType.equals(AccessControlInterface.ALLOW)) { |
|
776 |
numAllowRecords++; |
|
777 |
allowPermissionMask |= xmlAccessDAO.getPermission(); |
|
778 |
} else if (permType.equals(AccessControlInterface.DENY)) { |
|
779 |
numDenyRecords++; |
|
780 |
denyPermissionMask |= xmlAccessDAO.getPermission(); |
|
781 |
} |
|
693 | 782 |
} |
694 | 783 |
|
695 |
// remove all records for this user on this doc with this perm type and perm order |
|
696 |
// then insert a single record |
|
697 |
deleteXMLAccessForPrincipal(docId, principalName, permType, permOrder); |
|
698 |
insertXMLAccess(docId, principalName, permissionMask, permType, permOrder); |
|
784 |
// if there was more than one allow record, remove all allow records for this user on this doc |
|
785 |
// with this perm type and perm order then insert a single record |
|
786 |
if (numAllowRecords > 1) { |
|
787 |
deleteXMLAccessForPrincipal(docId, principalName, AccessControlInterface.ALLOW, permOrder); |
|
788 |
insertXMLAccess(docId, principalName, allowPermissionMask, AccessControlInterface.ALLOW, permOrder); |
|
789 |
} |
|
790 |
// if there was more than one deny record, remove all deny records for this user on this doc |
|
791 |
// with this perm type and perm order then insert a single record |
|
792 |
if (numDenyRecords > 1) { |
|
793 |
deleteXMLAccessForPrincipal(docId, principalName, AccessControlInterface.DENY, permOrder); |
|
794 |
insertXMLAccess(docId, principalName, denyPermissionMask, AccessControlInterface.DENY, permOrder); |
|
795 |
} |
|
699 | 796 |
} |
700 | 797 |
|
798 |
/** |
|
799 |
* |
|
800 |
* @param xmlAccessList |
|
801 |
* @throws PermOrderException |
|
802 |
*/ |
|
701 | 803 |
private void validateDocXMLAccessList(Vector<XMLAccessDAO> xmlAccessList) throws PermOrderException { |
702 | 804 |
String permOrder = null; |
703 | 805 |
for(XMLAccessDAO xmlAccessDAO : xmlAccessList) { |
... | ... | |
769 | 871 |
". Database intervention required "); |
770 | 872 |
} |
771 | 873 |
} |
772 |
|
|
773 |
/** |
|
774 |
* Check if the given list of XML access DAOs has redundant access. This occurs if there is |
|
775 |
* more than one instance of any combination of access type and access order. Note that we |
|
776 |
* assume that the list contains access records for one principal on one document. |
|
777 |
* @param xmlAccessList |
|
778 |
* @return |
|
779 |
* @throws AccessException |
|
780 |
*/ |
|
781 |
private boolean hasRedundantPrincipalAccess(Vector<XMLAccessDAO> xmlAccessList) throws AccessException { |
|
782 |
|
|
783 |
// These will hold counts of all combinations of access DAOs with different permission |
|
784 |
// orders and permission types. |
|
785 |
int allowFirstAllows = 0; |
|
786 |
int allowFirstDenys = 0; |
|
787 |
int denyFirstAllows = 0; |
|
788 |
int denyFirstDenys = 0; |
|
789 |
|
|
790 |
for(XMLAccessDAO xmlAccessDAO : xmlAccessList) { |
|
791 |
if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.ALLOWFIRST)) { |
|
792 |
if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) { |
|
793 |
allowFirstAllows++; |
|
794 |
} else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) { |
|
795 |
allowFirstDenys++; |
|
796 |
} else { |
|
797 |
throw new AccessException("XMLAccessAccess.validatePrincipalXMLAccessList - " + |
|
798 |
"Invalid permission type: "+ xmlAccessDAO.getPermType() + " for document " + |
|
799 |
xmlAccessDAO.getDocId() + ". Database intervention required "); |
|
800 |
} |
|
801 |
} else if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.DENYFIRST)) { |
|
802 |
if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) { |
|
803 |
denyFirstAllows++; |
|
804 |
} else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) { |
|
805 |
denyFirstDenys++; |
|
806 |
} else { |
|
807 |
throw new AccessException("XMLAccessAccess.validatePrincipalXMLAccessList - " + |
|
808 |
"Invalid permission type: " + xmlAccessDAO.getPermType() + " for document "+ |
|
809 |
xmlAccessDAO.getDocId() + ". Database intervention required "); |
|
810 |
} |
|
811 |
} |
|
812 |
} |
|
813 |
return (allowFirstAllows > 1) || (allowFirstDenys > 1) || (denyFirstAllows > 1) |
|
814 |
|| (denyFirstDenys > 1); |
|
815 |
} |
|
816 | 874 |
|
817 | 875 |
/** |
818 | 876 |
* Populate a job data object with the current row in a resultset |
Also available in: Unified diff
change AccessControlForSingleFile to only be instantiated for one file. move ACL methods to AccessControlForSingleFile. Change format of access sections returned to EML 2.1.0.