Project

General

Profile

Revision 1434

Added by Jing Tao over 18 years ago

Add the code to handle subtree access control.

View differences:

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