Project

General

Profile

« Previous | Next » 

Revision 425

Added by bojilova over 23 years ago

storing user_owner and user_updated where needed
new function in DocumentImpl checking for "write" perm on UPDATE or DELETE
added delete from xml_index of the old version of docid on UPDATE

View differences:

src/edu/ucsb/nceas/metacat/DBSAXHandler.java
44 44
   private DBSAXNode    rootNode;
45 45
   private String       action = null;
46 46
   private String       docid = null;
47
   private String       user = null;
47 48

  
48 49
   private static final int MAXDATACHARS = 4000;
49 50

  
......
67 68
   /** Construct an instance of the handler class 
68 69
    *
69 70
    * @param conn the JDBC connection to which information is written
71
    * @param action - "INSERT" or "UPDATE"
72
    * @param docid to be inserted or updated into JDBC connection
73
    * @param user the user connected to MetaCat servlet
70 74
    */
71
   public DBSAXHandler(Connection conn, String action, String docid) {
75
   public DBSAXHandler(Connection conn,String action,String docid,String user)
76
   {
72 77
     this(conn);
73 78
     this.action = action;
74 79
     this.docid = docid;
80
     this.user = user;
75 81
   }
76 82

  
77 83
   /** SAX Handler that receives notification of beginning of the document */
......
130 136
       rootNode.writeNodename(docname);
131 137
       try {
132 138
         currentDocument = new DocumentImpl(conn, rootNode.getNodeID(), 
133
                                           docname, doctype, docid, action);
139
                                       docname, doctype, docid, action, user);
134 140
       } catch (AccessionNumberException ane) {
135 141
         throw (new SAXException("Error with " + action, ane));
136 142
       }
src/edu/ucsb/nceas/metacat/DocumentImpl.java
38 38
 */
39 39
public class DocumentImpl {
40 40

  
41
  static final int ALL = 1;
42
  static final int WRITE = 2;
43
  static final int READ = 4;
44

  
41 45
  private Connection conn = null;
42 46
  private String docid = null;
43 47
  private String docname = null;
......
95 99
   *
96 100
   */
97 101
  public DocumentImpl(Connection conn, long rootnodeid, String docname, 
98
                      String doctype, String docid, String action)
102
                      String doctype, String docid, String action, String user)
99 103
                      throws AccessionNumberException 
100 104
  {
101 105
    this.conn = conn;
......
103 107
    this.docname = docname;
104 108
    this.doctype = doctype;
105 109
    this.docid = docid;
106
    writeDocumentToDB(action);
110
    writeDocumentToDB(action, user);
107 111
  }
108 112

  
109 113
  /**
......
287 291
   * @param docid the docid to use for the INSERT OR UPDATE
288 292
   */
289 293
  public static String write( Connection conn, String filename, String action, 
290
                              String docid )
291
                throws Exception, IOException, SQLException, 
292
                       ClassNotFoundException, SAXException, SAXParseException {
293
     return write(conn, new FileReader(new File(filename).toString()), 
294
                  action, docid);
294
                              String docid, String user, String group )
295
                throws IOException, SQLException, ClassNotFoundException,
296
                       SAXException, SAXParseException, Exception {
297

  
298
    return write(conn, new FileReader(new File(filename).toString()), 
299
                  action, docid, user, group);
295 300
  }
296 301
  
297 302
  /**
......
303 308
   * @param docid the docid to use for the INSERT OR UPDATE
304 309
   */
305 310
  public static String write( Connection conn, Reader xml, String action, 
306
                              String docid )
307
                throws Exception, IOException, SQLException, 
308
                       ClassNotFoundException, SAXException, SAXParseException {
311
                              String docid, String user, String group )
312
                throws IOException, SQLException, ClassNotFoundException,
