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 |
}
|
added new "getaccesscontrol" action for a given docid