Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class that handles checking permssision for a document
4
               and subtree in a document 
5
 *             
6
 *  Copyright: 2000 Regents of the University of California and the
7
 *             National Center for Ecological Analysis and Synthesis
8
 *    Authors: Chad Berkley
9
 *    Release: @release@
10
 *
11
 *   '$Author: tao $'
12
 *     '$Date: 2003-03-19 15:02:00 -0800 (Wed, 19 Mar 2003) $'
13
 * '$Revision: 1492 $'
14
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 2 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
 */
29
package edu.ucsb.nceas.metacat;
30
 
31
import java.sql.*;
32
import java.util.Enumeration;
33
import java.util.Hashtable;
34
import java.util.Stack;
35
import java.util.Vector;
36

    
37
public class PermissionController
38
{
39
   private String docId = null;
40
   private boolean hasSubTreeAccessControl = false; // flag if has a subtree
41
                                                    // access for this docid
42
   private Vector subTreeList = new Vector();
43
   
44
   
45
   /**
46
    * Constructor for PermissionController
47
    * @param myDocid      the docid need to access
48
    */
49
   public PermissionController(String myDocid) throws McdbException
50
   {
51
     // Get rid of rev number
52
     docId = MetaCatUtil.getDocIdFromString(myDocid);
53
     hasSubTreeAccessControl = checkSubTreeAccessControl();
54
   }
55
   
56
   /**
57
    * Return if a document has subtree access control
58
    */
59
   public boolean hasSubTreeAccessControl()
60
   {
61
     return hasSubTreeAccessControl;
62
   }
63
   
64
   /*
65
    * Go through the access table and find if has subtree access control
66
    * if has, store the subtree into list and return true. Otherwise, 
67
    * return false
68
    */
69
  private boolean checkSubTreeAccessControl() throws McdbException
70
  {
71
    boolean flag = false;
72
    PreparedStatement pStmt=null;
73
    ResultSet rs=null;
74
    DBConnection conn=null;
75
    int serialNumber=-1;
76
    String query="SELECT subtreeid, startnodeid, endnodeid from xml_access " +
77
                 "where docid =? ";
78
    
79
    try
80
    {
81
      //check out DBConnection
82
      conn=DBConnectionPool.getDBConnection("PermissionController.hasSubTreeA");
83
      serialNumber=conn.getCheckOutSerialNumber();
84
      
85
      pStmt=conn.prepareStatement(query);
86
      //bind the value to query
87
      pStmt.setString(1, docId);
88
      //execute the query
89
      pStmt.execute();
90
      rs=pStmt.getResultSet();
91
      //process the result
92
      while (rs.next()) //
93
      {
94
        String subTreeId = rs.getString(1);
95
        MetaCatUtil.debugMessage("subtreeid: "+subTreeId, 35);
96
        long startNodeId = rs.getLong(2);
97
        MetaCatUtil.debugMessage("subtree startNodeId: "+startNodeId, 35);
98
        long endNodeId = rs.getLong(3);
99
        MetaCatUtil.debugMessage("subtree endNodeId: "+endNodeId, 35);
100
        // if startnodeid field in table is empty,startNodeId will be 0
101
        if (subTreeId != null && startNodeId != 0 && startNodeId != 0)
102
        {
103
          flag = true;// has subtree control
104
          SubTree tree = new SubTree();
105
          tree.setSubTreeId(subTreeId);
106
          tree.setStartNodeId(startNodeId);
107
          tree.setEndNodeId(endNodeId);
108
          subTreeList.add(tree);
109
         }
110
      }
111
    }//try
112
    catch (SQLException e)
113
    {
114
      throw new McdbException(e);
115
    }
116
    finally
117
    {
118
      try
119
      {
120
        pStmt.close();
121
      }
122
      catch(SQLException ee)
123
      {
124
        throw new McdbException(ee);
125
      }
126
      finally
127
      {
128
        DBConnectionPool.returnDBConnection(conn, serialNumber);
129
      }
130
    }
131
    return flag;
132
  }
133
   
134
  /**
135
    * Check from db connection if at least one of the list of @principals
136
    * @param user  the user name
137
    * @param groups  the groups which the use is in
138
    * @param myPermission  permission type to check for
139
    */
140
  public boolean hasPermission(String user, String[]groups, String myPermission) 
141
                              throws SQLException, Exception
142
  {
143
    boolean hasPermission=false;
144
    String [] userPackage=null;
145
    int permission =AccessControlList.intValue(myPermission);
146
       
147
    //for the commnad line invocation
148
    if ((user==null) && (groups==null || groups.length==0))
149
    {
150
      return true;
151
    }
152
   
153
    //create a userpackage including user, public and group member
154
    userPackage=createUsersPackage(user, groups);
155
    
156
    //if the requested document is access documents and requested permission
157
    //is "write", the user should have "all" right
158
    if (isAccessDocument(docId) && (permission == AccessControlInterface.WRITE))
159
    {
160
      hasPermission = hasPermission(userPackage,docId, 7);// 7 is all permission
161
    }//if
162
    else //in other situation, just check the request permission
163
    {
164
    
165
      // Check for @permission on @docid for @user and/or @groups
166
      hasPermission = hasPermission(userPackage,docId, permission);
167
     
168
    }//else
169
    
170
    return hasPermission;
171
  }
172
  
173
 
174
  /**
175
    * Check from db connection if the users in String array @principals has
176
    * @permission on @docid* 
177
    * @param principals, names in userPakcage need to check for @permission
178
    * @param docid, document identifier to check on
179
    * @param permission, permission (write or all...) to check for 
180
    */
181
  private boolean hasPermission(String [] principals, String docId,
182
                                           int permission)
183
                         throws SQLException
184
  {
185
    String subTreeId = null;// this is for top level, so subtree id is null
186
    try 
187
    {
188
      //first, if there is a docid owner in user package, return true
189
      //because doc owner has all permssion 
190
      if (containDocumentOwner(principals, docId))
191
      {
192
          
193
          return true;
194
      }
195
      
196
      //If there is no owner in user package, checking the table
197
      //check perm_order
198
      if (isAllowFirst(principals, docId, subTreeId))
199
      {
200
        
201
        if (hasExplicitDenyRule(principals, docId, permission, subTreeId))
202
        {
203
          //if it is allowfirst and has deny rule(either explicit )
204
          //deny access
205
          return false;
206
        }//if
207
        else if ( hasAllowRule(principals, docId, permission, subTreeId))
208
        {
209
          //if it is allowfirst and hasn't deny rule and has allow rule
210
          //allow access
211
          return true;
212
        }//else if
213
        else
214
        {
215
          //other situation deny access
216
          return false;
217
        }//else
218
     }//if isAllowFirst
219
     else //denyFirst
220
     {
221
       if (hasAllowRule(principals, docId, permission, subTreeId))
222
       {
223
         //if it is denyFirst and has allow rule, allow access
224
         return true;
225
       }
226
       else
227
       {
228
         //if it is denyfirst but no allow rule, deny access
229
         return false;
230
       }
231
     }//else denyfirst
232
    }//try
233
    catch (Exception e)
234
    {
235
      MetaCatUtil.debugMessage("There is a exception in hasPermission method: "
236
                         +e.getMessage(), 50);
237
    }
238
   
239
    return false;
240
  }//hasPermission
241
  
242
  /**
243
   * The method to determine of a node can be access by a user just by subtree
244
   * access control
245
   */
246
  public boolean hasPermissionForSubTreeNode(String user, String[] groups,
247
                                             String myPermission, long nodeId)
248
                                             throws McdbException
249
  {
250
    boolean flag = true;
251
    // Get unaccessble subtree for this user
252
    Hashtable unaccessableSubTree = hasUnaccessableSubTree(user, groups, 
253
                                                           myPermission);
254
    Enumeration en = unaccessableSubTree.elements();
255
    while (en.hasMoreElements())
256
    {
257
      SubTree tree = (SubTree)en.nextElement();
258
      long start = tree.getStartNodeId();
259
      long stop  = tree.getEndNodeId();
260
      // nodeid in unaccessablesubtree, return false
261
      if ( nodeId >= start && nodeId <= stop)
262
      {
263
        flag = false;
264
        break;
265
      }
266
    }
267
    return flag;
268
  }
269
  /**
270
   * This method will return a hasTable of subtree which user doesn't has the 
271
   * permssion to access
272
   * @param user  the user name
273
   * @param groups  the groups which the use is in
274
   * @param myPermission  permission type to check for
275
   */
276
  public Hashtable hasUnaccessableSubTree(String user, String[] groups, 
277
                                       String myPermission) throws McdbException
278
  {
279
    Hashtable resultUnaccessableSubTree = new Hashtable();
280
    String [] principals=null;
281
    int permission =AccessControlList.intValue(myPermission);
282
    
283
    //for the commnad line invocation return null(no unaccessable subtree)
284
    if ((user==null) && (groups==null || groups.length==0))
285
    {
286
      return resultUnaccessableSubTree;
287
    }
288
    
289
    //create a userpackage including user, public and group member
290
    principals=createUsersPackage(user, groups);
291
    //for the document owner return null(no unaccessable subtree)
292
    try
293
    {
294
      if (containDocumentOwner(principals, docId))
295
      {
296
       return resultUnaccessableSubTree;
297
      }
298
    }
299
    catch (SQLException ee)
300
    {
301
      throw new McdbException(ee);
302
    }
303
    
304
    // go through every subtree which has access control
305
    for (int i = 0; i< subTreeList.size(); i++)
306
    {
307
      SubTree tree = (SubTree)subTreeList.elementAt(i);
308
      String subTreeId = (String)(tree.getSubTreeId());
309
     
310
      if (subTreeId != null)
311
      {
312
        try
313
        {
314
          if (isAllowFirst(principals, docId, subTreeId))
315
          {
316
           
317
            if (hasExplicitDenyRule(principals, docId, permission, subTreeId))
318
            {
319
             
320
             //if it is allowfirst and has deny rule
321
              // put the subtree into unaccessable vector
322
              if (!resultUnaccessableSubTree.containsKey(subTreeId))
323
              {
324
                resultUnaccessableSubTree.put(subTreeId, tree);
325
              }
326
            }//if
327
            else if ( hasAllowRule(principals, docId, permission, subTreeId))
328
            {
329
              //if it is allowfirst and hasn't deny rule and has allow rule
330
              //allow access do nothing
331
              
332
            }//else if
333
            else
334
            {
335
              //other situation deny access
336
              if (!resultUnaccessableSubTree.containsKey(subTreeId))
337
              {
338
                resultUnaccessableSubTree.put(subTreeId, tree);
339
              }
340
             
341
            }//else
342
          }//if isAllowFirst
343
          else //denyFirst
344
          {
345
            if (hasAllowRule(principals, docId, permission,subTreeId))
346
            {
347
              //if it is denyFirst and has allow rule, allow access, do nothing
348
           
349
            }
350
            else
351
            {
352
              //if it is denyfirst but no allow rule, deny access
353
              // add into vector
354
              if (!resultUnaccessableSubTree.containsKey(subTreeId))
355
              {
356
                resultUnaccessableSubTree.put(subTreeId, tree);
357
              }
358
            }
359
          }//else denyfirst
360
        }//try
361
        catch( Exception e)
362
        {
363
          MetaCatUtil.debugMessage("error in PermissionControl.has" +
364
                                   "UnaccessableSubTree "+e.getMessage(), 30);
365
          throw new McdbException(e);
366
        }
367
      }//if
368
    }//for
369
    return resultUnaccessableSubTree;
370
  }//hasUnaccessableSubtree
371
  
372
  /**
373
    * Check if a document id is a access document. Access document need user
374
    * has "all" permission to access it.
375
    * @param docId, the document id need to be checked
376
    */
377
    private boolean isAccessDocument(String docId) throws SQLException
378
    {
379
      //detele the rev number if docid contains it
380
      docId=MetaCatUtil.getDocIdFromString(docId);
381
      PreparedStatement pStmt=null;
382
      DBConnection conn = null;
383
      int serialNumber = -1;
384
      try
385
      {
386
        //check out DBConnection
387
        conn=DBConnectionPool.getDBConnection("PermissionControl.isAccessDoc");
388
        serialNumber=conn.getCheckOutSerialNumber();
389
        pStmt = conn.prepareStatement("select 'x' from xml_access where " +
390
                                      "accessfileid like '" + docId +  "'");
391
        pStmt.execute();
392
        ResultSet rs = pStmt.getResultSet();
393
        boolean hasRow = rs.next();
394
        pStmt.close();
395
        if(hasRow)
396
        {
397
          return true;
398
        }
399
      }
400
      catch(SQLException e)
401
      {
402
       
403
        throw new SQLException("PermissionControl.isAccessDocument " +
404
                     "Error checking" +
405
                     " on document " + docId + ". " + e.getMessage());
406
      }
407
      finally
408
      {
409
        try
410
        {
411
           pStmt.close();
412
        }
413
        finally
414
        {
415
          DBConnectionPool.returnDBConnection(conn, serialNumber);
416
        }
417
      }
418
      return false;
419
    }//isAccessDocument
420
     
421
  
422
  
423
  /**
424
    * Check if a stirng array contains a given documents' owner
425
    * @param principals, a string array storing the username, groups name and
426
    * public.
427
    * @param docid, the id of given documents 
428
    */ 
429
  private boolean containDocumentOwner( String[] principals, String docId)
430
                    throws SQLException
431
  {
432
    int lengthOfArray=principals.length;
433
    boolean hasRow; 
434
    PreparedStatement pStmt=null;
435
    DBConnection conn = null;
436
    int serialNumber = -1;
437
    
438
    try
439
    {
440
      //check out DBConnection
441
     conn=DBConnectionPool.getDBConnection("PermissionControl.containDocOnwer");
442
      serialNumber=conn.getCheckOutSerialNumber();
443
      pStmt = conn.prepareStatement(
444
                "SELECT 'x' FROM xml_documents " +
445
                "WHERE docid = ? AND user_owner = ?"); 
446
      //check every element in the string array too see if it conatains
447
      //the owner of document
448
      for (int i=0; i<lengthOfArray; i++)
449
      {
450
             
451
        // Bind the values to the query
452
        pStmt.setString(1, docId);
453
        pStmt.setString(2, principals[i]);
454

    
455
        pStmt.execute();
456
        ResultSet rs = pStmt.getResultSet();
457
        hasRow = rs.next();
458
        if (hasRow) 
459
        {
460
          pStmt.close();
461
          return true;
462
        }//if    
463
     
464
      }//for
465
    }//try
466
    catch (SQLException e) 
467
    {
468
        pStmt.close();
469
       
470
        throw new 
471
        SQLException("PermissionControl.hasPermission(). " +
472
                     "Error checking ownership for " + principals[0] +
473
                     " on document #" + docId + ". " + e.getMessage());
474
    }//catch
475
    finally
476
    {
477
      try
478
      {
479
        pStmt.close();
480
      }
481
      finally
482
      {
483
        DBConnectionPool.returnDBConnection(conn, serialNumber);
484
      }
485
    }
486
    return false; 
487
  }//containDocumentOwner
488
  
489
  /**
490
    * Check if the permission order for user at that documents is allowFirst
491
    * @param principals, list of names of principals to check for 
492
    * @param docid, document identifier to check for
493
    */
494
  private boolean isAllowFirst(String [] principals, String docId, 
495
                               String subTreeId)
496
                  throws SQLException, Exception
497
  {
498
    int lengthOfArray=principals.length;
499
    boolean hasRow;
500
    PreparedStatement pStmt = null;
501
    DBConnection conn = null;
502
    int serialNumber = -1;
503
    String sql = null;
504
    boolean topLever =false;
505
    if (subTreeId == null)
506
    {
507
      //top level
508
      topLever = true;
509
      sql = "SELECT perm_order FROM xml_access " +
510
            "WHERE principal_name= ? AND docid = ? AND subtreeid is NULL";
511
    }
512
    else
513
    {
514
      //sub tree level
515
      sql = "SELECT perm_order FROM xml_access " +
516
            "WHERE principal_name= ? AND docid = ? AND subtreeid = ?";
517
    }
518
    
519
    try
520
    {
521
      //check out DBConnection
522
      conn=DBConnectionPool.getDBConnection("AccessControlList.isAllowFirst");
523
      serialNumber=conn.getCheckOutSerialNumber();
524
    
525
      //select permission order from database
526
      pStmt = conn.prepareStatement(sql);
527
   
528
      //check every name in the array
529
      for (int i=0; i<lengthOfArray;i++)
530
      {
531
        //bind value
532
        pStmt.setString(1, principals[i]);//user name
533
        pStmt.setString(2, docId);//docid
534
        
535
        // if subtree, we need set subtree id 
536
        if (!topLever)
537
        {
538
          pStmt.setString(3, subTreeId);
539
        }
540
    
541
        pStmt.execute();
542
        ResultSet rs = pStmt.getResultSet();
543
        hasRow=rs.next();
544
        if (hasRow)
545
        {
546
          //get the permission order from data base
547
          String permissionOrder=rs.getString(1);
548
          //if the permission order is "allowFirst
549
          if (permissionOrder.equalsIgnoreCase(AccessControlInterface.ALLOWFIRST))
550
          {
551
            pStmt.close();
552
            return true;
553
          }
554
          else
555
          {
556
            pStmt.close();
557
            return false;
558
          }
559
        }//if
560
      }//for
561
    }//try
562
    catch (SQLException e)
563
    {
564
      throw e;
565
    }
566
    finally
567
    {
568
      try
569
      {
570
        pStmt.close();
571
      }
572
      finally
573
      {
574
        DBConnectionPool.returnDBConnection(conn, serialNumber);
575
      }
576
    }
577
    
578
    //if reach here, means there is no permssion record for given names and 
579
    //docid. So throw a exception.
580
    
581
    throw new Exception("There is no permission record for user"+principals[0]+
582
                        "at document "+docId);
583
        
584
  }//isAllowFirst
585
  
586
  /**
587
    * Check if the users array has allow rules for given users, docid and 
588
    * permission.
589
    * If it has permission rule and ticket count is greater than 0, the ticket
590
    * number will decrease one for every allow rule
591
    * @param principals, list of names of principals to check for 
592
    * @param docid, document identifier to check for
593
    * @param permission, the permssion need to check
594
    */
595
  private boolean hasAllowRule(String [] principals, String docId, 
596
                                  int permission, String subTreeId)
597
                  throws SQLException, Exception
598
 {
599
   int lengthOfArray=principals.length;
600
   boolean allow=false;//initial value is no allow rule
601
   ResultSet rs;
602
   PreparedStatement pStmt = null;
603
   int permissionValue=permission;
604
   int permissionValueInTable;
605
   int ticketCount;
606
   DBConnection conn = null;
607
   int serialNumber = -1;
608
   boolean topLever = false;
609
   String sql = null;
610
   if (subTreeId == null)
611
   {
612
     // for toplevel
613
     topLever = true;
614
     sql = "SELECT permission FROM xml_access WHERE docid = ? " +  
615
           "AND principal_name = ? AND perm_type = ? AND subtreeid is NULL";
616
   }
617
   else
618
   {
619
     topLever =false;
620
     sql = "SELECT permission FROM xml_access WHERE docid = ? " +  
621
           "AND principal_name = ? AND perm_type = ? AND subtreeid= ?";
622
   }
623
   try
624
   {
625
     //check out DBConnection
626
     conn=DBConnectionPool.getDBConnection("AccessControlList.hasAllowRule");
627
     serialNumber=conn.getCheckOutSerialNumber();
628
    //This sql statement will select entry with 
629
    //begin_time<=currentTime<=end_time in xml_access table
630
    //If begin_time or end_time is null in table, isnull(begin_time, sysdate)
631
    //function will assign begin_time=sysdate
632
    pStmt = conn.prepareStatement(sql);
633
    //bind docid, perm_type
634
    pStmt.setString(1, docId);
635
    pStmt.setString(3, AccessControlInterface.ALLOW);
636
    
637
    // if subtree lever, need to set subTreeId
638
    if (!topLever)
639
    {
640
      pStmt.setString(4, subTreeId);
641
    }
642
   
643
    //bind every elenment in user name array
644
    for (int i=0;i<lengthOfArray; i++)
645
    {
646
      pStmt.setString(2, principals[i]);
647
      pStmt.execute();
648
      rs=pStmt.getResultSet();
649
      while (rs.next())//check every entry for one user
650
      {
651
        permissionValueInTable=rs.getInt(1);
652
            
653
        //permission is ok  
654
        //the user have a permission to access the file
655
        if (( permissionValueInTable & permissionValue )== permissionValue )
656
        {
657
           allow=true;//has allow rule entry
658
        }//if
659
      }//while
660
    }//for
661
   }//try
662
   catch (SQLException sqlE)
663
   {
664
     throw sqlE;
665
   }
666
   catch (Exception e)
667
   {
668
     throw e;
669
   }
670
   finally
671
   {
672
     try
673
     {
674
       pStmt.close();
675
     }
676
     finally
677
     {
678
       DBConnectionPool.returnDBConnection(conn, serialNumber);
679
     }
680
   }
681
    return allow;
682
 }//hasAllowRule
683
 
684
 
685
   
686
   /**
687
    * Check if the users array has explicit deny rules for given users, docid 
688
    * and permission. That means the perm_type is deny and current time is
689
    * less than end_time and greater than begin time, or no time limit.
690
    * @param principals, list of names of principals to check for 
691
    * @param docid, document identifier to check for
692
    * @param permission, the permssion need to check
693
    */
694
  private boolean hasExplicitDenyRule(String [] principals, String docId, 
695
                                      int permission, String subTreeId)
696
                  throws SQLException
697
 {
698
   int lengthOfArray=principals.length;
699
   ResultSet rs;
700
   PreparedStatement pStmt = null;
701
   int permissionValue=permission;
702
   int permissionValueInTable;
703
   DBConnection conn = null;
704
   int serialNumber = -1;
705
   String sql = null;
706
   boolean topLevel = false;
707
   
708
   // decide top level or subtree level
709
   if (subTreeId == null)
710
   {
711
     topLevel = true;
712
     sql = "SELECT permission FROM xml_access WHERE docid = ? " + 
713
            "AND principal_name = ? AND perm_type = ? AND subtreeid is NULL";
714
   }
715
   else
716
   {
717
     topLevel = false;
718
     sql = "SELECT permission FROM xml_access WHERE docid = ? " + 
719
            "AND principal_name = ? AND perm_type = ? AND subtreeid = ?";
720
   }
721
   
722
   try
723
   {
724
     //check out DBConnection
725
     conn=DBConnectionPool.getDBConnection("PermissionControl.hasExplicitDeny");
726
     serialNumber=conn.getCheckOutSerialNumber();
727
   
728
     pStmt = conn.prepareStatement(sql);
729
    //bind docid, perm_type
730
    pStmt.setString(1, docId);
731
    pStmt.setString(3, AccessControlInterface.DENY);
732
    
733
    // subtree level need to set up subtreeid
734
    if (!topLevel)
735
    {
736
      pStmt.setString(4, subTreeId);
737
    }
738
   
739
    //bind every elenment in user name array
740
    for (int i=0;i<lengthOfArray; i++)
741
    {
742
      pStmt.setString(2, principals[i]);
743
      pStmt.execute();
744
      rs=pStmt.getResultSet();
745
      while (rs.next())//check every entry for one user
746
      {
747
        permissionValueInTable=rs.getInt(1);
748
        
749
        //permission is ok the user doesn't have permission to access the file
750
        if (( permissionValueInTable & permissionValue )== permissionValue )
751
             
752
        {
753
           pStmt.close();
754
           return true;
755
         }//if
756
      }//while
757
    }//for
758
   }//try
759
   catch (SQLException e)
760
   {
761
     throw e;
762
   }//catch
763
   finally
764
   {
765
     try
766
     {
767
       pStmt.close();
768
     }
769
     finally
770
     {
771
       DBConnectionPool.returnDBConnection(conn, serialNumber);
772
     }
773
   }//finally
774
   return false;//no deny rule
775
  }//hasExplicitDenyRule 
776
   
777

    
778
  /**
779
    * Creat a users pakages to check permssion rule, user itself, public and
780
    * the gourps the user belong will be include in this package
781
    * @param user, the name of user
782
    * @param groups, the string array of the groups that user belong to
783
    */
784
  private String[] createUsersPackage(String user, String [] groups)
785
  {
786
    String [] usersPackage=null;
787
    int lengthOfPackage;
788
    
789
    if (groups!=null)
790
    {
791
      //if gouprs is not null and user is not public, we should create a array 
792
      //to store the groups and user and public. 
793
      //So the length of userPackage is the length of group plus two
794
      if (!user.equalsIgnoreCase(AccessControlInterface.PUBLIC))
795
      {
796
        lengthOfPackage=(groups.length)+2;
797
        usersPackage=new String [lengthOfPackage];
798
        //the first two elements is user self and public
799
        usersPackage[0]=user;
800
        usersPackage[1]=AccessControlInterface.PUBLIC;
801
        //put groups element from index 0 to lengthOfPackage-3 into userPackage
802
        //from index 2 to lengthOfPackage-1
803
        for (int i=2; i<lengthOfPackage; i++)
804
        {
805
          usersPackage[i]=groups[i-2];
806
        } //for
807
      }//if user!=public
808
      else//use=public
809
      {
810
        lengthOfPackage=(groups.length)+1;
811
        usersPackage=new String [lengthOfPackage];
812
        //the first lements is public
813
        usersPackage[0]=AccessControlInterface.PUBLIC;
814
        //put groups element from index 0 to lengthOfPackage-2 into userPackage
815
        //from index 1 to lengthOfPackage-1
816
        for (int i=1; i<lengthOfPackage; i++)
817
        {
818
          usersPackage[i]=groups[i-1];
819
        } //for
820
      }//else user=public
821
       
822
    }//if groups!=null
823
    else
824
    {
825
      //because no groups, the userPackage only need two elements
826
      //one is for user, the other is for public
827
      if (!user.equalsIgnoreCase(AccessControlInterface.PUBLIC))
828
      {
829
        lengthOfPackage=2;
830
        usersPackage=new String [lengthOfPackage];
831
        usersPackage[0]=user;
832
        usersPackage[1]=AccessControlInterface.PUBLIC;
833
      }//if user!=public
834
      else //user==public
835
      {
836
        //only put public into array
837
        lengthOfPackage=1;
838
        usersPackage=new String [lengthOfPackage];
839
        usersPackage[0]=AccessControlInterface.PUBLIC;
840
      }
841
    }//else groups==null
842
    return usersPackage;
843
  }//createUsersPackage
844
 
845
  /**
846
    * This method will return a data set id for given access id.
847
    * @param accessDocId, the accessDocId which need to be found data set id
848
   */
849
  private String getDataSetId(String accessDocId) 
850
                              throws SQLException
851
  {
852
    String dataSetId=null;
853
    PreparedStatement pStmt=null;
854
    ResultSet rs=null;
855
    DBConnection conn=null;
856
    int serialNumber=-1;
857
    String query="SELECT docId from xml_relation where subject = ? or "
858
                                                +"object = ?";
859
    
860
    try
861
    {
862
      //check out DBConnection
863
      conn=DBConnectionPool.getDBConnection("PermissionControl.getDataSetId");
864
      serialNumber=conn.getCheckOutSerialNumber();
865
      
866
      pStmt=conn.prepareStatement(query);
867
      //bind the value to query
868
      pStmt.setString(1, accessDocId);
869
      pStmt.setString(2, accessDocId);
870
      //execute the query
871
      pStmt.execute();
872
      rs=pStmt.getResultSet();
873
      //process the result
874
      if (rs.next()) //There are some records for the data set id for access id
875
      {
876
        dataSetId=rs.getString(1);
877
      }
878
      else //No data set id for the given access id in xml_relation table
879
      {
880
        dataSetId=null;
881
      }
882
    }//try
883
    finally
884
    {
885
      try
886
      {
887
        pStmt.close();
888
      }
889
      finally
890
      {
891
        DBConnectionPool.returnDBConnection(conn, serialNumber);
892
      }
893
    }
894
    return dataSetId;
895
  }//getDataPackageId() 
896
  
897
  /**
898
    * To create a part of query: "docid like '" +str1+ "', " +"docid like '" 
899
    * +str2+"'" ... We need to check user, group and public together for the 
900
    * permission. So we need the principal in an array and according the array
901
    * to create a part of query which will be used in other methods
902
    * @param principals, a string array storing the username, groups name and
903
    * public.
904
    */
905
   private String partQueryAboutDocId( String [] principals)
906
   {
907
     String partQuery="";
908
     int lengthOfArray=principals.length;
909
     
910
     for (int i=0;i<(lengthOfArray-1);i++)
911
     {
912
        partQuery=partQuery+"docid like '"+principals[i]+"',";
913
     }
914
     
915
     //the last one dosen't has "'"
916
     partQuery=partQuery+"docid like '"+principals[(lengthOfArray-1)]+"'";
917
     return partQuery;
918
     
919
   }
920
}
(44-44/54)