Project

General

Profile

« Previous | Next » 

Revision 951

Added by Jing Tao almost 23 years ago

The two hasPermission methods were rewritten. Some logic bugs were fixed. Now user, public and group will not be checked speratedly, but they will be check together as string array. In order to do this, private methods isAccessDocument, containDocumentOwner, isAllowFirst, hasAllowRule, hasExplicitDenyRule, hasImplicitDenyRule, and createUsersPackage were added.

View differences:

src/edu/ucsb/nceas/metacat/AccessControlList.java
58 58
  private static final int WRITE = 2;
59 59
  private static final int READ = 4;
60 60
  private static final int ALL = 7;
61
  private static final String ALLOWFIRST="allowFirst";
62
  private static final String DENYFIRST="denyFirst";
63
  private static final String ALLOW="allow";
64
  private static final String DENY="deny";
65
  private static final String PUBLIC="public";
61 66
  private static String sysdate = MetaCatUtil.dbAdapter.getDateTimeFunction();
62 67
  private static String isnull = MetaCatUtil.dbAdapter.getIsNULLFunction();
63 68

  
......
545 550
    return txtPerm.append("\"").toString();
546 551
  }
547 552

  
553
  
548 554
  /**
555
    * Check if a document id is a access document. Access document need user
556
    * has "all" permission to access it.
557
    * @param docId, the document id need to be checked
558
    */
559
    private boolean isAccessDocument(String docId) throws SQLException
560
    {
561
      //detele the rev number if docid contains it
562
      docId=MetaCatUtil.getDocIdFromString(docId);
563
      PreparedStatement pStmt=null;
564
      try
565
      {
566
        pStmt = conn.prepareStatement("select 'x' from xml_access where " +
567
                                      "accessfileid like '" + docId +  "'");
568
        pStmt.execute();
569
        ResultSet rs = pStmt.getResultSet();
570
        boolean hasRow = rs.next();
571
        pStmt.close();
572
        if(hasRow)
573
        {
574
          return true;
575
        }
576
      }
577
      catch(SQLException e)
578
      {
579
        pStmt.close();
580
        throw new SQLException("AccessControlList.hasPermission():2 " +
581
                     "Error checking ownership for " + principal +
582
                     " on document #" + docId + ". " + e.getMessage());
583
      }
584
      return false;
585
    }//isAccessDocument
586
     
587
  /**
588
    * To create a part of query: "docid like '" +str1+ "', " +"docid like '" 
589
    * +str2+"'" ... We need to check user, group and public together for the 
590
    * permission. So we need the principal in an array and according the array
591
    * to create a part of query which will be used in other methods
592
    * @param principals, a string array storing the username, groups name and
593
    * public.
594
    */
595
   private String partQueryAboutDocId( String [] principals)
596
   {
597
     String partQuery="";
598
     int lengthOfArray=principals.length;
599
     
600
     for (int i=0;i<(lengthOfArray-1);i++)
601
     {
602
        partQuery=partQuery+"docid like '"+principals[i]+"',";
603
     }
604
     
605
     //the last one dosen't has "'"
606
     partQuery=partQuery+"docid like '"+principals[(lengthOfArray-1)]+"'";
607
     return partQuery;
608
     
609
   }
610
  
611
  /**
612
    * Check if a stirng array contains a given documents' owner
613
    * @param principals, a string array storing the username, groups name and
614
    * public.
615
    * @param docid, the id of given documents 
616
    */ 
617
  private boolean containDocumentOwner( String [] principals, String docId)
618
                    throws SQLException
619
  {
620
    int lengthOfArray=principals.length;
621
    boolean hasRow; 
622
    PreparedStatement pStmt=null;
623
    try
624
    {
625
      pStmt = conn.prepareStatement(
626
                "SELECT 'x' FROM xml_documents " +
627
                "WHERE docid = ? AND user_owner = ?"); 
628
      //check every element in the string array too see if it conatains
629
      //the owner of document
630
      for (int i=0; i<lengthOfArray; i++)
631
      {
632
             
633
        // Bind the values to the query
634
        pStmt.setString(1, docId);
635
        pStmt.setString(2, principals[i]);
636

  
637
        pStmt.execute();
638
        ResultSet rs = pStmt.getResultSet();
639
        hasRow = rs.next();
640
        if (hasRow) 
641
        {
642
          pStmt.close();
643
          return true;
644
        }//if    
645
     
646
      }//for
647
    }//try
648
    catch (SQLException e) 
649
    {
650
        pStmt.close();
651
       
652
        throw new 
653
        SQLException("AccessControlList.hasPermission(). " +
654
                     "Error checking ownership for " + principals[0] +
655
                     " on document #" + docId + ". " + e.getMessage());
656
    }//catch
657
     
658
    
659
    pStmt.close();
660
   
661
    return false; 
662
  }//containDocumentOwner