313
                       SAXException, SAXParseException, Exception {
314

  
315
    if ( action.equals("UPDATE") ) {
316
      // Determine if the docid is OK for an UPDATE
317
      AccessionNumber ac = new AccessionNumber();
318
      String newdocid = ac.generate(docid, "UPDATE");
319

  
320
      // b' of the command line invocation
321
      if ( (user != null) &&  (group != null) ) { 
322
        if ( !hasWritePermission(conn, docid, user, group) ) {
323
          throw new Exception("User " + user + 
324
                " does not have permission to update XML Document #" + docid);
325
        }        
326
      }          
327
    }
328

  
309 329
    try {
310
        XMLReader parser = initializeParser(conn, action, docid);
330
        XMLReader parser = initializeParser(conn, action, docid, user);
311 331
        conn.setAutoCommit(false);
312 332
        parser.parse(new InputSource(xml));
313 333
        conn.commit();
......
350 370
   *
351 371
   * @param docid the ID of the document to be deleted from the database
352 372
   */
353
  public static void delete( Connection conn, String docid )
354
                  throws IOException, SQLException, 
355
                         ClassNotFoundException, AccessionNumberException {
373
  public static void delete( Connection conn, String docid,
374
                                 String user, String group )
375
                throws IOException, SQLException, ClassNotFoundException, 
376
                       AccessionNumberException, Exception {
356 377

  
357 378
    AccessionNumber ac = new AccessionNumber();
358 379
    String newdocid = ac.generate(docid, "DELETE");
359 380

  
381
    if ( (user != null) &&  (group != null) ) {
382
      if ( !hasWritePermission(conn, docid, user, group) ) {
383
        throw new Exception("User " + user + 
384
                " does not have permission to delete XML Document #" + docid);
385
      }          
386
    }
387

  
360 388
    conn.setAutoCommit(false);
361 389
    // Copy the record to the xml_revisions table
362
    DocumentImpl.archiveDocRevision( conn, docid );
390
    DocumentImpl.archiveDocRevision( conn, docid, user );
363 391

  
364 392
    // Now delete it from the xml_documents table
365 393
    Statement stmt = conn.createStatement();
366
    stmt.execute("DELETE FROM xml_index WHERE docid LIKE '" + docid + "'");
367
    stmt.execute("DELETE FROM xml_documents WHERE docid LIKE '" + docid + "'");
394
    stmt.execute("DELETE FROM xml_index WHERE docid = '" + docid + "'");
395
    stmt.execute("DELETE FROM xml_documents WHERE docid = '" + docid + "'");
368 396
    stmt.close();
369 397
    conn.commit();
370 398
  }
399
  
400
  /** Check for "write" permissions from DB connection */
401
  private static boolean hasWritePermission(Connection conn, String docid, 
402
                                     String user, String group) 
403
                                     throws SQLException {
404
    PreparedStatement pstmt;
405
    // checking if user is owner of docid
406
    try {
407
      pstmt = conn.prepareStatement(
408
                   "SELECT docid FROM xml_documents " +
409
                   "WHERE docid LIKE ? AND user_owner LIKE ?");
410
      // Bind the values to the query
411
      pstmt.setString(1, docid);
412
      pstmt.setString(2, user);
371 413

  
414
      pstmt.execute();
415
      ResultSet rs = pstmt.getResultSet();
416
      boolean hasRow = rs.next();
417
      pstmt.close();
418
      if (hasRow) {
419
        return true;
420
      }
421
      
422
    } catch (SQLException e) {
423
      throw new 
424
        SQLException("Error getting document's owner: " + e.getMessage());
425
    }
426

  
427
    // checking access type from xml_access table
428
    int accesstype = 0;
429
    try {
430
      pstmt = conn.prepareStatement(
431
                   "SELECT access_type FROM xml_access " +
432
                   "WHERE docid LIKE ? " + 
433
                   "AND principal_name LIKE ? " +
434
                   "AND principal_type = 'user' " +
435
                   "AND sysdate BETWEEN begin_time AND end_time " +
436
                   "UNION " +
437
                   "SELECT access_type FROM xml_access " +
438
                   "WHERE docid LIKE ? " + 
439
                   "AND principal_name LIKE ? " +
440
                   "AND principal_type = 'group' " +
441
                   "AND sysdate BETWEEN begin_time AND end_time");
442
      // Bind the values to the query
443
      pstmt.setString(1, docid);
444
      pstmt.setString(2, user);
445
      pstmt.setString(3, docid);
446
      pstmt.setString(2, group);
447

  
448
      pstmt.execute();
449
      ResultSet rs = pstmt.getResultSet();
450
      boolean hasRows = rs.next();
451
      if ( !hasRows ) {
452
        pstmt.close();
453
        return false;
454
      }
455

  
456
      accesstype = rs.getInt(1);
457
      pstmt.close();
458
      
459
      accesstype = accesstype | WRITE;
460
      if ( (accesstype & WRITE) == WRITE ) {
461
        return true;
462
      }
463
      
464
      return false;
465
      
466
    } catch (SQLException e) {
467
      throw new 
468
      SQLException("Error getting document's permissions: " + e.getMessage());
469
    }
470
  }
471

  
372 472
  /** creates SQL code and inserts new document into DB connection */
373
  private void writeDocumentToDB(String action) 
473
  private void writeDocumentToDB(String action, String user) 
374 474
               throws AccessionNumberException {
375 475
    try {
376 476
      PreparedStatement pstmt = null;
......
381 481
        pstmt = conn.prepareStatement(
382 482
            "INSERT INTO xml_documents " +
383 483
            "(docid, rootnodeid, docname, doctype, " +
384
            "date_created, date_updated) " +
385
            "VALUES (?, ?, ?, ?, sysdate, sysdate)");
484
            "user_owner, user_updated, date_created, date_updated) " +
485
            "VALUES (?, ?, ?, ?, ?, ?, sysdate, sysdate)");
386 486
        // Bind the values to the query
387 487
        pstmt.setString(1, this.docid);
388 488
        pstmt.setLong(2, rootnodeid);
389 489
        pstmt.setString(3, docname);
390 490
        pstmt.setString(4, doctype);
491
        pstmt.setString(5, user);
492
        pstmt.setString(6, user);
391 493
      } else if (action.equals("UPDATE")) {
392 494

  
393
        // Determine if the docid is OK for an UPDATE
394
        AccessionNumber ac = new AccessionNumber();
395
        this.docid = ac.generate(docid, "UPDATE");
495
//    moved the check earlier before start of parsing
496
//        // Determine if the docid is OK for an UPDATE
497
//        AccessionNumber ac = new AccessionNumber();
498
//        this.docid = ac.generate(docid, "UPDATE");
396 499

  
397 500
        // Save the old document entry in a backup table
398
        DocumentImpl.archiveDocRevision( conn, docid );
501
        DocumentImpl.archiveDocRevision( conn, docid, user );
399 502

  
503
        // Delete index for the old version of docid
504
        // The new index is inserting on the next calls to DBSAXNode
505
        pstmt = conn.prepareStatement(
506
                "DELETE FROM xml_index WHERE docid='" + this.docid + "'");
507
        pstmt.execute();
508
        pstmt.close();
509

  
400 510
        // Update the new document to reflect the new node tree
401 511
        pstmt = conn.prepareStatement(
402 512
            "UPDATE xml_documents " +
403 513
            "SET rootnodeid = ?, docname = ?, doctype = ?, " +
404
            "date_updated = sysdate WHERE docid LIKE ?");
514
            "user_updated = ?, date_updated = sysdate WHERE docid LIKE ?");
405 515
        // Bind the values to the query
406 516
        pstmt.setLong(1, rootnodeid);
407 517
        pstmt.setString(2, docname);
408 518
        pstmt.setString(3, doctype);
409
        pstmt.setString(4, this.docid);
519
        pstmt.setString(4, user);
520
        pstmt.setString(5, this.docid);
410 521
      } else {
411 522
        System.err.println("Action not supported: " + action);
412 523
      }
......
516 627
  }
517 628

  
518 629
  /** Save a document entry in the xml_revisions table */
519
  private static void archiveDocRevision(Connection conn, String docid) 
520
                      throws SQLException {
630
  private static void archiveDocRevision(Connection conn, String docid,
631
                                         String user) throws SQLException {
521 632
    // First get all of the values we need
522 633
    long rnodeid = -1;
523 634
    String docname = null;
524 635
    String doctype = null;
525 636
    String doctitle = null;
637
    String user_owner = null;
526 638
    Date date_created = null;
527 639
    PreparedStatement pstmt = conn.prepareStatement(
528
       "SELECT rootnodeid, docname, doctype, doctitle, date_created " +
529
       "FROM xml_documents " +
530
       "WHERE docid = ?");
640
      "SELECT rootnodeid,docname,doctype,doctitle,user_owner,date_created " +
641
      "FROM xml_documents " +
642
      "WHERE docid = ?");
531 643
    // Bind the values to the query and execute it
532 644
    pstmt.setString(1, docid);
533 645
    pstmt.execute();
......
539 651
      docname      = rs.getString(2);
540 652
      doctype      = rs.getString(3);
541 653
      doctitle     = rs.getString(4);
542
      date_created = rs.getDate(5);
654
      user_owner   = rs.getString(5);
655
      date_created = rs.getDate(6);
543 656
    }
544 657
    pstmt.close();
545 658

  
......
552 665
    pstmt = conn.prepareStatement(
553 666
       "INSERT INTO xml_revisions " +
554 667
       "(revisionid, docid, rootnodeid, docname, doctype, doctitle, " +
555
       "date_created, date_updated) " +
556
       "VALUES (null, ?, ?, ?, ?, ?, sysdate, sysdate)");
668
       "user_owner, user_updated, date_created, date_updated) " +
669
       "VALUES (null, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)");
