Revision 1434
Added by Jing Tao over 21 years ago
src/edu/ucsb/nceas/metacat/PermissionController.java | ||
---|---|---|
29 | 29 |
package edu.ucsb.nceas.metacat; |
30 | 30 |
|
31 | 31 |
import java.sql.*; |
32 |
import java.util.Hashtable; |
|
32 | 33 |
import java.util.Stack; |
33 | 34 |
import java.util.Vector; |
34 | 35 |
|
... | ... | |
44 | 45 |
* Constructor for PermissionController |
45 | 46 |
* @param myDocid the docid need to access |
46 | 47 |
*/ |
47 |
public PermissionController(String myDocid) throws SQLException
|
|
48 |
public PermissionController(String myDocid) throws McdbException
|
|
48 | 49 |
{ |
49 | 50 |
// Get rid of rev number |
50 | 51 |
docId = MetaCatUtil.getDocIdFromString(myDocid); |
... | ... | |
56 | 57 |
* if has, store the subtree into list and return true. Otherwise, |
57 | 58 |
* return false |
58 | 59 |
*/ |
59 |
private boolean checkSubTreeAccessControl() throws SQLException
|
|
60 |
private boolean checkSubTreeAccessControl() throws McdbException
|
|
60 | 61 |
{ |
61 | 62 |
boolean flag = false; |
62 | 63 |
PreparedStatement pStmt=null; |
... | ... | |
99 | 100 |
} |
100 | 101 |
} |
101 | 102 |
}//try |
103 |
catch (SQLException e) |
|
104 |
{ |
|
105 |
throw new McdbException(e); |
|
106 |
} |
|
102 | 107 |
finally |
103 | 108 |
{ |
104 | 109 |
try |
105 | 110 |
{ |
106 | 111 |
pStmt.close(); |
107 | 112 |
} |
113 |
catch(SQLException ee) |
|
114 |
{ |
|
115 |
throw new McdbException(ee); |
|
116 |
} |
|
108 | 117 |
finally |
109 | 118 |
{ |
110 | 119 |
DBConnectionPool.returnDBConnection(conn, serialNumber); |
... | ... | |
118 | 127 |
* @param user the user name |
119 | 128 |
* @param groups the groups which the use is in |
120 | 129 |
* @param myPermission permission type to check for |
121 |
* @param principals list of names of principals to check for @permission |
|
122 | 130 |
*/ |
123 | 131 |
public boolean hasPermission(String user, String[]groups, String myPermission) |
124 | 132 |
throws SQLException, Exception |
... | ... | |
126 | 134 |
boolean hasPermission=false; |
127 | 135 |
String [] userPackage=null; |
128 | 136 |
int permission =AccessControlList.intValue(myPermission); |
129 |
|
|
137 |
|
|
130 | 138 |
//for the commnad line invocation |
131 | 139 |
if ((user==null) && (groups==null || groups.length==0)) |
132 | 140 |
{ |
... | ... | |
164 | 172 |
int permission) |
165 | 173 |
throws SQLException |
166 | 174 |
{ |
175 |
String subTreeId = null;// this is for top level, so subtree id is null |
|
167 | 176 |
try |
168 | 177 |
{ |
169 | 178 |
//first, if there is a docid owner in user package, return true |
... | ... | |
176 | 185 |
|
177 | 186 |
//If there is no owner in user package, checking the table |
178 | 187 |
//check perm_order |
179 |
if (isAllowFirst(principals, docId)) |
|
188 |
if (isAllowFirst(principals, docId, subTreeId))
|
|
180 | 189 |
{ |
181 | 190 |
|
182 |
if (hasExplicitDenyRule(principals, docId, permission)) |
|
191 |
if (hasExplicitDenyRule(principals, docId, permission, subTreeId))
|
|
183 | 192 |
{ |
184 | 193 |
//if it is allowfirst and has deny rule(either explicit ) |
185 | 194 |
//deny access |
186 | 195 |
return false; |
187 | 196 |
}//if |
188 |
else if ( hasAllowRule(principals, docId, permission)) |
|
197 |
else if ( hasAllowRule(principals, docId, permission, subTreeId))
|
|
189 | 198 |
{ |
190 | 199 |
//if it is allowfirst and hasn't deny rule and has allow rule |
191 | 200 |
//allow access |
... | ... | |
199 | 208 |
}//if isAllowFirst |
200 | 209 |
else //denyFirst |
201 | 210 |
{ |
202 |
if (hasAllowRule(principals, docId, permission)) |
|
211 |
if (hasAllowRule(principals, docId, permission, subTreeId))
|
|
203 | 212 |
{ |
204 | 213 |
//if it is denyFirst and has allow rule, allow access |
205 | 214 |
return true; |
... | ... | |
221 | 230 |
}//hasPermission |
222 | 231 |
|
223 | 232 |
/** |
233 |
* This method will return a hasTable of subtree which user doesn't has the |
|
234 |
* permssion to access |
|
235 |
* @param user the user name |
|
236 |
* @param groups the groups which the use is in |
|
237 |
* @param myPermission permission type to check for |
|
238 |
*/ |
|
239 |
public Hashtable hasUnaccessableSubTree(String user, String[] groups, |
|
240 |
String myPermission) throws McdbException |
|
241 |
{ |
|
242 |
Hashtable resultUnaccessableSubTree = new Hashtable(); |
|
243 |
String [] principals=null; |
|
244 |
int permission =AccessControlList.intValue(myPermission); |
|
245 |
|
|
246 |
//for the commnad line invocation return null(no unaccessable subtree) |
|
247 |
if ((user==null) && (groups==null || groups.length==0)) |
|
248 |
{ |
|
249 |
return resultUnaccessableSubTree; |
|
250 |
} |
|
251 |
|
|
252 |
//create a userpackage including user, public and group member |
|
253 |
principals=createUsersPackage(user, groups); |
|
254 |
//for the document owner return null(no unaccessable subtree) |
|
255 |
try |
|
256 |
{ |
|
257 |
if (containDocumentOwner(principals, docId)) |
|
258 |
{ |
|
259 |
return resultUnaccessableSubTree; |
|
260 |
} |
|
261 |
} |
|
262 |
catch (SQLException ee) |
|
263 |
{ |
|
264 |
throw new McdbException(ee); |
|
265 |
} |
|
266 |
|
|
267 |
// go through every subtree which has access control |
|
268 |
for (int i = 0; i< subTreeList.size(); i++) |
|
269 |
{ |
|
270 |
SubTree tree = (SubTree)subTreeList.elementAt(i); |
|
271 |
String subTreeId = (String)(tree.getSubTreeId()); |
|
272 |
|
|
273 |
if (subTreeId != null) |
|
274 |
{ |
|
275 |
try |
|
276 |
{ |
|
277 |
if (isAllowFirst(principals, docId, subTreeId)) |
|
278 |
{ |
|
279 |
|
|
280 |
if (hasExplicitDenyRule(principals, docId, permission, subTreeId)) |
|
281 |
{ |
|
282 |
|
|
283 |
//if it is allowfirst and has deny rule |
|
284 |
// put the subtree into unaccessable vector |
|
285 |
if (!resultUnaccessableSubTree.containsKey(subTreeId)) |
|
286 |
{ |
|
287 |
resultUnaccessableSubTree.put(subTreeId, tree); |
|
288 |
} |
|
289 |
}//if |
|
290 |
else if ( hasAllowRule(principals, docId, permission, subTreeId)) |
|
291 |
{ |
|
292 |
//if it is allowfirst and hasn't deny rule and has allow rule |
|
293 |
//allow access do nothing |
|
294 |
|
|
295 |
}//else if |
|
296 |
else |
|
297 |
{ |
|
298 |
//other situation deny access |
|
299 |
if (!resultUnaccessableSubTree.containsKey(subTreeId)) |
|
300 |
{ |
|
301 |
resultUnaccessableSubTree.put(subTreeId, tree); |
|
302 |
} |
|
303 |
|
|
304 |
}//else |
|
305 |
}//if isAllowFirst |
|
306 |
else //denyFirst |
|
307 |
{ |
|
308 |
if (hasAllowRule(principals, docId, permission,subTreeId)) |
|
309 |
{ |
|
310 |
//if it is denyFirst and has allow rule, allow access, do nothing |
|
311 |
|
|
312 |
} |
|
313 |
else |
|
314 |
{ |
|
315 |
//if it is denyfirst but no allow rule, deny access |
|
316 |
// add into vector |
|
317 |
if (!resultUnaccessableSubTree.containsKey(subTreeId)) |
|
318 |
{ |
|
319 |
resultUnaccessableSubTree.put(subTreeId, tree); |
|
320 |
} |
|
321 |
} |
|
322 |
}//else denyfirst |
|
323 |
}//try |
|
324 |
catch( Exception e) |
|
325 |
{ |
|
326 |
MetaCatUtil.debugMessage("error in PermissionControl.has" + |
|
327 |
"UnaccessableSubTree "+e.getMessage(), 30); |
|
328 |
throw new McdbException(e); |
|
329 |
} |
|
330 |
}//if |
|
331 |
}//for |
|
332 |
return resultUnaccessableSubTree; |
|
333 |
}//hasUnaccessableSubtree |
|
334 |
|
|
335 |
/** |
|
224 | 336 |
* Check if a document id is a access document. Access document need user |
225 | 337 |
* has "all" permission to access it. |
226 | 338 |
* @param docId, the document id need to be checked |
... | ... | |
235 | 347 |
try |
236 | 348 |
{ |
237 | 349 |
//check out DBConnection |
238 |
conn=DBConnectionPool.getDBConnection("AccessControlList.isAccessDoc");
|
|
350 |
conn=DBConnectionPool.getDBConnection("PermissionControl.isAccessDoc");
|
|
239 | 351 |
serialNumber=conn.getCheckOutSerialNumber(); |
240 | 352 |
pStmt = conn.prepareStatement("select 'x' from xml_access where " + |
241 | 353 |
"accessfileid like '" + docId + "'"); |
... | ... | |
251 | 363 |
catch(SQLException e) |
252 | 364 |
{ |
253 | 365 |
|
254 |
throw new SQLException("AccessControlList.isAccessDocument " +
|
|
366 |
throw new SQLException("PermissionControl.isAccessDocument " +
|
|
255 | 367 |
"Error checking" + |
256 | 368 |
" on document " + docId + ". " + e.getMessage()); |
257 | 369 |
} |
... | ... | |
277 | 389 |
* public. |
278 | 390 |
* @param docid, the id of given documents |
279 | 391 |
*/ |
280 |
private boolean containDocumentOwner( String [] principals, |
|
281 |
String docId) |
|
392 |
private boolean containDocumentOwner( String[] principals, String docId) |
|
282 | 393 |
throws SQLException |
283 | 394 |
{ |
284 | 395 |
int lengthOfArray=principals.length; |
... | ... | |
290 | 401 |
try |
291 | 402 |
{ |
292 | 403 |
//check out DBConnection |
293 |
conn=DBConnectionPool.getDBConnection("AccessControlList.containDocOnwer");
|
|
404 |
conn=DBConnectionPool.getDBConnection("PermissionControl.containDocOnwer");
|
|
294 | 405 |
serialNumber=conn.getCheckOutSerialNumber(); |
295 | 406 |
pStmt = conn.prepareStatement( |
296 | 407 |
"SELECT 'x' FROM xml_documents " + |
... | ... | |
320 | 431 |
pStmt.close(); |
321 | 432 |
|
322 | 433 |
throw new |
323 |
SQLException("AccessControlList.hasPermission(). " +
|
|
434 |
SQLException("PermissionControl.hasPermission(). " +
|
|
324 | 435 |
"Error checking ownership for " + principals[0] + |
325 | 436 |
" on document #" + docId + ". " + e.getMessage()); |
326 | 437 |
}//catch |
... | ... | |
343 | 454 |
* @param principals, list of names of principals to check for |
344 | 455 |
* @param docid, document identifier to check for |
345 | 456 |
*/ |
346 |
private boolean isAllowFirst(String [] principals, String docId) |
|
457 |
private boolean isAllowFirst(String [] principals, String docId, |
|
458 |
String subTreeId) |
|
347 | 459 |
throws SQLException, Exception |
348 | 460 |
{ |
349 | 461 |
int lengthOfArray=principals.length; |
... | ... | |
351 | 463 |
PreparedStatement pStmt = null; |
352 | 464 |
DBConnection conn = null; |
353 | 465 |
int serialNumber = -1; |
466 |
String sql = null; |
|
467 |
boolean topLever =false; |
|
468 |
if (subTreeId == null) |
|
469 |
{ |
|
470 |
//top level |
|
471 |
topLever = true; |
|
472 |
sql = "SELECT perm_order FROM xml_access " + |
|
473 |
"WHERE principal_name= ? AND docid = ? AND subtreeid is NULL"; |
|
474 |
} |
|
475 |
else |
|
476 |
{ |
|
477 |
//sub tree level |
|
478 |
sql = "SELECT perm_order FROM xml_access " + |
|
479 |
"WHERE principal_name= ? AND docid = ? AND subtreeid = ?"; |
|
480 |
} |
|
481 |
|
|
354 | 482 |
try |
355 | 483 |
{ |
356 | 484 |
//check out DBConnection |
... | ... | |
358 | 486 |
serialNumber=conn.getCheckOutSerialNumber(); |
359 | 487 |
|
360 | 488 |
//select permission order from database |
361 |
pStmt = conn.prepareStatement( |
|
362 |
"SELECT perm_order FROM xml_access " + |
|
363 |
"WHERE principal_name= ? AND docid = ?"); |
|
489 |
pStmt = conn.prepareStatement(sql); |
|
364 | 490 |
|
365 | 491 |
//check every name in the array |
366 | 492 |
for (int i=0; i<lengthOfArray;i++) |
... | ... | |
368 | 494 |
//bind value |
369 | 495 |
pStmt.setString(1, principals[i]);//user name |
370 | 496 |
pStmt.setString(2, docId);//docid |
497 |
|
|
498 |
// if subtree, we need set subtree id |
|
499 |
if (!topLever) |
|
500 |
{ |
|
501 |
pStmt.setString(3, subTreeId); |
|
502 |
} |
|
371 | 503 |
|
372 | 504 |
pStmt.execute(); |
373 | 505 |
ResultSet rs = pStmt.getResultSet(); |
... | ... | |
424 | 556 |
* @param permission, the permssion need to check |
425 | 557 |
*/ |
426 | 558 |
private boolean hasAllowRule(String [] principals, String docId, |
427 |
int permission) |
|
559 |
int permission, String subTreeId)
|
|
428 | 560 |
throws SQLException, Exception |
429 | 561 |
{ |
430 | 562 |
int lengthOfArray=principals.length; |
... | ... | |
436 | 568 |
int ticketCount; |
437 | 569 |
DBConnection conn = null; |
438 | 570 |
int serialNumber = -1; |
571 |
boolean topLever = false; |
|
572 |
String sql = null; |
|
573 |
if (subTreeId == null) |
|
574 |
{ |
|
575 |
// for toplevel |
|
576 |
topLever = true; |
|
577 |
sql = "SELECT permission FROM xml_access WHERE docid = ? " + |
|
578 |
"AND principal_name = ? AND perm_type = ? AND subtreeid is NULL"; |
|
579 |
} |
|
580 |
else |
|
581 |
{ |
|
582 |
topLever =false; |
|
583 |
sql = "SELECT permission FROM xml_access WHERE docid = ? " + |
|
584 |
"AND principal_name = ? AND perm_type = ? AND subtreeid= ?"; |
|
585 |
} |
|
439 | 586 |
try |
440 | 587 |
{ |
441 | 588 |
//check out DBConnection |
... | ... | |
445 | 592 |
//begin_time<=currentTime<=end_time in xml_access table |
446 | 593 |
//If begin_time or end_time is null in table, isnull(begin_time, sysdate) |
447 | 594 |
//function will assign begin_time=sysdate |
448 |
pStmt = conn.prepareStatement( |
|
449 |
"SELECT permission " + |
|
450 |
"FROM xml_access " + |
|
451 |
"WHERE docid = ? " + |
|
452 |
"AND principal_name = ? " + |
|
453 |
"AND perm_type = ? "); |
|
595 |
pStmt = conn.prepareStatement(sql); |
|
454 | 596 |
//bind docid, perm_type |
455 | 597 |
pStmt.setString(1, docId); |
456 | 598 |
pStmt.setString(3, AccessControlInterface.ALLOW); |
599 |
|
|
600 |
// if subtree lever, need to set subTreeId |
|
601 |
if (!topLever) |
|
602 |
{ |
|
603 |
pStmt.setString(4, subTreeId); |
|
604 |
} |
|
457 | 605 |
|
458 | 606 |
//bind every elenment in user name array |
459 | 607 |
for (int i=0;i<lengthOfArray; i++) |
... | ... | |
507 | 655 |
* @param permission, the permssion need to check |
508 | 656 |
*/ |
509 | 657 |
private boolean hasExplicitDenyRule(String [] principals, String docId, |
510 |
int permission)
|
|
658 |
int permission, String subTreeId)
|
|
511 | 659 |
throws SQLException |
512 | 660 |
{ |
513 | 661 |
int lengthOfArray=principals.length; |
... | ... | |
517 | 665 |
int permissionValueInTable; |
518 | 666 |
DBConnection conn = null; |
519 | 667 |
int serialNumber = -1; |
668 |
String sql = null; |
|
669 |
boolean topLevel = false; |
|
520 | 670 |
|
671 |
// decide top level or subtree level |
|
672 |
if (subTreeId == null) |
|
673 |
{ |
|
674 |
topLevel = true; |
|
675 |
sql = "SELECT permission FROM xml_access WHERE docid = ? " + |
|
676 |
"AND principal_name = ? AND perm_type = ? AND subtreeid is NULL"; |
|
677 |
} |
|
678 |
else |
|
679 |
{ |
|
680 |
topLevel = false; |
|
681 |
sql = "SELECT permission FROM xml_access WHERE docid = ? " + |
|
682 |
"AND principal_name = ? AND perm_type = ? AND subtreeid = ?"; |
|
683 |
} |
|
684 |
|
|
521 | 685 |
try |
522 | 686 |
{ |
523 | 687 |
//check out DBConnection |
524 |
conn=DBConnectionPool.getDBConnection("AccessControlList.hasExplicitDeny");
|
|
688 |
conn=DBConnectionPool.getDBConnection("PermissionControl.hasExplicitDeny");
|
|
525 | 689 |
serialNumber=conn.getCheckOutSerialNumber(); |
526 | 690 |
|
527 |
pStmt = conn.prepareStatement( |
|
528 |
"SELECT permission " + |
|
529 |
"FROM xml_access " + |
|
530 |
"WHERE docid = ? " + |
|
531 |
"AND principal_name = ? " + |
|
532 |
"AND perm_type = ? "); |
|
691 |
pStmt = conn.prepareStatement(sql); |
|
533 | 692 |
//bind docid, perm_type |
534 | 693 |
pStmt.setString(1, docId); |
535 | 694 |
pStmt.setString(3, AccessControlInterface.DENY); |
695 |
|
|
696 |
// subtree level need to set up subtreeid |
|
697 |
if (!topLevel) |
|
698 |
{ |
|
699 |
pStmt.setString(4, subTreeId); |
|
700 |
} |
|
536 | 701 |
|
537 | 702 |
//bind every elenment in user name array |
538 | 703 |
for (int i=0;i<lengthOfArray; i++) |
... | ... | |
658 | 823 |
try |
659 | 824 |
{ |
660 | 825 |
//check out DBConnection |
661 |
conn=DBConnectionPool.getDBConnection("AccessControlList.getDataSetId");
|
|
826 |
conn=DBConnectionPool.getDBConnection("PermissionControl.getDataSetId");
|
|
662 | 827 |
serialNumber=conn.getCheckOutSerialNumber(); |
663 | 828 |
|
664 | 829 |
pStmt=conn.prepareStatement(query); |
Also available in: Unified diff
Add the code to handle subtree access control.