Revision 6744
Added by ben leinfelder over 12 years ago
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
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