557 670
    // Bind the values to the query and execute it
558 671
    pstmt.setString(1, docid);
559 672
    pstmt.setLong(2, rnodeid);
560 673
    pstmt.setString(3, docname);
561 674
    pstmt.setString(4, doctype);
562 675
    pstmt.setString(5, doctitle);
676
    pstmt.setString(6, user_owner);
677
    pstmt.setString(7, user);
563 678
    //pstmt.setDate(6, date_created);
564 679
    pstmt.execute();
565 680
    pstmt.close();
......
569 684
   * Set up the parser handlers for writing the document to the database
570 685
   */
571 686
  private static XMLReader initializeParser(Connection conn,
572
                           String action, String docid) {
687
                           String action, String docid, String user) {
573 688
    XMLReader parser = null;
574 689
    //
575 690
    // Set up the SAX document handlers for parsing
576 691
    //
577 692
    try {
578
      ContentHandler chandler   = new DBSAXHandler(conn, action, docid);
693
      ContentHandler chandler   = new DBSAXHandler(conn, action, docid, user);
579 694
      EntityResolver dbresolver = new DBEntityResolver(conn, 
580 695
                                      (DBSAXHandler)chandler);
581 696
      DTDHandler dtdhandler     = new DBDTDHandler(conn);
......
680 795
          DocumentImpl xmldoc = new DocumentImpl( dbconn, docid );
681 796
          System.out.println(xmldoc.toString());
682 797
      } else if (action.equals("DELETE")) {
683
        DocumentImpl.delete(dbconn, docid);
798
        DocumentImpl.delete(dbconn, docid, null, null);
684 799
        System.out.println("Document deleted: " + docid);
685 800
      } else {
686
        String newdocid = DocumentImpl.write(dbconn, filename, action, docid);
801
        String newdocid = DocumentImpl.write(dbconn, filename, action, docid,
802
                                                                  null, null);
687 803
        if ((docid != null) && (!docid.equals(newdocid))) {
688 804
          if (action.equals("INSERT")) {
689 805
            System.out.println("New document ID generated!!! ");
src/edu/ucsb/nceas/metacat/MetaCatServlet.java
217 217
    // by looking up the current session information for all actions
218 218
    // other than "Login" and "Logout"
219 219
    // handle login action
220
    String username = null;
221
    String groupname = null;
220 222
    if (action.equals("Login") || action.equals("Login Client")) {
221 223
      handleLoginAction(out, params, request, response);
222 224
    // handle logout action  
......
241 243
        // redirect to default page for query only access
242 244

  
243 245
      //  response.sendRedirect(htmlpath + "/sexpire.html");
244

  
245
      } 
246
      } else {
247
        username = (String)sess.getAttribute("username");
248
        groupname = (String)sess.getAttribute("groupname");
249
      }  
246 250
    }    
247 251

  
248 252
    // Now that we know the session is valid, we can delegate the request
......
272 276
        out.println(se.getMessage());
273 277
      }
274 278
    } else if (action.equals("insert") || action.equals("update")) {
275
      handleInsertOrUpdateAction(out, params, response);
279
      if ( !username.equals("public") && (username != null) ) {
280
        handleInsertOrUpdateAction(out, params, response, username, groupname);
281
      } else {  
282
        out.println("Permission denied for " + action);
283
      }  
276 284
    } else if (action.equals("delete")) {
277
      handleDeleteAction(out, params, response);
285
      if ( !username.equals("public") && (username != null) ) {
286
        handleDeleteAction(out, params, response, username, groupname);
287
      } else {  
288
        out.println("Permission denied for " + action);
289
      }  
278 290
    } else if (action.equals("validate")) {
279 291
      handleValidateAction(out, params, response);  
280 292
    } else if (action.equals("getdatadoc")) {
......
396 408
    Hashtable doclist = runQuery(xmlquery);
397 409
    String qformat = ((String[])params.get("qformat"))[0]; 
398 410
    String resultdoc = createResultDocument(doclist, transformQuery(params));
411

  
399 412
    //format and transform the results                                        
400 413
    if(qformat.equals("html")) {
401 414
      transformResultset(resultdoc, response, out);
......
575 588
   * to the database connection
576 589
   */
577 590
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
578
               HttpServletResponse response) {
591
               HttpServletResponse response, String user, String group) {
579 592

  
580 593
    Connection conn = null;
581 594

  
......
607 620
                if (accNumber.equals("")) {
608 621
                    accNumber = null;
609 622
                }
610
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber);  
623
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber, 
624
                                                                  user, group);
611 625
            } catch (NullPointerException npe) {
612
              newdocid = DocumentImpl.write(conn, xml, doAction, null);
626
              newdocid = DocumentImpl.write(conn,xml,doAction,null,user,group);
613 627
            }
614 628
        } catch (Exception e) {
615 629
          response.setContentType("text/html");
......
653 667
   * from the database connection
654 668
   */
655 669
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
656
               HttpServletResponse response) {
670
               HttpServletResponse response, String user, String group) {
657 671

  
658 672
    String[] docid = (String[])params.get("docid");
659 673
    Connection conn = null;
......
666 680
                                      // FOR EXISTENCE OF DOCID PARAM
667 681
                                      // BEFORE ACCESSING ARRAY
668 682
      try { 
669
        DocumentImpl.delete(conn, docid[0]);
683
        DocumentImpl.delete(conn, docid[0], user, group);
670 684
        response.setContentType("text/xml");
671 685
        out.println("<?xml version=\"1.0\"?>");
672 686
        out.println("<success>");

Also available in: Unified diff