Project

General

Profile

« Previous | Next » 

Revision 688

Added by bojilova almost 24 years ago

added new "getaccesscontrol" action for a given docid

View differences:

src/edu/ucsb/nceas/metacat/MetaCatServlet.java
91 91
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog<br>
92 92
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
93 93
 * valtext -- XML text to be validated<br>
94
 * action=getdatadoc -- retreive a stored datadocument<br>
95
 * action=getdoctypes -- retreive all doctypes (publicID)<br>
96
 * action=getdataguide -- retreive a Data Guide<br>
94
 * action=getdatadoc -- retrieve a stored datadocument<br>
95
 * action=getaccesscontrol -- retrieve acl info for Metacat document<br>
96
 * action=getdoctypes -- retrieve all doctypes (publicID)<br>
97
 * action=getdataguide -- retrieve a Data Guide<br>
97 98
 * datadoc -- data document name (id)<br>
98 99
 * <p>
99 100
 * The particular combination of parameters that are valid for each 
......
354 355
      response.setContentType("application/zip");
355 356
      ServletOutputStream out = response.getOutputStream();
356 357
      handleGetDataDocumentAction(out, params, response);  
358
    } else if (action.equals("getaccesscontrol")) {
359
      PrintWriter out = response.getWriter();
360
      handleGetAccessControlAction(out, params, response, username, groupname);
357 361
    } else if (action.equals("getdoctypes")) {
358 362
      PrintWriter out = response.getWriter();
359 363
      handleGetDoctypesAction(out, params, response);  
......
1496 1500
  }
1497 1501
  
1498 1502
  /** 
1499
   * Handle the getdoctypes Action.
1503
   * Handle "getaccesscontrol" action.
1504
   * Read Access Control List from db connection in XML format
1505
   */
1506
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params, 
1507
                                       HttpServletResponse response, 
1508
                                       String username, String groupname) {
1509

  
1510
    Connection conn = null;
1511
    String docid = ((String[])params.get("docid"))[0];
1512
    
1513
    try {
1514

  
1515
        // get connection from the pool
1516
        conn = util.getConnection();
1517
        AccessControlList aclobj = new AccessControlList(conn);
1518
        String acltext = aclobj.getACL(docid, username, groupname);
1519
        out.println(acltext);
1520

  
1521
    } catch (Exception e) {
1522
      out.println("<?xml version=\"1.0\"?>");
1523
      out.println("<error>");
1524
      out.println(e.getMessage());
1525
      out.println("</error>");
1526
    } finally {
1527
      util.returnConnection(conn);
1528
    }  
1529
    
1530
  }
1531

  
1532
  /** 
1533
   * Handle "getdoctypes" action.
1500 1534
   * Read all doctypes from db connection in XML format
1501 1535
   */
1502 1536
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
......
1524 1558
  }
1525 1559

  
1526 1560
  /** 
1527
   * Handle the getdataguide Action.
1561
   * Handle the "getdataguide" action.
1528 1562
   * Read Data Guide for a given doctype from db connection in XML format
1529 1563
   */
1530 1564
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
src/edu/ucsb/nceas/metacat/DocumentImpl.java
1009 1009
    Statement stmt = conn.createStatement();
1010 1010
    stmt.execute("DELETE FROM xml_index WHERE docid = '" + docid + "'");
1011 1011
    stmt.execute("DELETE FROM xml_documents WHERE docid = '" + docid + "'");
1012
    stmt.execute("DELETE FROM xml_access WHERE docid = '" + docid + "'");
1012
    //stmt.execute("DELETE FROM xml_access WHERE docid = '" + docid + "'");
1013 1013
    stmt.execute("DELETE FROM xml_access WHERE accessfileid = '" + docid + "'");
1014 1014
    stmt.execute("DELETE FROM xml_relation WHERE docid = '" + docid + "'");
1015 1015
    stmt.close();
src/edu/ucsb/nceas/metacat/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