663
  
664
  /**
665
    * Check if the permission order for user at that documents is allowFirst
666
    * @param principals, list of names of principals to check for 
667
    * @param docid, document identifier to check for
668
    */
669
  private boolean isAllowFirst(String [] principals, String docId)
670
                  throws SQLException, Exception
671
  {
672
    int lengthOfArray=principals.length;
673
    boolean hasRow;
674
    
675
    //select permission order from database
676
    PreparedStatement pStmt = conn.prepareStatement(
677
                "SELECT perm_order FROM xml_access " +
678
                "WHERE principal_name= ? AND docid = ?");
679
   
680
   //check every name in the array
681
    for (int i=0; i<lengthOfArray;i++)
682
    {
683
      //bind value
684
      pStmt.setString(1, principals[i]);//user name
685
      pStmt.setString(2, docId);//docid
686
    
687
      pStmt.execute();
688
      ResultSet rs = pStmt.getResultSet();
689
      hasRow=rs.next();
690
      if (hasRow)
691
      {
692
        //get the permission order from data base
693
        String permissionOrder=rs.getString(1);
694
        //if the permission order is "allowFirst
695
        if (permissionOrder.compareTo(ALLOWFIRST)==0)
696
        {
697
          pStmt.close();
698
          return true;
699
        }
700
        else
701
        {
702
          pStmt.close();
703
          return false;
704
        }
705
      }//if
706
    }//for
707
    
708
    //if reach here, means there is no permssion record for given names and 
709
    //docid. So throw a exception.
710
    pStmt.close();
711
    throw new Exception("There is no permission record for user"+principals[0]+
712
                        "at document "+docId);
713
        
714
  }//isAllowFirst
715
  
716
  /**
717
    * Check if the users array has allow rules for given users, docid and 
718
    * permission.
719
    * If it has permission rule and ticket count is greater than 0, the ticket
720
    * number will decrease one
721
    * @param principals, list of names of principals to check for 
722
    * @param docid, document identifier to check for
723
    * @param permission, the permssion need to check
724
    */
725
  private boolean hasAllowRule(String [] principals, String docId, 
726
                                  String permission)
727
                  throws SQLException, Exception
728
 {
729
   int lengthOfArray=principals.length;
730
   ResultSet rs;
731
   PreparedStatement pStmt;
732
   int permissionValue=intValue(permission);
733
   int permissionValueInTable;
734
   int ticketCount;
735
   
736
   //This sql statement will select entry with 
737
   //begin_time<=currentTime<=end_time in xml_access table
738
   //If begin_time or end_time is null in table, isnull(begin_time, sysdate)
739
   //function will assign begin_time=sysdate
740
   pStmt = conn.prepareStatement(
741
                "SELECT permission, ticket_count " +
742
                "FROM xml_access " +
743
                "WHERE docid = ? " + 
744
                "AND principal_name = ? " +
745
                "AND perm_type = ? " +
746
                "AND " + sysdate + 
747
                " BETWEEN " + isnull + "(begin_time," + sysdate + ") " +
748
                     "AND " + isnull + "(end_time," + sysdate + ")");
749
   //bind docid, perm_type
750
   pStmt.setString(1, docId);
751
   pStmt.setString(3, ALLOW);
752
   
753
   //bind every elenment in user name array
754
    for (int i=0;i<lengthOfArray; i++)
755
    {
756
      pStmt.setString(2, principals[i]);
757
      pStmt.execute();
758
      rs=pStmt.getResultSet();
759
      while (rs.next())//check every entry for one user
760
      {
761
        permissionValueInTable=rs.getInt(1);
762
        ticketCount=rs.getInt(2);
763
       
764
        //permission is ok and ticketcount geat than 0 or ticket is null, 
765
        //the user have a permission to access the file
766
        if ((( permissionValueInTable & permissionValue )== permissionValue )
767
              && (rs.wasNull()||ticketCount > 0))
768
        {
769
           //ticket count should minus one 
770
           //ticketCount isnot null and greater than 0, order is allowfirst
771
           if (!rs.wasNull() && ticketCount>0 && isAllowFirst(principals,docId))
772
           {
773
              decreaseNumberOfAccess(permissionValueInTable, principals[i],
774
                                              docId, ALLOW, ALLOWFIRST);
775
            }
776
           //ticketCount isnot null and greater than 0, order is not allowfirst
777
           if (!rs.wasNull() &&ticketCount>0 && !isAllowFirst(principals,docId))
778
           {
779
              decreaseNumberOfAccess(permissionValueInTable, principals[i],
780
                                              docId, ALLOW, DENYFIRST);
781
           }
782
           pStmt.close();
783
           return true;
784
         }//if
785
      }//while
786
    }//for
787
    pStmt.close();
788
    return false;//no allow rule
789
 }//hasAllowRule
