Revision 688
Added by bojilova about 23 years ago
AccessControlList.java | ||
---|---|---|
86 | 86 |
|
87 | 87 |
/** |
88 | 88 |
* Construct an instance of the AccessControlList class. |
89 |
* It is used by the permission check up from DBQuery and DocumentImpl
|
|
90 |
* and for "getaccesscontrol" action
|
|
89 |
* It is used by the permission check up from DBQuery or DocumentImpl
|
|
90 |
* and from "getaccesscontrol" action
|
|
91 | 91 |
* |
92 | 92 |
* @param conn the JDBC connection where acl info is get |
93 | 93 |
*/ |
... | ... | |
130 | 130 |
this.principal = new Vector(); |
131 | 131 |
this.permission = 0; |
132 | 132 |
this.ticketCount = 0; |
133 |
this.publicAcc = null; |
|
133 | 134 |
this.serverCode = serverCode; |
134 | 135 |
|
135 | 136 |
// Initialize the parser and read the queryspec |
... | ... | |
140 | 141 |
|
141 | 142 |
/** |
142 | 143 |
* Construct an instance of the AccessControlList class. |
143 |
* It parse acl file and loads acl data into db connection. |
|
144 |
* It parses eml-access file and loads acl data into db connection. |
|
145 |
* It is used from command line execution. |
|
144 | 146 |
* |
145 | 147 |
* @param conn the JDBC connection where acl data are loaded |
146 | 148 |
* @param docid the Accession# of the document with the acl data |
147 | 149 |
* @param aclfilename the name of acl file containing acl data |
150 |
* @param user the user connected to MetaCat servlet and owns the document |
|
151 |
* @param group the group to which user belongs |
|
148 | 152 |
*/ |
149 | 153 |
public AccessControlList( Connection conn, String aclid, String aclfilename, |
150 | 154 |
String user, String group ) |
... | ... | |
181 | 185 |
} |
182 | 186 |
|
183 | 187 |
/** |
184 |
* callback method used by the SAX Parser when beginning of the document
|
|
188 |
* Callback method used by the SAX Parser when beginning of the document
|
|
185 | 189 |
*/ |
186 | 190 |
public void startDocument() throws SAXException |
187 | 191 |
{ |
... | ... | |
200 | 204 |
} |
201 | 205 |
|
202 | 206 |
/** |
203 |
* callback method used by the SAX Parser when the start tag of an
|
|
207 |
* Callback method used by the SAX Parser when the start tag of an
|
|
204 | 208 |
* element is detected. Used in this context to parse and store |
205 | 209 |
* the acl information in class variables. |
206 | 210 |
*/ |
... | ... | |
223 | 227 |
} |
224 | 228 |
|
225 | 229 |
/** |
226 |
* callback method used by the SAX Parser when the text sequences of an
|
|
230 |
* Callback method used by the SAX Parser when the text sequences of an
|
|
227 | 231 |
* xml stream are detected. Used in this context to parse and store |
228 | 232 |
* the acl information in class variables. |
229 | 233 |
*/ |
... | ... | |
304 | 308 |
} |
305 | 309 |
|
306 | 310 |
/** |
307 |
* callback method used by the SAX Parser when the end tag of an
|
|
311 |
* Callback method used by the SAX Parser when the end tag of an
|
|
308 | 312 |
* element is detected. Used in this context to parse and store |
309 | 313 |
* the acl information in class variables. |
310 | 314 |
*/ |
311 | 315 |
public void endElement (String uri, String localName, String qName) |
312 | 316 |
throws SAXException |
313 | 317 |
{ |
314 |
BasicNode leaving = (BasicNode)elementStack.pop(); |
|
315 |
if ( leaving.getTagName().equals("resourceIdentifier") ) { |
|
318 |
BasicNode leaving = (BasicNode)elementStack.pop(); |
|
319 |
String leavingTagName = leaving.getTagName(); |
|
320 |
|
|
321 |
if ( leavingTagName.equals("resourceIdentifier") ) { |
|
316 | 322 |
|
317 | 323 |
try { |
318 | 324 |
// make a relationship for @aclid on the current resource(docurl) |
... | ... | |
323 | 329 |
throw new SAXException(sqle); |
324 | 330 |
} |
325 | 331 |
|
326 |
} else if ( leaving.getTagName().equals("allow") ) { |
|
332 |
} else if ( leavingTagName.equals("allow") || |
|
333 |
leavingTagName.equals("deny") ) { |
|
327 | 334 |
|
328 | 335 |
if ( permission > 0 ) { |
329 | 336 |
|
330 | 337 |
// insert into db calculated permission for the list of principals |
331 | 338 |
try { |
332 |
insertPermissions("allowed");
|
|
339 |
insertPermissions(leavingTagName);
|
|
333 | 340 |
} catch (SQLException sqle) { |
334 | 341 |
throw new SAXException(sqle); |
335 | 342 |
} |
336 | 343 |
} |
337 | 344 |
|
338 |
// reset the allowed permission
|
|
345 |
// reset the allow/deny permission
|
|
339 | 346 |
principal = new Vector(); |
340 | 347 |
permission = 0; |
341 | 348 |
beginTime = null; |
342 | 349 |
endTime = null; |
343 | 350 |
ticketCount = 0; |
344 | 351 |
|
345 |
} else if ( leaving.getTagName().equals("deny") ) { |
|
346 |
|
|
347 |
if ( permission > 0 ) { |
|
352 |
} else if ( leavingTagName.equals("resource") ) { |
|
348 | 353 |
|
349 |
// insert into db calculated permission for the list of principals |
|
354 |
// update public access for the list of resources |
|
355 |
if ( publicAcc != null ) { |
|
350 | 356 |
try { |
351 |
insertPermissions("denied");
|
|
357 |
updatePublicAccess(publicAcc);
|
|
352 | 358 |
} catch (SQLException sqle) { |
353 | 359 |
throw new SAXException(sqle); |
354 | 360 |
} |
355 | 361 |
} |
356 |
|
|
357 |
// reset the denied permission |
|
358 |
principal = new Vector(); |
|
359 |
permission = 0; |
|
360 |
beginTime = null; |
|
361 |
endTime = null; |
|
362 |
ticketCount = 0; |
|
363 |
|
|
364 |
} else if ( leaving.getTagName().equals("resource") ) { |
|
365 |
|
|
366 |
// update public access for the list of resources |
|
367 |
try { |
|
368 |
updatePublicAccess(publicAcc); |
|
369 |
} catch (SQLException sqle) { |
|
370 |
throw new SAXException(sqle); |
|
371 |
} |
|
372 | 362 |
|
373 | 363 |
// reset the resource |
374 | 364 |
resourceID = new Vector(); |
... | ... | |
379 | 369 |
|
380 | 370 |
} |
381 | 371 |
|
382 |
/** SAX Handler that receives notification of DOCTYPE. Sets the DTD */ |
|
372 |
/** |
|
373 |
* SAX Handler that receives notification of DOCTYPE. Sets the DTD. |
|
374 |
* @param name name of the DTD |
|
375 |
* @param publicId Public Identifier of the DTD |
|
376 |
* @param systemId System Identifier of the DTD |
|
377 |
*/ |
|
383 | 378 |
public void startDTD(String name, String publicId, String systemId) |
384 | 379 |
throws SAXException { |
385 | 380 |
docname = name; |
... | ... | |
389 | 384 |
} |
390 | 385 |
|
391 | 386 |
/** |
392 |
* SAX Handler that receives notification of the start of entities |
|
387 |
* SAX Handler that receives notification of the start of entities. |
|
388 |
* @param name name of the entity |
|
393 | 389 |
*/ |
394 | 390 |
public void startEntity(String name) throws SAXException { |
395 | 391 |
if (name.equals("[dtd]")) { |
... | ... | |
398 | 394 |
} |
399 | 395 |
|
400 | 396 |
/** |
401 |
* SAX Handler that receives notification of the end of entities |
|
397 |
* SAX Handler that receives notification of the end of entities. |
|
398 |
* @param name name of the entity |
|
402 | 399 |
*/ |
403 | 400 |
public void endEntity(String name) throws SAXException { |
404 | 401 |
if (name.equals("[dtd]")) { |
... | ... | |
407 | 404 |
} |
408 | 405 |
|
409 | 406 |
/** |
410 |
* get the document name
|
|
407 |
* Get the document name.
|
|
411 | 408 |
*/ |
412 | 409 |
public String getDocname() { |
413 | 410 |
return docname; |
414 | 411 |
} |
415 | 412 |
|
416 | 413 |
/** |
417 |
* get the document processing state
|
|
414 |
* Get the document processing state.
|
|
418 | 415 |
*/ |
419 | 416 |
public boolean processingDTD() { |
420 | 417 |
return processingDTD; |
421 | 418 |
} |
422 | 419 |
|
423 |
/** Delete from db all permission for resources related to @aclid if any */
|
|
420 |
/* Delete from db all permission for resources related to @aclid if any.*/
|
|
424 | 421 |
private void deletePermissionsForRelatedResources(String aclid) |
425 | 422 |
throws SQLException |
426 | 423 |
{ |
... | ... | |
430 | 427 |
stmt.close(); |
431 | 428 |
} |
432 | 429 |
|
433 |
/** |
|
434 |
* Deletes all of the relations with a docid of @docid. |
|
435 |
* @param docid the docid to delete. |
|
436 |
*/ |
|
437 |
public void deleteRelations(String docid) |
|
430 |
/* Delete all of the relations with a docid of @docid from db connection.*/ |
|
431 |
private void deleteRelations(String docid) |
|
438 | 432 |
throws SQLException |
439 | 433 |
{ |
440 | 434 |
Statement stmt = conn.createStatement(); |
... | ... | |
442 | 436 |
stmt.close(); |
443 | 437 |
} |
444 | 438 |
|
445 |
/** Insert relationship into db for @aclid on @resourceURL */
|
|
439 |
/* Insert relationship for @aclid on @resourceURL into db connection.*/
|
|
446 | 440 |
private void insertRelation(String aclid, String resourceURL) |
447 | 441 |
throws SQLException |
448 | 442 |
{ |
... | ... | |
462 | 456 |
pstmt.close(); |
463 | 457 |
} |
464 | 458 |
|
465 |
/** Insert into db calculated permission for the list of principals */
|
|
459 |
/* Insert into db calculated permission for the list of principals */ |
|
466 | 460 |
private void insertPermissions( String permType ) |
467 | 461 |
throws SQLException |
468 | 462 |
{ |
... | ... | |
486 | 480 |
} else { |
487 | 481 |
pstmt.setString(8, ""); |
488 | 482 |
} |
483 |
String docid; |
|
484 |
String prName; |
|
489 | 485 |
for ( int i = 0; i < resourceID.size(); i++ ) { |
490 |
pstmt.setString(1, (String)resourceID.elementAt(i)); |
|
486 |
docid = (String)resourceID.elementAt(i); |
|
487 |
pstmt.setString(1, docid); |
|
491 | 488 |
for ( int j = 0; j < principal.size(); j++ ) { |
492 |
pstmt.setString(2, (String)principal.elementAt(j)); |
|
489 |
prName = (String)principal.elementAt(j); |
|
490 |
pstmt.setString(2, prName); |
|
493 | 491 |
pstmt.execute(); |
492 |
|
|
493 |
// check if there are conflict with permission's order |
|
494 |
String permOrderOpos = permOrder; |
|
495 |
int perm = getPermissions(permission, prName, docid, permOrder); |
|
496 |
if ( perm != 0 ) { |
|
497 |
if ( permOrder.equals("allowFirst") ) { |
|
498 |
permOrderOpos = "denyFirst"; |
|
499 |
} else if ( permOrder.equals("denyFirst") ) { |
|
500 |
permOrderOpos = "allowFirst"; |
|
501 |
} |
|
502 |
throw new SQLException("Permission(s) " + txtValue(perm) + |
|
503 |
" for \"" + prName + "\" on document #" + docid + |
|
504 |
" has/have been used with \"" + permOrderOpos + "\""); |
|
505 |
} |
|
494 | 506 |
} |
495 | 507 |
} |
496 | 508 |
pstmt.close(); |
... | ... | |
501 | 513 |
} |
502 | 514 |
} |
503 | 515 |
|
504 |
/** Update into db public read access for the list of resources */
|
|
516 |
/* Update into db public "read" access for the list of resources. */
|
|
505 | 517 |
private void updatePublicAccess(String publicAcc) |
506 | 518 |
throws SQLException |
507 | 519 |
{ |
... | ... | |
530 | 542 |
} |
531 | 543 |
} |
532 | 544 |
|
533 |
/** Check for @permission for @principal on @resourceID from db connection */ |
|
545 |
/* Get permissions with permission order different than @permOrder. */ |
|
546 |
private int getPermissions(int permission, String principal, |
|
547 |
String docid, String permOrder) |
|
548 |
throws SQLException |
|
549 |
{ |
|
550 |
PreparedStatement pstmt; |
|
551 |
pstmt = conn.prepareStatement( |
|
552 |
"SELECT permission FROM xml_access " + |
|
553 |
"WHERE docid LIKE ? " + |
|
554 |
"AND principal_name LIKE ? " + |
|
555 |
"AND perm_order NOT LIKE ?"); |
|
556 |
pstmt.setString(1, docid); |
|
557 |
pstmt.setString(2, principal); |
|
558 |
pstmt.setString(3, permOrder); |
|
559 |
pstmt.execute(); |
|
560 |
ResultSet rs = pstmt.getResultSet(); |
|
561 |
boolean hasRow = rs.next(); |
|
562 |
int perm = 0; |
|
563 |
while ( hasRow ) { |
|
564 |
perm = rs.getInt(1); |
|
565 |
perm = permission & perm; |
|
566 |
if ( perm != 0 ) { |
|
567 |
pstmt.close(); |
|
568 |
return perm; |
|
569 |
} |
|
570 |
hasRow = rs.next(); |
|
571 |
} |
|
572 |
pstmt.close(); |
|
573 |
return 0; |
|
574 |
} |
|
575 |
|
|
576 |
/* Get the int value of READ, WRITE or ALL. */ |
|
577 |
private int intValue ( String permission ) |
|
578 |
{ |
|
579 |
if ( permission.equals("READ") ) { |
|
580 |
return READ; |
|
581 |
} else if ( permission.equals("WRITE") ) { |
|
582 |
return WRITE; |
|
583 |
} else if ( permission.equals("ALL") ) { |
|
584 |
return ALL; |
|
585 |
} |
|
586 |
|
|
587 |
return -1; |
|
588 |
} |
|
589 |
|
|
590 |
/* Get the text value of READ, WRITE or ALL. */ |
|
591 |
private String txtValue ( int permission ) |
|
592 |
{ |
|
593 |
StringBuffer txtPerm = new StringBuffer("\""); |
|
594 |
if ( (permission & READ) != 0 ) { |
|
595 |
txtPerm.append("read"); |
|
596 |
} |
|
597 |
if ( (permission & WRITE) != 0 ) { |
|
598 |
if ( txtPerm.length() > 0 ) txtPerm.append(","); |
|
599 |
txtPerm.append("write"); |
|
600 |
} |
|
601 |
if ( (permission & ALL) != 0 ) { |
|
602 |
if ( txtPerm.length() > 0 ) txtPerm.append(","); |
|
603 |
txtPerm.append("all"); |
|
604 |
} |
|
605 |
|
|
606 |
return txtPerm.append("\"").toString(); |
|
607 |
} |
|
608 |
|
|
609 |
/* Read docid from @url. */ |
|
610 |
private String getDocid ( String url ) throws SAXException |
|
611 |
{ |
|
612 |
MetaCatUtil util = new MetaCatUtil(); |
|
613 |
try { |
|
614 |
URL urlobj = new URL(url); |
|
615 |
Hashtable urlParams = util.parseQuery(urlobj.getQuery()); |
|
616 |
if ( urlParams.containsKey("docid") ) { |
|
617 |
return (String)urlParams.get("docid"); // return the docid value |
|
618 |
} else { |
|
619 |
throw new |
|
620 |
SAXException("\"docid\" not specified within " + url); |
|
621 |
} |
|
622 |
} catch (MalformedURLException e) { |
|
623 |
throw new SAXException(e.getMessage()); |
|
624 |
} |
|
625 |
} |
|
626 |
|
|
627 |
|
|
628 |
/** |
|
629 |
* Check from db connection if @principal has @permission on @resourceID. |
|
630 |
* @param permission permission type to check for |
|
631 |
* @param principal name of principal to check for @permission |
|
632 |
* @param resourceID resource identifier to check on |
|
633 |
*/ |
|
534 | 634 |
public boolean hasPermission ( String permission, |
535 | 635 |
String principal, String resourceID ) |
536 | 636 |
throws SQLException |
... | ... | |
556 | 656 |
|
557 | 657 |
} catch (SQLException e) { |
558 | 658 |
throw new |
559 |
SQLException("AccessControlList.hasPermission(): " +
|
|
560 |
"Error checking document's public access. " +
|
|
561 |
e.getMessage()); |
|
659 |
SQLException("AccessControlList.hasPermission(). " +
|
|
660 |
"Error checking public access for document #"+resourceID+
|
|
661 |
". " + e.getMessage());
|
|
562 | 662 |
} |
563 | 663 |
} |
564 | 664 |
|
... | ... | |
584 | 684 |
|
585 | 685 |
} catch (SQLException e) { |
586 | 686 |
throw new |
587 |
SQLException("AccessControlList.hasPermission(): " + |
|
588 |
"Error checking document's ownership. " + e.getMessage()); |
|
687 |
SQLException("AccessControlList.hasPermission(). " + |
|
688 |
"Error checking ownership for " + principal + |
|
689 |
" on document #" + resourceID + ". " + e.getMessage()); |
|
589 | 690 |
} |
590 | 691 |
|
591 | 692 |
// check @principal's @permission on @resourceID from xml_access table |
... | ... | |
598 | 699 |
"FROM xml_access " + |
599 | 700 |
"WHERE docid LIKE ? " + |
600 | 701 |
"AND principal_name LIKE ? " + |
702 |
"AND perm_type LIKE ? " + |
|
601 | 703 |
"AND sysdate BETWEEN nvl(begin_time,sysdate) " + |
602 |
"AND nvl(end_time,sysdate) " + |
|
603 |
"AND perm_type LIKE ?"); |
|
604 |
// check if it is "denied" first |
|
704 |
"AND nvl(end_time,sysdate)"); |
|
705 |
// check if it is "deny" with "allowFirst" first |
|
605 | 706 |
// Bind the values to the query |
606 | 707 |
pstmt.setString(1, resourceID); |
607 | 708 |
pstmt.setString(2, principal); |
608 |
pstmt.setString(3, "denied");
|
|
709 |
pstmt.setString(3, "deny");
|
|
609 | 710 |
|
610 | 711 |
pstmt.execute(); |
611 | 712 |
ResultSet rs = pstmt.getResultSet(); |
... | ... | |
618 | 719 |
( permOrder.equals("allowFirst") ) && |
619 | 720 |
( rs.wasNull() || ticketCount > 0 ) ) { |
620 | 721 |
if ( !rs.wasNull() && ticketCount > 0 ) { |
621 |
decreaseNumberOfAccess(accessValue,principal,resourceID,"denied");
|
|
722 |
decreaseNumberOfAccess(accessValue,principal,resourceID,"deny","allowFirst");
|
|
622 | 723 |
} |
623 | 724 |
pstmt.close(); |
624 | 725 |
return false; |
625 | 726 |
} |
626 | 727 |
hasRows = rs.next(); |
627 | 728 |
} |
628 |
//System.out.println("Passed the check for denied access");
|
|
729 |
//System.out.println("Passed the check for \"deny\" access with \"allowFirst\"");
|
|
629 | 730 |
|
630 |
// it is not denied then check if it is "allowed"
|
|
731 |
// it is not denied then check if it is "allow" |
|
631 | 732 |
// Bind the values to the query |
632 | 733 |
pstmt.setString(1, resourceID); |
633 | 734 |
pstmt.setString(2, principal); |
634 |
pstmt.setString(3, "allowed");
|
|
735 |
pstmt.setString(3, "allow"); |
|
635 | 736 |
|
636 | 737 |
pstmt.execute(); |
637 | 738 |
rs = pstmt.getResultSet(); |
638 | 739 |
hasRows = rs.next(); |
639 | 740 |
while ( hasRows ) { |
640 | 741 |
accessValue = rs.getInt(1); |
742 |
permOrder = rs.getString(2); |
|
641 | 743 |
ticketCount = rs.getInt(3); |
642 | 744 |
if ( ( accessValue & intValue(permission) )==intValue(permission) && |
643 | 745 |
( rs.wasNull() || ticketCount > 0 ) ) { |
644 | 746 |
if ( !rs.wasNull() && ticketCount > 0 ) { |
645 |
decreaseNumberOfAccess(accessValue,principal,resourceID,"allowed");
|
|
747 |
decreaseNumberOfAccess(accessValue,principal,resourceID,"allow",permOrder);
|
|
646 | 748 |
} |
647 | 749 |
pstmt.close(); |
648 | 750 |
return true; |
649 | 751 |
} |
650 | 752 |
hasRows = rs.next(); |
651 | 753 |
} |
652 |
//System.out.println("Passed the check for allowed access");
|
|
754 |
//System.out.println("Passed the check for \"allow\" access");
|
|
653 | 755 |
|
654 |
// ??? |
|
655 |
// here there could be a check for the group's permission like |
|
656 |
// selfrecursive call to hasPermission(conn,permission,group,recourceId) |
|
657 |
// |
|
756 |
// it is not allowed then check if it is "deny" with "denyFirst" |
|
757 |
// Bind the values to the query |
|
758 |
pstmt.setString(1, resourceID); |
|
759 |
pstmt.setString(2, principal); |
|
760 |
pstmt.setString(3, "deny"); |
|
761 |
|
|
762 |
pstmt.execute(); |
|
763 |
rs = pstmt.getResultSet(); |
|
764 |
hasRows = rs.next(); |
|
765 |
while ( hasRows ) { |
|
766 |
accessValue = rs.getInt(1); |
|
767 |
permOrder = rs.getString(2); |
|
768 |
ticketCount = rs.getInt(3); |
|
769 |
if ( ( accessValue & intValue(permission) ) == intValue(permission) && |
|
770 |
( permOrder.equals("denyFirst") ) && |
|
771 |
( rs.wasNull() || ticketCount > 0 ) ) { |
|
772 |
if ( !rs.wasNull() && ticketCount > 0 ) { |
|
773 |
decreaseNumberOfAccess(accessValue,principal,resourceID,"deny","denyFirst"); |
|
774 |
} |
|
775 |
pstmt.close(); |
|
776 |
return false; |
|
777 |
} |
|
778 |
hasRows = rs.next(); |
|
779 |
} |
|
780 |
//System.out.println("Passed the check for \"deny\" access wirh \"denyFirst\""); |
|
658 | 781 |
|
659 | 782 |
pstmt.close(); |
660 | 783 |
return false; |
661 | 784 |
|
662 | 785 |
} catch (SQLException e) { |
663 | 786 |
throw new |
664 |
SQLException("AccessControlList.hasPermission(): " + |
|
665 |
"Error checking document's permission. " + e.getMessage()); |
|
787 |
SQLException("AccessControlList.hasPermission(). " + |
|
788 |
"Error checking " + permission + " permission for " + |
|
789 |
principal + " on document #" + resourceID + ". " + |
|
790 |
e.getMessage()); |
|
666 | 791 |
} |
667 | 792 |
} |
668 | 793 |
|
669 | 794 |
return false; |
670 | 795 |
} |
671 | 796 |
|
672 |
/** decrease the number of access to @resourceID for @principal */
|
|
797 |
/* Decrease the number of access to @resourceID for @principal in db. */
|
|
673 | 798 |
private void decreaseNumberOfAccess(int permission, String principal, |
674 |
String resourceID, String permType) |
|
799 |
String resourceID, String permType, |
|
800 |
String permOrder) |
|
675 | 801 |
throws SQLException |
676 | 802 |
{ |
677 | 803 |
PreparedStatement pstmt; |
... | ... | |
680 | 806 |
"WHERE docid LIKE ? " + |
681 | 807 |
"AND principal_name LIKE ? " + |
682 | 808 |
"AND permission LIKE ? " + |
809 |
"AND perm_type LIKE ? " + |
|
810 |
"AND perm_order LIKE ? " + |
|
683 | 811 |
"AND sysdate BETWEEN nvl(begin_time,sysdate) " + |
684 |
"AND nvl(end_time,sysdate) " + |
|
685 |
"AND perm_type LIKE ?"); |
|
812 |
"AND nvl(end_time,sysdate)"); |
|
686 | 813 |
// Bind the values to the query |
687 | 814 |
pstmt.setString(1, resourceID); |
688 | 815 |
pstmt.setString(2, principal); |
689 | 816 |
pstmt.setInt(3, permission); |
690 | 817 |
pstmt.setString(4, permType); |
818 |
pstmt.setString(5, permOrder); |
|
691 | 819 |
|
692 | 820 |
pstmt.execute(); |
693 | 821 |
pstmt.close(); |
694 | 822 |
} |
695 | 823 |
|
696 |
// get the int value of READ, WRITE or ALL |
|
697 |
private int intValue ( String permission ) |
|
824 |
|
|
825 |
/** |
|
826 |
* Get Access Control List information for document from db connetion. |
|
827 |
* User or Group should have permissions for reading |
|
828 |
* access control information for a document specified by @docid. |
|
829 |
* @param docid document identifier which acl info to get |
|
830 |
* @param user name of user connected to Metacat system |
|
831 |
* @param group name of user's group to which user belongs |
|
832 |
*/ |
|
833 |
public String getACL(String docid, String user, String group) |
|
834 |
throws SQLException |
|
698 | 835 |
{ |
699 |
if ( permission.equals("READ") ) { |
|
700 |
return READ; |
|
701 |
} else if ( permission.equals("WRITE") ) { |
|
702 |
return WRITE; |
|
703 |
} else if ( permission.equals("ALL") ) { |
|
704 |
return ALL; |
|
705 |
} |
|
836 |
StringBuffer output = new StringBuffer(); |
|
837 |
StringBuffer outTemp = new StringBuffer(); |
|
838 |
MetaCatUtil util = new MetaCatUtil(); |
|
839 |
String accDoctype = util.getOption("accessdoctype"); |
|
840 |
String server = util.getOption("server"); |
|
841 |
String docurl = "metacat://" + server + "/?docid=" + docid; |
|
842 |
String systemID; |
|
843 |
boolean isOwned = false; |
|
844 |
boolean hasPermission = false; |
|
845 |
String publicAcc; |
|
706 | 846 |
|
707 |
return -1; |
|
708 |
} |
|
709 |
|
|
710 |
// get docid from @url |
|
711 |
private String getDocid ( String url ) throws SAXException |
|
712 |
{ |
|
713 |
MetaCatUtil util = new MetaCatUtil(); |
|
847 |
String acfid = ""; |
|
848 |
String acfid_prev = ""; |
|
849 |
String principal; |
|
850 |
Vector principalArr = new Vector(); |
|
851 |
int permission; |
|
852 |
int perm_prev = -1; |
|
853 |
String permType; |
|
854 |
String permOrder = ""; |
|
855 |
String permOrder_prev = ""; |
|
856 |
String beginTime = ""; |
|
857 |
String begin_prev = ""; |
|
858 |
String endTime = ""; |
|
859 |
String end_prev = ""; |
|
860 |
int ticketCount = -1; |
|
861 |
int ticket_prev = -1; |
|
862 |
|
|
714 | 863 |
try { |
715 |
URL urlobj = new URL(url); |
|
716 |
Hashtable urlParams = util.parseQuery(urlobj.getQuery()); |
|
717 |
if ( urlParams.containsKey("docid") ) { |
|
718 |
return (String)urlParams.get("docid"); // return the docid value |
|
719 |
} else { |
|
720 |
throw new |
|
721 |
SAXException("\"docid\" not specified within " + url); |
|
864 |
|
|
865 |
isOwned = isOwned(docid, user); |
|
866 |
systemID = getSystemID(accDoctype); |
|
867 |
publicAcc = getPublicAccess(docid); |
|
868 |
|
|
869 |
output.append("<?xml version=\"1.0\"?>\n"); |
|
870 |
output.append("<!DOCTYPE acl PUBLIC \"" + accDoctype + "\" \"" + |
|
871 |
systemID + "\">\n"); |
|
872 |
output.append("<acl authSystem=\"\">\n"); |
|
873 |
|
|
874 |
PreparedStatement pstmt; |
|
875 |
pstmt = conn.prepareStatement( |
|
876 |
"SELECT distinct accessfileid, principal_name, permission, " + |
|
877 |
"perm_type, perm_order, to_char(begin_time,'mm/dd/yyyy'), " + |
|
878 |
"to_char(end_time,'mm/dd/yyyy'), ticket_count " + |
|
879 |
"FROM xml_access WHERE docid LIKE ? " + |
|
880 |
"ORDER BY accessfileid, perm_order, perm_type, permission"); |
|
881 |
// Bind the values to the query |
|
882 |
pstmt.setString(1, docid); |
|
883 |
pstmt.execute(); |
|
884 |
ResultSet rs = pstmt.getResultSet(); |
|
885 |
boolean hasRows = rs.next(); |
|
886 |
while (hasRows) { |
|
887 |
|
|
888 |
acfid = rs.getString(1); |
|
889 |
principal = rs.getString(2); |
|
890 |
permission = rs.getInt(3); |
|
891 |
permType = rs.getString(4); |
|
892 |
permOrder = rs.getString(5); |
|
893 |
beginTime = rs.getString(6); |
|
894 |
endTime = rs.getString(7); |
|
895 |
ticketCount = rs.getInt(8); |
|
896 |
|
|
897 |
// if @docid is not owned by @user, only ACL info from that |
|
898 |
// access files to which @user/@group has "read" permission |
|
899 |
// is extracted |
|
900 |
if ( !isOwned ) { |
|
901 |
if ( !acfid.equals(acfid_prev) ) { |
|
902 |
acfid_prev = acfid; |
|
903 |
hasPermission = hasPermission("READ",user,acfid); |
|
904 |
if ( !hasPermission && group != null ) { |
|
905 |
hasPermission = hasPermission("READ",group,acfid); |
|
906 |
} |
|
907 |
} |
|
908 |
if ( !hasPermission ) { |
|
909 |
rs.next(); |
|
910 |
continue; |
|
911 |
} |
|
912 |
} |
|
913 |
|
|
914 |
// open <resource> tag |
|
915 |
if ( !permOrder.equals(permOrder_prev) ) { |
|
916 |
// close </resource> tag if any was opened |
|
917 |
output.append(outTemp.toString()); |
|
918 |
outTemp = new StringBuffer(); |
|
919 |
if ( !permOrder_prev.equals("") ) { |
|
920 |
output.append(" </resource>\n"); |
|
921 |
} |
|
922 |
output.append(" <resource order=\"" + permOrder + "\" public=\"" + |
|
923 |
publicAcc + "\">\n"); |
|
924 |
output.append(" <resourceIdentifier>" + docurl + |
|
925 |
"</resourceIdentifier>\n"); |
|
926 |
permOrder_prev = permOrder; |
|
927 |
} |
|
928 |
|
|
929 |
// close </allow> or </deny> tag then open new one |
|
930 |
if ( permission != perm_prev || |
|
931 |
(endTime == null) && (end_prev != null) || |
|
932 |
(beginTime == null) && (begin_prev != null) || |
|
933 |
endTime != null && !endTime.equals(end_prev) || |
|
934 |
beginTime != null && !beginTime.equals(begin_prev) || |
|
935 |
ticketCount != ticket_prev ) { |
|
936 |
output.append(outTemp.toString()); |
|
937 |
outTemp = new StringBuffer(); |
|
938 |
principalArr.removeAllElements(); |
|
939 |
output.append(" <" + permType + ">\n"); |
|
940 |
} |
|
941 |
|
|
942 |
// put all principals here for the same |
|
943 |
// permission, duration and ticket_count |
|
944 |
if ( !principalArr.contains(principal) ) { |
|
945 |
principalArr.addElement(principal); |
|
946 |
output.append(" <principal>" + principal + "</principal>\n"); |
|
947 |
} |
|
948 |
|
|
949 |
// prepare <permission> tags, <duration> and <ticketCount> |
|
950 |
// if any to put within <allow> (<deny>) by next cicle |
|
951 |
if ( permission != perm_prev || |
|
952 |
(endTime == null) && (end_prev != null) || |
|
953 |
(beginTime == null) && (begin_prev != null) || |
|
954 |
endTime != null && !endTime.equals(end_prev) || |
|
955 |
beginTime != null && !beginTime.equals(begin_prev) || |
|
956 |
ticketCount != ticket_prev ) { |
|
957 |
if ( (permission & READ) != 0 ) { |
|
958 |
outTemp.append(" <permission>read</permission>\n"); |
|
959 |
} |
|
960 |
if ( (permission & WRITE) != 0 ) { |
|
961 |
outTemp.append(" <permission>write</permission>\n"); |
|
962 |
} |
|
963 |
if ( (permission & ALL) != 0 ) { |
|
964 |
outTemp.append(" <permission>all</permission>\n"); |
|
965 |
} |
|
966 |
if ( (beginTime != null) || (endTime != null) ) { |
|
967 |
outTemp.append(" <duration>" + beginTime + " " + endTime + |
|
968 |
"</duration>\n"); |
|
969 |
} |
|
970 |
if ( ticketCount > 0 ) { |
|
971 |
outTemp.append(" <ticketCount>" + ticketCount + |
|
972 |
"</ticketCount>\n"); |
|
973 |
} |
|
974 |
outTemp.append(" </" + permType + ">\n"); |
|
975 |
perm_prev = permission; |
|
976 |
ticket_prev = ticketCount; |
|
977 |
begin_prev = beginTime; |
|
978 |
end_prev = endTime; |
|
979 |
} |
|
980 |
|
|
981 |
hasRows = rs.next(); |
|
722 | 982 |
} |
723 |
} catch (MalformedURLException e) { |
|
724 |
throw new SAXException(e.getMessage()); |
|
983 |
|
|
984 |
// close <allow> or <deny> if anything left in outTemp var |
|
985 |
output.append(outTemp.toString()); |
|
986 |
|
|
987 |
// If there are no any acl info for @docid accessible by @user/@group, |
|
988 |
// extract only the following information |
|
989 |
if ( permOrder.equals("") ) { |
|
990 |
output.append(" <resource public=\"" + publicAcc + "\">\n"); |
|
991 |
output.append(" <resourceIdentifier>" + docurl + |
|
992 |
"</resourceIdentifier>\n"); |
|
993 |
} |
|
994 |
|
|
995 |
// always close them |
|
996 |
output.append(" </resource>\n"); |
|
997 |
output.append("</acl>\n"); |
|
998 |
|
|
999 |
pstmt.close(); |
|
1000 |
|
|
1001 |
return output.toString(); |
|
1002 |
|
|
1003 |
} catch (SQLException e) { |
|
1004 |
throw new |
|
1005 |
SQLException("AccessControlList.getACL(). " + e.getMessage()); |
|
725 | 1006 |
} |
726 |
} |
|
1007 |
} |
|
1008 |
|
|
1009 |
/* Check if @user is owner of @docid from db conn. */ |
|
1010 |
private boolean isOwned(String docid, String user) throws SQLException { |
|
1011 |
|
|
1012 |
PreparedStatement pstmt; |
|
1013 |
pstmt = conn.prepareStatement("SELECT 'x' FROM xml_documents " + |
|
1014 |
"WHERE docid LIKE ? " + |
|
1015 |
"AND user_owner LIKE ?"); |
|
1016 |
pstmt.setString(1, docid); |
|
1017 |
pstmt.setString(2, user); |
|
1018 |
pstmt.execute(); |
|
1019 |
ResultSet rs = pstmt.getResultSet(); |
|
1020 |
boolean hasRow = rs.next(); |
|
1021 |
|
|
1022 |
return hasRow; |
|
1023 |
} |
|
727 | 1024 |
|
1025 |
/* Get the flag for public "read" access for @docid from db conn. */ |
|
1026 |
private String getPublicAccess(String docid) throws SQLException { |
|
1027 |
|
|
1028 |
int publicAcc = 0; |
|
1029 |
PreparedStatement pstmt; |
|
1030 |
pstmt = conn.prepareStatement("SELECT public_access FROM xml_documents " + |
|
1031 |
"WHERE docid LIKE ?"); |
|
1032 |
pstmt.setString(1, docid); |
|
1033 |
pstmt.execute(); |
|
1034 |
ResultSet rs = pstmt.getResultSet(); |
|
1035 |
boolean hasRow = rs.next(); |
|
1036 |
if ( hasRow ) { |
|
1037 |
publicAcc = rs.getInt(1); |
|
1038 |
} |
|
1039 |
|
|
1040 |
return (publicAcc == 1) ? "yes" : "no"; |
|
1041 |
} |
|
1042 |
|
|
1043 |
/* Get SystemID for @publicID from Metacat DB Catalog. */ |
|
1044 |
private String getSystemID(String publicID) throws SQLException { |
|
1045 |
|
|
1046 |
String systemID = ""; |
|
1047 |
PreparedStatement pstmt; |
|
1048 |
pstmt = conn.prepareStatement("SELECT system_id FROM xml_catalog " + |
|
1049 |
"WHERE entry_type = 'DTD' " + |
|
1050 |
"AND public_id LIKE ?"); |
|
1051 |
pstmt.setString(1, publicID); |
|
1052 |
pstmt.execute(); |
|
1053 |
ResultSet rs = pstmt.getResultSet(); |
|
1054 |
boolean hasRow = rs.next(); |
|
1055 |
if ( hasRow ) { |
|
1056 |
systemID = rs.getString(1); |
|
1057 |
} |
|
1058 |
|
|
1059 |
return systemID; |
|
1060 |
} |
|
1061 |
|
|
728 | 1062 |
} |
Also available in: Unified diff
added new "getaccesscontrol" action for a given docid