Project

General

Profile

« Previous | Next » 

Revision 6744

refactor Metacat access handling to be on a per-revision basis so that it more closely aligns with the DataONE approach
http://bugzilla.ecoinformatics.org/show_bug.cgi?id=5560

View differences:

PermissionController.java
53 53

  
54 54
public class PermissionController
55 55
{
56
   private String docId = null;
56
//   private String docId = null;
57
//   private int rev = -1;
58
   
59
   private String guid = null;
60
   
57 61
   private boolean hasSubTreeAccessControl = false; // flag if has a subtree
58 62
                                                    // access for this docid
59 63
   private Vector subTreeList = new Vector();
......
64 68
   private static Logger logMetacat = Logger.getLogger(PermissionController.class);
65 69

  
66 70
   /**
67
    * Constructor for PermissionController
68
    * @param myDocid      the docid need to access
69
    */
70
   public PermissionController(String myDocid) throws McdbException
71
   {
72
     // Get rid of rev number
73
     docId = DocumentUtil.getSmartDocId(myDocid);
74
     //hasSubTreeAccessControl = checkSubTreeAccessControl();
75
   }
71
	 * Constructor for PermissionController
72
	 * 
73
	 * @param myDocid the docid need to access
74
	 */
75
	public PermissionController(String myDocid) throws McdbException {
76 76

  
77
   /**
78
    * Constructor for PermssionController
79
    * @param myDocid String
80
    * @param needDeleteRev boolean
81
    */
82
   public PermissionController(String myDocid, boolean needDeleteRevFromDocid)
83
   {
84
     if (!needDeleteRevFromDocid)
85
     {
86
       docId = myDocid;
87
     }
88
     else
89
     {
90
         docId = DocumentUtil.getDocIdFromAccessionNumber(myDocid);
91
     }
92
   }
77
		// find the guid if we can
78
		String docId = null;
79
		int rev = -1;
93 80

  
81
		// get the parts
82
		docId = DocumentUtil.getSmartDocId(myDocid);
83
		rev = DocumentUtil.getRevisionFromAccessionNumber(myDocid);
84

  
85
		// this is what we really want
86
		guid = IdentifierManager.getInstance().getGUID(docId, rev);
87

  
88
	}
89

  
94 90
   /**
95 91
    * Return if a document has subtree access control
96 92
    */
......
147 143
    //if the requested document is access documents and requested permission
148 144
    //is "write", the user should have "all" right
149 145

  
150
    if (isAccessDocument(docId) && (permission == AccessControlInterface.WRITE))
146
    if (isAccessDocument() && (permission == AccessControlInterface.WRITE))
151 147
    {
152 148

  
153
      hasPermission = hasPermission(userPackage,docId, 7);// 7 is all permission
149
      hasPermission = hasPermission(userPackage, 7);// 7 is all permission
154 150
    }//if
155 151
    else //in other situation, just check the request permission
156 152
    {
157 153
      // Check for @permission on @docid for @user and/or @groups
158
      hasPermission = hasPermission(userPackage,docId, permission);
154
      hasPermission = hasPermission(userPackage, permission);
159 155
    }//else
160 156

  
161 157
    return hasPermission;
......
169 165
    * @param docid, document identifier to check on
170 166
    * @param permission, permission (write or all...) to check for
171 167
    */
172
  private boolean hasPermission(String [] principals, String docId,
173
                                           int permission)
168
  private boolean hasPermission(String [] principals, int permission)
174 169
                         throws SQLException
175 170
  {
176 171
    long startId = TOPLEVELSTARTNODEID;// this is for top level, so startid is 0
......
178 173
    {
179 174
      //first, if there is a docid owner in user package, return true
180 175
      //because doc owner has all permssion
181
      if (containDocumentOwner(principals, docId))
176
      if (containDocumentOwner(principals))
182 177
      {
183 178

  
184 179
          return true;
......
186 181

  
187 182
      //If there is no owner in user package, checking the table
188 183
      //check perm_order
189
      if (isAllowFirst(principals, docId, startId))
184
      if (isAllowFirst(principals, startId))
190 185
      {
191 186

  
192
        if (hasExplicitDenyRule(principals, docId, permission, startId))
187
        if (hasExplicitDenyRule(principals, permission, startId))
193 188
        {
194 189
          //if it is allowfirst and has deny rule(either explicit )
195 190
          //deny access
196 191

  
197 192
          return false;
198 193
        }//if
199
        else if ( hasAllowRule(principals, docId, permission, startId))
194
        else if ( hasAllowRule(principals, permission, startId))
200 195
        {
201 196
          //if it is allowfirst and hasn't deny rule and has allow rule
202 197
          //allow access
......
212 207
     }//if isAllowFirst
213 208
     else //denyFirst
214 209
     {
215
       if (hasAllowRule(principals, docId, permission, startId))
210
       if (hasAllowRule(principals, permission, startId))
216 211
       {
217 212
         //if it is denyFirst and has allow rule, allow access
218 213
         return true;
......
251 246
     // from inlinedataId directly. You should get it from eml document itself
252 247
     String []userPackage = createUsersPackage(user, groups);
253 248
     try {
254
        if (containDocumentOwner(userPackage, docId))
249
        if (containDocumentOwner(userPackage))
255 250
         {
256 251
           return true;
257 252
         }
258 253
         else
259 254
         {
260
             PermissionController controller =
261
                                   new PermissionController(inlineDataId, false);
255
        	 // is a funky inline data id with the extra part, so we set it manually
256
             PermissionController controller = new PermissionController(guid);
257
             controller.guid = inlineDataId;
262 258
             return controller.hasPermission(user, groups, myPermission);
263 259
         }
264 260
    } catch (SQLException e) {
......
318 314
    //for the document owner return null(no unaccessable subtree)
319 315
    try
320 316
    {
321
      if (containDocumentOwner(principals, docId))
317
      if (containDocumentOwner(principals))
322 318
      {
323 319
       return resultUnaccessableSubTree;
324 320
      }
......
337 333

  
338 334
        try
339 335
        {
340
          if (isAllowFirst(principals, docId, startId))
336
          if (isAllowFirst(principals, startId))
341 337
          {
342 338

  
343
            if (hasExplicitDenyRule(principals, docId, permission, startId ))
339
            if (hasExplicitDenyRule(principals, permission, startId ))
344 340
            {
345 341

  
346 342
             //if it is allowfirst and has deny rule
......
350 346
                resultUnaccessableSubTree.put(new Long(startId), tree);
351 347
              }
352 348
            }//if
353
            else if ( hasAllowRule(principals, docId, permission, startId))
349
            else if ( hasAllowRule(principals, permission, startId))
354 350
            {
355 351
              //if it is allowfirst and hasn't deny rule and has allow rule
356 352
              //allow access do nothing
......
368 364
          }//if isAllowFirst
369 365
          else //denyFirst
370 366
          {
371
            if (hasAllowRule(principals, docId, permission,startId))
367
            if (hasAllowRule(principals, permission,startId))
372 368
            {
373 369
              //if it is denyFirst and has allow rule, allow access, do nothing
374 370

  
......
463 459
	 * @param docId,
464 460
	 *            the document id need to be checked
465 461
	 */
466
	private boolean isAccessDocument(String docId) throws SQLException {
467
		// detele the rev number if docid contains it
462
	private boolean isAccessDocument() throws SQLException {
463
		// get the docid from the guid
464
		String docId = null;
465
		try {
466
			docId = IdentifierManager.getInstance().getLocalId(guid);
467
		} catch (McdbDocNotFoundException e) {
468
			return false;
469
			//throw new SQLException(e);
470
		}
471

  
468 472
		docId = DocumentUtil.getDocIdFromString(docId);
469 473
		PreparedStatement pStmt = null;
470 474
		DBConnection conn = null;
......
520 524
	 * @param docid,
521 525
	 *            the id of given documents
522 526
	 */
523
  private boolean containDocumentOwner( String[] principals, String docId)
527
  private boolean containDocumentOwner(String[] principals)
524 528
                    throws SQLException
525 529
  {
530
	 
531
	// get the docid  
532
	String docId = null;
533
	try {
534
		docId = IdentifierManager.getInstance().getLocalId(guid);
535
		docId = DocumentUtil.getDocIdFromString(docId);
536
	} catch (McdbDocNotFoundException e) {
537
		// should be true if we own the parent doc, but likely won't be checked in that case
538
		return false;
539
	}
540
	
526 541
    int lengthOfArray=principals.length;
527 542
    boolean hasRow;
528 543
    PreparedStatement pStmt=null;
......
593 608
    * @param principals, list of names of principals to check for
594 609
    * @param docid, document identifier to check for
595 610
    */
596
  private boolean isAllowFirst(String [] principals, String docId,
597
                               long startId)
611
  private boolean isAllowFirst(String [] principals, long startId)
598 612
                  throws SQLException, Exception
599 613
  {
600 614
    int lengthOfArray=principals.length;
......
608 622
    {
609 623
      //top level
610 624
      topLever = true;
611
      sql = "SELECT perm_order FROM xml_access " +
612
    "WHERE lower(principal_name) = ? AND docid = ? AND startnodeid is NULL";
625
      sql = 
626
    	  "SELECT perm_order FROM xml_access " +
627
		    "WHERE lower(principal_name) = ? " +
628
		    "AND guid = ? " +
629
		    "AND startnodeid is NULL";
613 630
    }
614 631
    else
615 632
    {
616 633
      //sub tree level
617 634
      sql = "SELECT perm_order FROM xml_access " +
618
        "WHERE lower(principal_name)= ? AND docid = ? AND startnodeid = ?";
635
        "WHERE lower(principal_name) = ? " +
636
        "AND guid = ? " +
637
        "AND startnodeid = ?";
619 638
    }
620 639

  
621 640
    try
......
632 651
      {
633 652
        //bind value
634 653
        pStmt.setString(1, principals[i]);//user name
635
        pStmt.setString(2, docId);//docid
636

  
654
        pStmt.setString(2, guid);//guid
655
        
637 656
        // if subtree, we need set subtree id
638 657
        if (!topLever)
639 658
        {
......
681 700
    //docid. So throw a exception.
682 701

  
683 702
    throw new Exception("PermissionController.isAllowFirst - There is no permission record for user "+ principals[0] + 
684
                        " at document " + docId);
703
                        " at document " + guid);
685 704

  
686 705
  }//isAllowFirst
687 706

  
......
694 713
    * @param docid, document identifier to check for
695 714
    * @param permission, the permssion need to check
696 715
    */
697
  private boolean hasAllowRule(String [] principals, String docId,
698
                                  int permission, long startId)
716
  private boolean hasAllowRule(String [] principals, int permission, long startId)
699 717
                  throws SQLException, Exception
700 718
 {
701 719
   int lengthOfArray=principals.length;
......
704 722
   PreparedStatement pStmt = null;
705 723
   int permissionValue=permission;
706 724
   int permissionValueInTable;
707
   int ticketCount;
708 725
   DBConnection conn = null;
709 726
   int serialNumber = -1;
710 727
   boolean topLever = false;
......
713 730
   {
714 731
     // for toplevel
715 732
     topLever = true;
716
     sql = "SELECT permission FROM xml_access WHERE docid = ? " +
717
   "AND lower(principal_name) = ? AND perm_type = ? AND startnodeid is NULL";
733
     sql = "SELECT permission " +
734
		"FROM xml_access " +
735
 		"WHERE guid = ? " +
736
 		"AND lower(principal_name) = ? " +
737
 		"AND perm_type = ? " +
738
 		"AND startnodeid is NULL";
718 739
   }
719 740
   else
720 741
   {
721 742
     topLever =false;
722
     sql = "SELECT permission FROM xml_access WHERE docid = ? " +
723
      "AND lower(principal_name) = ? AND perm_type = ? AND startnodeid = ?";
743
     sql = "SELECT permission " +
744
     		"FROM xml_access " +
745
     		"WHERE guid = ? " +
746
     		"AND lower(principal_name) = ? " +
747
     		"AND perm_type = ? " +
748
     		"AND startnodeid = ?";
724 749
   }
725 750
   try
726 751
   {
......
733 758
    //function will assign begin_time=sysdate
734 759
    pStmt = conn.prepareStatement(sql);
735 760
    //bind docid, perm_type
736
    pStmt.setString(1, docId);
761
    pStmt.setString(1, guid);
737 762
    pStmt.setString(3, AccessControlInterface.ALLOW);
738 763

  
739 764
    // if subtree lever, need to set subTreeId
......
794 819
    * @param docid, document identifier to check for
795 820
    * @param permission, the permssion need to check
796 821
    */
797
  private boolean hasExplicitDenyRule(String [] principals, String docId,
822
  private boolean hasExplicitDenyRule(String [] principals,
798 823
                                      int permission, long startId)
799 824
                  throws SQLException
800 825
 {
......
812 837
   if (startId == TOPLEVELSTARTNODEID)
813 838
   {
814 839
     topLevel = true;
815
     sql = "SELECT permission FROM xml_access WHERE docid = ? " +
816
    "AND lower(principal_name) = ? AND perm_type = ? AND startnodeid is NULL";
840
     sql = "SELECT permission " +
841
     		"FROM xml_access " +
842
     		"WHERE guid = ? " +
843
	     	"AND lower(principal_name) = ? " +
844
	     	"AND perm_type = ? " +
845
	     	"AND startnodeid is NULL";
817 846
   }
818 847
   else
819 848
   {
820 849
     topLevel = false;
821
     sql = "SELECT permission FROM xml_access WHERE docid = ? " +
822
     "AND lower(principal_name) = ? AND perm_type = ? AND startnodeid = ?";
850
     sql = "SELECT permission " +
851
		"FROM xml_access " +
852
		"WHERE guid = ? " +
853
	  	"AND lower(principal_name) = ? " +
854
	  	"AND perm_type = ? " +
855
	  	"AND startnodeid = ?";
823 856
   }
824 857

  
825 858
   try
......
830 863

  
831 864
     pStmt = conn.prepareStatement(sql);
832 865
    //bind docid, perm_type
833
    pStmt.setString(1, docId);
866
    pStmt.setString(1, guid);
834 867
    pStmt.setString(3, AccessControlInterface.DENY);
835 868

  
836 869
    // subtree level need to set up subtreeid
......
978 1011
   * user can't read it. The key is subtree id of inlinedata, the data is
979 1012
   * internal file name for the inline data which is stored as docid
980 1013
   * in xml_access table or data object doc id.
981
   * @param docidWithoutRev, metadata docid which should be the accessfileid
1014
   * @param docid (With Rev), metadata docid which should be the accessfileid
982 1015
   *                         in the table
983 1016
   * @param user , the name of user
984 1017
   * @param groups, the group which the user belong to
985 1018
   */
986
   public static Hashtable<String, String> getUnReadableInlineDataIdList(String docidWithoutRev,
987
                                                   String user, String[] groups,
988
                                                   boolean withRevision)
1019
   public static Hashtable<String, String> getUnReadableInlineDataIdList(String docid,
1020
                                                   String user, String[] groups)
989 1021
                                                throws McdbException
990 1022
   {
991
     Hashtable<String, String> inlineDataList = getUnAccessableInlineDataIdList(docidWithoutRev,
992
                              user, groups, AccessControlInterface.READSTRING,
993
                              withRevision);
1023
     Hashtable<String, String> inlineDataList = getUnAccessableInlineDataIdList(docid,
1024
                              user, groups, AccessControlInterface.READSTRING);
994 1025

  
995 1026
     return inlineDataList;
996 1027
   }
......
1011 1042
                                               throws Exception
1012 1043
  {
1013 1044
    Hashtable<String, String> inlineDataList = getUnAccessableInlineDataIdList(docidWithoutRev,
1014
                            user, groups, AccessControlInterface.WRITESTRING,
1015
                            withRevision);
1045
                            user, groups, AccessControlInterface.WRITESTRING);
1016 1046

  
1017 1047
    return inlineDataList;
1018 1048
  }
1019 1049

  
1020 1050

  
1021
   /*
1051
   /**
1022 1052
    * This method will get hashtable which contains a unaccessable distribution
1023 1053
    * inlinedata object list
1024 1054
    *
1025
    * withRevision is used to get inline id list with or without revision number
1026
    * e.g. when withRevision is true, temp.1.1.1, temp.1.1.2 would be returned
1027
    * otherwise temp.1.1 and temp.1.2 would be returned.
1028 1055
    */
1029 1056
   private static Hashtable<String, String> getUnAccessableInlineDataIdList(String docid,
1030
                               String user, String[] groups, String permission,
1031
                               boolean withRevision)
1057
                               String user, String[] groups, String permission)
1032 1058
                             throws McdbException
1033 1059
   {
1034 1060
       Hashtable<String, String> unAccessibleIdList = new Hashtable();
......
1047 1073
      {
1048 1074
        String subTreeId = (String) en.nextElement();
1049 1075
        String fileId = (String) allIdList.get(subTreeId);
1050
        //Here fileid is internal file id for line data. It stored in docid
1051
        // field in xml_access table. so we don't need to delete rev
1052
        PermissionController controller = new PermissionController(docid, false);
1076
        //Here fileid is internal file id for line data. It stored in guid
1077
        // field in xml_access table. 
1078
        PermissionController controller = new PermissionController(docid);
1053 1079
        if (!controller.hasPermissionForInlineData(user, groups, permission, fileId))
1054 1080
        {
1055
            if(withRevision)
1056
            {
1057
                logMetacat.info("PermissionController.getUnAccessableInlineDataIdList - Put subtree id " + subTreeId +
1058
                                         " and " + "inline data file name " +
1059
                                         fileId + " into " + "un" + permission +
1060
                                         " hash");
1061
                unAccessibleIdList.put(subTreeId, fileId);
1081
            
1082
            logMetacat.info("PermissionController.getUnAccessableInlineDataIdList - Put subtree id " + subTreeId +
1083
                                     " and " + "inline data file name " +
1084
                                     fileId + " into " + "un" + permission +
1085
                                     " hash");
1086
            unAccessibleIdList.put(subTreeId, fileId);
1062 1087

  
1063
            }
1064
            else
1065
            {
1066
                logMetacat.info("PermissionController.getUnAccessableInlineDataIdList - Put subtree id " + subTreeId +
1067
                                         " and " + "inline data file name " +
1068
                                         DocumentUtil.getInlineDataIdWithoutRev(fileId) +
1069
                                         " into " + "un" + permission +
1070
                                         " hash");
1071
                unAccessibleIdList.put(subTreeId, 
1072
                		DocumentUtil.getInlineDataIdWithoutRev(fileId));
1073
            }
1088
                        
1074 1089
        }
1075 1090
      }
1076 1091
      return unAccessibleIdList;
......
1085 1100
   private static Hashtable getAllInlineDataIdList(String docid) throws SQLException
1086 1101
   {
1087 1102
     Hashtable inlineDataList = new Hashtable();
1088
     String sql = "SELECT subtreeid, docid FROM xml_access WHERE " +
1089
                   "accessfileid = ? AND subtreeid  IS NOT NULL";
1103
     String sql = 
1104
    	 "SELECT subtreeid, guid " +
1105
    	 "FROM xml_access " +
1106
    	 "WHERE accessfileid = ? " +
1107
    	 "AND subtreeid IS NOT NULL";
1090 1108
     PreparedStatement pStmt=null;
1091 1109
     ResultSet rs=null;
1092 1110
     DBConnection conn=null;

Also available in: Unified diff