790
   
791
   /**
792
    * Check if the users array has explicit deny rules for given users, docid 
793
    * and permission. That means the perm_type is deny and current time is
794
    * less than end_time and greater than begin time, or no time limit.
795
    * @param principals, list of names of principals to check for 
796
    * @param docid, document identifier to check for
797
    * @param permission, the permssion need to check
798
    */
799
  private boolean hasExplicitDenyRule(String [] principals, String docId, 
800
                                  String permission)
801
                  throws SQLException
802
 {
803
   int lengthOfArray=principals.length;
804
   ResultSet rs;
805
   PreparedStatement pStmt;
806
   int permissionValue=intValue(permission);
807
   int permissionValueInTable;
808
 
809
   
810
   //This sql statement will select entry with 
811
   //begin_time<=currentTime<=end_time in xml_access table
812
   //If begin_time or end_time is null in table, isnull(begin_time, sysdate)
813
   //function will assign begin_time=sysdate
814
   pStmt = conn.prepareStatement(
815
                "SELECT permission " +
816
                "FROM xml_access " +
817
                "WHERE docid = ? " + 
818
                "AND principal_name = ? " +
819
                "AND perm_type = ? " +
820
                "AND " + sysdate + 
821
                " BETWEEN " + isnull + "(begin_time," + sysdate + ") " +
822
                     "AND " + isnull + "(end_time," + sysdate + ")");
823
   //bind docid, perm_type
824
   pStmt.setString(1, docId);
825
   pStmt.setString(3, DENY);
826
   
827
   //bind every elenment in user name array
828
    for (int i=0;i<lengthOfArray; i++)
829
    {
830
      pStmt.setString(2, principals[i]);
831
      pStmt.execute();
832
      rs=pStmt.getResultSet();
833
      while (rs.next())//check every entry for one user
834
      {
835
        permissionValueInTable=rs.getInt(1);
836
        
837
        //permission is ok the user doesn't have permission to access the file
838
        if (( permissionValueInTable & permissionValue )== permissionValue )
839
             
840
        {
841
           pStmt.close();
842
           return true;
843
         }//if
844
      }//while
845
    }//for
846
    pStmt.close();
847
    return false;//no deny rule
848
  }//hasExplicitDenyRule 
849
   
850
   /**
851
    * Check if the users array has implicit deny rules for given users, docid 
852
    * and permission. That means the though perm_type is "allow" but current 
853
    * time is less than begin_time or greater than end time, or ticket count
854
    * is 0.
855
    * @param principals, list of names of principals to check for 
856
    * @param docid, document identifier to check for
857
    * @param permission, the permssion need to check
858
    */
859
  private boolean hasImplicitDenyRule(String [] principals, String docId, 
860
                                  String permission)
861
                  throws SQLException
