Project

General

Profile

« Previous | Next » 

Revision 5098

Added by daigle over 14 years ago

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.

View differences:

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