862
 {
863
   int lengthOfArray=principals.length;
864
   ResultSet rs;
865
   PreparedStatement pStmt;
866
   int permissionValue=intValue(permission);
867
   int permissionValueInTable;
868
 
869
   
870
   //This sql statement will select entry with  perm_type =allow and
871
   //currentTime is less than begin_time or greater than end time
872
   //in xml_access table. This is an implicit deny rule (allow is out of date) 
873
   pStmt = conn.prepareStatement(
874
                "SELECT permission " +
875
                "FROM xml_access " +
876
                "WHERE docid = ? " + 
877
                "AND principal_name = ? " +
878
                "AND perm_type = ? " +
879
                "AND " + sysdate + 
880
                " < " + isnull + "(begin_time," + sysdate + ") " +
881
                "OR " + sysdate + " > "+ isnull + "(end_time," + sysdate + ")");
882
   //bind docid, perm_type
883
   pStmt.setString(1, docId);
884
   pStmt.setString(3, ALLOW);//It is allow
885
   
886
   //bind every elenment in user name array
887
    for (int i=0;i<lengthOfArray; i++)
888
    {
889
      pStmt.setString(2, principals[i]);
890
      pStmt.execute();
891
      rs=pStmt.getResultSet();
892
      while (rs.next())//check every entry for one user
893
      {
894
        permissionValueInTable=rs.getInt(1);
895
        
896
        //permission is ok the user doesn't have permission to access the file
897
        if (( permissionValueInTable & permissionValue )== permissionValue )
898
             
899
        {
900
           pStmt.close();
901
           //has a implicit deny rule: allow is out of date
902
           return true;
903
         }//if
904
      }//while
905
    }//for
906
    pStmt.close();
907
    
908
    //Now, there is no implicit deny rule which is allow is out of date
909
    //another implicit deny rule need to be check: allow is out of ticketCount
910
    //ticketCount=0
911
    pStmt = conn.prepareStatement(
912
                "SELECT permission " +
913
                "FROM xml_access " +
914
                "WHERE docid = ? " + 
915
                "AND principal_name = ? " +
916
                "AND perm_type = ? " +
917
                "AND ticket_count = ?");
918
   //bind docid, perm_type, ticket_count
919
   pStmt.setString(1, docId);
920
   pStmt.setString(3, ALLOW);//It is allow!
921
   pStmt.setInt(4,0);
922
   
923
   //bind every elenment in user name array
924
    for (int i=0;i<lengthOfArray; i++)
925
    {
926
      pStmt.setString(2, principals[i]);
927
      pStmt.execute();
928
      rs=pStmt.getResultSet();
929
      while (rs.next())//check every entry for one user
930
      {
931
        permissionValueInTable=rs.getInt(1);
932
        
933
        //permission is ok the user doesn't have permission to access the file
934
        if (( permissionValueInTable & permissionValue )== permissionValue )
935
             
936
        {
937
           
938
           pStmt.close();
939
           //has a implicit deny rule: allow is out of ticketCount
940
           return true;
941
         }//if
942
      }//while
943
    }//for
944
    
945
    pStmt.close();
946
    return false;//no implicit deny rule
947
  }//hasImplicitDenyRule
948
  
949
  /**
950
    * Creat a users pakages to check permssion rule, user itself, public and
951
    * the gourps the user belong will be include in this package
952
    * @param user, the name of user
953
    * @param groups, the string array of the groups that user belong to
954
    */
955
  private String [] createUsersPackage(String user, String [] groups)
956
  {
957
    String [] usersPackage=null;
958
    int lengthOfPackage;
959
    
960
    if (groups!=null)
961
    {
962
      //if gouprs is not null and user is not public, we should create a array 
963
      //to store the groups and user and public. 
964
      //So the length of userPackage is the length of group plus two
965
      if (user.compareTo(PUBLIC)!=0)
966
      {
967
        lengthOfPackage=(groups.length)+2;
968
        usersPackage=new String [lengthOfPackage];
969
        //the first two elements is user self and public
970
        usersPackage[0]=user;
971
        usersPackage[1]=PUBLIC;
972
        //put groups element from index 0 to lengthOfPackage-3 into userPackage
973
        //from index 2 to lengthOfPackage-1
974
        for (int i=2; i<lengthOfPackage; i++)
975
        {
976
          usersPackage[i]=groups[i-2];
977
        } //for
978
      }//if user!=public
979
      else//use=public
980
      {
981
        lengthOfPackage=(groups.length)+1;
982
        usersPackage=new String [lengthOfPackage];
983
        //the first lements is public
984
        usersPackage[0]=PUBLIC;
985
        //put groups element from index 0 to lengthOfPackage-2 into userPackage
986
        //from index 1 to lengthOfPackage-1
987
        for (int i=1; i<lengthOfPackage; i++)
988
        {
989
          usersPackage[i]=groups[i-1];
990
        } //for
991
      }//else user=public
992
       
993
    }//if groups!=null
994
    else
995
    {
996
      //because no groups, the userPackage only need two elements
997
      //one is for user, the other is for public
998
      if (user.compareTo(PUBLIC)!=0)
999
      {
1000
        lengthOfPackage=2;
1001
        usersPackage=new String [lengthOfPackage];
1002
        usersPackage[0]=user;
1003
        usersPackage[1]=PUBLIC;
1004
      }//if user!=public
1005
      else //user==public
1006
      {
1007
        //only put public into array
1008
        lengthOfPackage=1;
1009
        usersPackage=new String [lengthOfPackage];
1010
        usersPackage[0]=PUBLIC;
1011
      }
1012
    }//else groups==null
1013
    return usersPackage;
1014
  }//createUsersPackage
1015
   
1016
  /**
549 1017
    * Check from db connection if at least one of the list of @principals
550 1018
    * has @permission on @docid.
551 1019
    * @param permission permission type to check for
......
553 1021
    * @param docid document identifier to check on
554 1022
    */
555 1023
  public boolean hasPermission(String permission, String user,
556
                               String[] groups, String docid )
1024
                               String[] groups, String docId )
557 1025
                 throws SQLException
558 1026
  {
1027
    //detele the rev number if docid contains it
1028
    docId=MetaCatUtil.getDocIdFromString(docId);
1029
    boolean hasPermission=false;
1030
    String [] userPackage=null;
1031
    
559 1032
    // b' of the command line invocation
560 1033
    if ( (user == null) && (groups == null || groups.length == 0) ) {
561 1034
      return true;
562 1035
    }
563 1036
    
564
    // Check for @permission on @docid for @user and/or @groups
565
    boolean hasPermission = hasPermission(permission,user,docid);
566
    int i = 0;
567
    if ( groups != null ) {
568
      while ( !hasPermission && i<groups.length ) {
569
        hasPermission = hasPermission(permission,groups[i++],docid);
570
      }
571
    }
572
    // Check for @permission for "public" user
573
    if ( !hasPermission ) {
574
      hasPermission = hasPermission(permission,"public",docid);
575
    }
576 1037
    
1038
    //create a userpackage including user, public and group member
1039
    userPackage=createUsersPackage(user, groups);
1040
    
1041
    //if the requested document is access documents the user should 
1042
    //have "all" permission not matter the requested permission
1043
    if (isAccessDocument(docId))
1044
    {
1045
      
1046
      // check for all permission on @docid for @userPackage
1047
      hasPermission = hasPermission(userPackage,docId,"all");
1048
      
1049
    }//if
1050
    else //if it is not access documents, just check the request permission
1051
    {
1052
    
1053
      // Check for @permission on @docid for @user and/or @groups
1054
      hasPermission = hasPermission(userPackage,docId, permission);
1055
     
1056
    }//else
1057
    
577 1058
    return hasPermission;
578 1059
  }
579

  
1060
 
580 1061
  /**
581
    * Check from db connection if @principal has @permission on @docid.
582
    * @param permission permission type to check for
583
    * @param principal name of principal to check for @permission
584
    * @param docid document identifier to check on
1062
    * Check from db connection if the users in String array @principals has
1063
    * @permission on @docid* 
1064
    * @param principals, names in userPakcage need to check for @permission
1065
    * @param docid, document identifier to check on
1066
    * @param permission, permission (write or all...) to check for 
585 1067
    */
586
  private boolean hasPermission(String permission,
587
                                String principal, String docid)
588
                 throws SQLException
1068
  private boolean hasPermission(String [] principals, String docId,
1069
                                            String permission)
1070
                         throws SQLException
589 1071
  {
590
    //detele the rev number if docid contains it
591
    docid=MetaCatUtil.getDocIdFromString(docid);
592
    PreparedStatement pstmt;
593
    
594
   
595
    // since owner of resource has all permission on it,
596
    // check if @principal is owner of @docid in xml_documents table
597
    if ( principal != null ) {
598
      try {
599
        pstmt = conn.prepareStatement(
600
                "SELECT 'x' FROM xml_documents " +
601
                "WHERE docid = ? AND user_owner = ?");
602
        // Bind the values to the query
603
        pstmt.setString(1, docid);
604
        pstmt.setString(2, principal);
605

  
606
        pstmt.execute();
607
        ResultSet rs = pstmt.getResultSet();
608
        boolean hasRow = rs.next();
609
        pstmt.close();
610
        if (hasRow) {
1072
    try 
1073
    {
1074
      //first, if there is a docid owner in user package, return true
1075
      //because doc owner has all permssion 
1076
      if (containDocumentOwner(principals, docId))
1077
      {
1078
          
611 1079
          return true;
612
        }    
613
     
614
      } catch (SQLException e) {
615
        throw new 
616
        SQLException("AccessControlList.hasPermission(). " +
617
                     "Error checking ownership for " + principal +
618
                     " on document #" + docid + ". " + e.getMessage());
619 1080
      }
620 1081
      
621
      //check to see if the file we are checking is an access file and if the
622
      //user that is trying to update it has ALL permissions
1082
      //If there is no owner in user package, checking the table
1083
      //check perm_order
1084
      if (isAllowFirst(principals, docId))
1085
      {
1086
        
1087
        if (hasExplicitDenyRule(principals, docId, permission)||
1088
                            hasImplicitDenyRule(principals, docId, permission))
1089
        {
1090
          //if it is allowfirst and has deny rule(either explicit or implicit)
1091
          //deny access
1092
          return false;
1093
        }//if
1094
        else if ( hasAllowRule(principals, docId, permission))
1095
        {
1096
          //if it is allowfirst and hasn't deny rule and has allow rule
1097
          //allow access
1098
          return true;
1099
        }//else if
1100
        else
1101
        {
1102
          //other situation deny access
1103
          return false;
1104
        }//else
1105
     }//if isAllowFirst
1106
     else //denyFirst
1107
     {
1108
       if (hasAllowRule(principals, docId, permission))
1109
       {
1110
         //if it is denyFirst and has allow rule, allow access
1111
         return true;
1112
       }
1113
       else
1114
       {
1115
         //if it is denyfirst but no allow rule, deny access
1116
         return false;
1117
       }
1118
     }//else denyfirst
1119
    }//try
1120
    catch (Exception e)
1121
    {
1122
      MetaCatUtil.debugMessage("There is a exception in hasPermission method: "
1123
                         +e.getMessage());
1124
    }
1125
    return false;
1126
  }//hasPermission
1127
 
1128
  private boolean hasValidDenyEntry(String persmission, String principal, 
1129
                                      String docId)
1130
                  throws SQLException
1131
  {
1132
  //detele the rev number if docid contains it
1133
      docId=MetaCatUtil.getDocIdFromString(docId);
1134
      PreparedStatement pStmt;
1135
      String permissionType;
1136
      int accessValue;
1137
      
1138
      
623 1139
      try
624 1140
      {
625
        pstmt = conn.prepareStatement("select 'x' from xml_access where " +
626
                                      "accessfileid like '" + docid + 
627
                                      "' and principal_name like '" + principal+
628
                                      "' and perm_type like 'allow' and " +
629
                                      "permission = 7");
630
        pstmt.execute();
631
        ResultSet rs = pstmt.getResultSet();
1141
        pStmt = conn.prepareStatement("select perm_type, permission, begin_time"
1142
                                    + ", end_time from xml_access where " +
1143
                                      "docid like '" + docId +  "' and "
1144
                                    + "principal_name like '"+principal+"'");
1145
        pStmt.execute();
1146
        ResultSet rs = pStmt.getResultSet();
632 1147
        boolean hasRow = rs.next();
633
        pstmt.close();
1148
        pStmt.close();
634 1149
        if(hasRow)
635 1150
        {
636 1151
          return true;
......
640 1155
      {
641 1156
        throw new SQLException("AccessControlList.hasPermission():2 " +
642 1157
                     "Error checking ownership for " + principal +
643
                     " on document #" + docid + ". " + e.getMessage());
1158
                     " on document #" + docId + ". " + e.getMessage());
644 1159
      }
645

  
646
      // check @principal's @permission on @docid from xml_access table
647
      int accessValue = 0;
648
      int ticketCount = 0;
649
      String permOrder = "";
650
      try {
651
        pstmt = conn.prepareStatement(
652
                "SELECT permission, perm_order, ticket_count " +
653
                "FROM xml_access " +
654
                "WHERE docid = ? " + 
655
                "AND principal_name = ? " +
656
                "AND perm_type = ? " +
657
                "AND " + sysdate + 
658
                " BETWEEN " + isnull + "(begin_time," + sysdate + ") " +
659
                     "AND " + isnull + "(end_time," + sysdate + ")");
660
        // check if it is "deny" with "allowFirst" first
661
        // Bind the values to the query
662
        pstmt.setString(1, docid);
663
        pstmt.setString(2, principal);
664
        pstmt.setString(3, "deny");
665

  
666
        pstmt.execute();
667
        ResultSet rs = pstmt.getResultSet();
668
        boolean hasRows = rs.next();
669
        while ( hasRows ) {
670
          accessValue = rs.getInt(1);
671
          permOrder = rs.getString(2);
672
          ticketCount = rs.getInt(3);
673
          if ( ( accessValue & intValue(permission) ) == intValue(permission) &&
674
               ( permOrder.equals("allowFirst") ) &&
675
               ( rs.wasNull() || ticketCount > 0 ) ) {
676
            if ( !rs.wasNull() && ticketCount > 0 ) {
677
              decreaseNumberOfAccess(accessValue,principal,docid,
678
                                                          "deny","allowFirst");
679
            }
680
            pstmt.close();
681
            return false;
682
          }
683
          hasRows = rs.next();
684
        }
685
     
686

  
687
        // it is not denied then check if it is "allow"
688
        // Bind the values to the query
689
        pstmt.setString(1, docid);
690
        pstmt.setString(2, principal);
691
        pstmt.setString(3, "allow");
692

  
693
        pstmt.execute();
694
        rs = pstmt.getResultSet();
695
        hasRows = rs.next();
696
        while ( hasRows ) {
697
          accessValue = rs.getInt(1);
698
          permOrder = rs.getString(2);
699
          ticketCount = rs.getInt(3);
700
          if ( ( accessValue & intValue(permission) )==intValue(permission) &&
701
               ( rs.wasNull() || ticketCount > 0 ) ) {
702
            if ( !rs.wasNull() && ticketCount > 0 ) {
703
              decreaseNumberOfAccess(accessValue,principal,
704
                                                      docid,"allow",permOrder);
705
            }
706
            pstmt.close();
707
            return true;
708
          }
709
          hasRows = rs.next();
710
        }
711
   
712

  
713
        // it is not allowed then check if it is "deny" with "denyFirst"
714
        // Bind the values to the query
715
        pstmt.setString(1, docid);
716
        pstmt.setString(2, principal);
717
        pstmt.setString(3, "deny");
718

  
719
        pstmt.execute();
720
        rs = pstmt.getResultSet();
721
        hasRows = rs.next();
722
        while ( hasRows ) {
723
          accessValue = rs.getInt(1);
724
          permOrder = rs.getString(2);
725
          ticketCount = rs.getInt(3);
726
          if ( ( accessValue & intValue(permission) ) == intValue(permission) &&
727
               ( permOrder.equals("denyFirst") ) &&
728
               ( rs.wasNull() || ticketCount > 0 ) ) {
729
            if ( !rs.wasNull() && ticketCount > 0 ) {
730
                decreaseNumberOfAccess(accessValue,principal,docid,
731
                                                "deny","denyFirst");
732
            }
733
            pstmt.close();
734
            return false;
735
          }
736
          hasRows = rs.next();
737
        }
738
      
739
      
740
        pstmt.close();
741
        return false;
742
  
743
      } catch (SQLException e) {
744
        throw new 
745
        SQLException("AccessControlList.hasPermission(). " +
746
                     "Error checking " + permission + " permission for " +
747
                     principal + " on document #" + docid + ". " +
748
                     e.getMessage());
749
      }
750
    }
751
    
752
    return false;
1160
      return false;
753 1161
  }
754

  
755 1162
  /* Decrease the number of access to @docid for @principal in db. */
756 1163
  private void decreaseNumberOfAccess(int permission, String principal,
757 1164
                                      String docid, String permType, 
......
790 1197
    * @param groups names of user's groups to which user belongs
791 1198
    */
792 1199
  public String getACL(String docid, String user, String[] groups) 
793
          throws SQLException 
1200
          throws SQLException
794 1201
  {
795 1202
    StringBuffer output = new StringBuffer();
796 1203
    StringBuffer outTemp = new StringBuffer();

Also available in: Unified diff