Project

General

Profile

Revision 6122

include GUID column for xml_access and related methods for storing/retrieving access rules

View differences:

test/edu/ucsb/nceas/metacat/dataone/CNCoreTest.java
1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *  Purpose: To test the Access Controls in metacat by JUnit
6
 *
7
 *   '$Author$'
8
 *     '$Date$'
9
 * '$Revision$'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

  
26
package edu.ucsb.nceas.metacat.dataone;
27

  
28
import java.util.Date;
29

  
30
import junit.framework.Test;
31
import junit.framework.TestSuite;
32

  
33
import org.dataone.service.types.Checksum;
34
import org.dataone.service.types.ChecksumAlgorithm;
35
import org.dataone.service.types.Identifier;
36
import org.dataone.service.types.NodeReference;
37
import org.dataone.service.types.ObjectFormat;
38
import org.dataone.service.types.Session;
39
import org.dataone.service.types.Subject;
40
import org.dataone.service.types.SystemMetadata;
41

  
42
import edu.ucsb.nceas.MCTestCase;
43

  
44
/**
45
 * A JUnit test for testing the dataone CNCore implementation
46
 */
47
public class CNCoreTest extends MCTestCase {   
48
    
49
    /**
50
    * constructor for the test
51
    */
52
    public CNCoreTest(String name)
53
    {
54
        super(name);
55
    }
56
  
57
    /**
58
	 * Establish a testing framework by initializing appropriate objects
59
	 */
60
	public void setUp() throws Exception 
61
	{
62
		super.setUp();
63
	}
64

  
65
	/**
66
	 * Release any objects after tests are complete
67
	 */
68
	public void tearDown() 
69
	{
70
	}
71

  
72
	/**
73
	 * Create a suite of tests to be run together
74
	 */
75
	public static Test suite() 
76
	{
77
		TestSuite suite = new TestSuite();
78
		suite.addTest(new CNCoreTest("initialize"));
79
		
80
		suite.addTest(new CNCoreTest("testRegisterSystemMetadata"));
81
	
82
		return suite;
83
	}
84
	
85
	/**
86
	 * test for registering standalone system metadata
87
	 */
88
	public void testRegisterSystemMetadata()
89
	{
90
	    printTestHeader("testRegisterSystemMetadata");
91

  
92
	    try {
93
            Session session = new Session();
94
            Subject subject = new Subject();
95
            subject.setValue("cn=test,dc=dataone,dc=org");
96
            session.setSubject(subject);
97
			Identifier guid = new Identifier();
98
			guid.setValue("testRegisterSystemMetadata." + System.currentTimeMillis());
99
			SystemMetadata sysmeta = createSystemMetadata(guid, subject);
100
			CNCoreImpl.getInstance().registerSystemMetaData(session, guid, sysmeta);
101
        }
102
        catch(Exception e)
103
        {
104
            fail("Unexpected error in testDescribe: " + e.getMessage());
105
        }
106
	}
107
	
108
	/**
109
	 * Run an initial test that always passes to check that the test harness is
110
	 * working.
111
	 */
112
	public void initialize() 
113
	{
114
	    printTestHeader("initialize");
115
		assertTrue(1 == 1);
116
	}
117
	
118
	
119
	/**
120
	 * create system metadata with a specified id
121
	 */
122
	private SystemMetadata createSystemMetadata(Identifier id, Subject owner)
123
	  throws Exception
124
	{
125
	    SystemMetadata sm = new SystemMetadata();
126
        //set the id
127
        sm.setIdentifier(id);
128
        sm.setObjectFormat(ObjectFormat.OCTET_STREAM);
129
        //create the checksum
130
        String checksumS = "test";
131
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
132
        Checksum checksum = new Checksum();
133
        checksum.setValue(checksumS);
134
        checksum.setAlgorithm(ca);
135
        sm.setChecksum(checksum);
136
        //set the size
137
        sm.setSize(0);
138
        sm.setSubmitter(owner);
139
        sm.setRightsHolder(owner);
140
        sm.setDateUploaded(new Date());
141
        sm.setDateSysMetadataModified(new Date());
142
        NodeReference nr = new NodeReference();
143
        nr.setValue("metacat");
144
        sm.setOriginMemberNode(nr);
145
        sm.setAuthoritativeMemberNode(nr);
146
        return sm;
147
	}
148
	
149
	/**
150
	 * print a header to start each test
151
	 */
152
	private void printTestHeader(String testName)
153
	{
154
	    System.out.println();
155
	    System.out.println("*************** " + testName + " ***************");
156
	}
157
 
158
}
0 159

  
src/xmltables-oracle.sql
282 282
 */
283 283
CREATE TABLE xml_access (
284 284
	docid		VARCHAR2(250),	-- the document id #
285
	guid   VARCHAR2(2000),    -- the globally unique string identifier
285 286
	accessfileid	VARCHAR2(250),	-- the document id # for the access file
286 287
	principal_name	VARCHAR2(100),	-- name of user, group, etc.
287 288
	permission	NUMBER(1),	-- "read", "write", "all"
src/xmltables-postgres.sql
206 206
 */
207 207
CREATE TABLE xml_access (
208 208
	docid VARCHAR(250),	-- the document id #
209
	guid text,	-- foreign key to system metadata
209 210
	accessfileid VARCHAR(250),	-- the document id # for the access file
210 211
	principal_name VARCHAR(100),	-- name of user, group, etc.
211 212
	permission INT8,		-- "read", "write", "all"
......
226 227
CREATE INDEX xml_access_idx3 ON xml_access (perm_type);
227 228
CREATE INDEX xml_access_idx4 ON xml_access (perm_order);
228 229
CREATE INDEX xml_access_idx5 ON xml_access (subtreeid);
230
/*
231
 * ALTER TABLE xml_access ADD COLUMN guid text;
232
*/
229 233

  
230 234
/*
231 235
 * Index of Nodes -- table to store precomputed paths through tree for
src/edu/ucsb/nceas/metacat/accesscontrol/XMLAccessAccess.java
44 44
	
45 45
	private Logger logMetacat = Logger.getLogger(XMLAccessAccess.class);
46 46
	
47
	private static String DOCID = "docid";
48
	
49
	private static String GUID = "guid";
50

  
51
	private String idAttribute = DOCID;
52
	
47 53
	// Constructor
48 54
	public XMLAccessAccess() throws AccessException {}
49 55
	
56
	public XMLAccessAccess(boolean useGuid) {
57
		if (useGuid) {
58
			idAttribute = GUID;
59
		}
60
	}
61

  
50 62
	/**
51 63
	 * Get all xml access for a document
52 64
	 * 
53
	 * @param docId
65
	 * @param id
54 66
	 *            the id of the document
55 67
	 * @return an xml access DAO list
56 68
	 */ 
57
	public Vector<XMLAccessDAO> getXMLAccessForDoc(String docId) throws AccessException {
69
	public Vector<XMLAccessDAO> getXMLAccessForDoc(String id) throws AccessException {
58 70

  
59 71
		Vector<XMLAccessDAO> xmlAccessList = new Vector<XMLAccessDAO>();
60 72
		
61
		if (docId == null) {
73
		if (id == null) {
62 74
			throw new AccessException("XMLAccessAccess.getXMLAccessForDoc - doc id " + 
63 75
					"must be specified when selecting xml_access record");
64 76
		}
......
71 83
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.getXMLAccessForDoc");
72 84
    		serialNumber = conn.getCheckOutSerialNumber();
73 85

  
74
			String sql = "SELECT * FROM xml_access WHERE docid = ?";
86
			String sql = "SELECT * FROM xml_access WHERE " + idAttribute + " = ?";
75 87
			pstmt = conn.prepareStatement(sql);
76 88

  
77
			pstmt.setString(1, docId);
89
			pstmt.setString(1, id);
78 90
			
79 91
			String sqlReport = "XMLAccessAccess.getXMLAccessForDoc - SQL: " + sql;
80
			sqlReport += " [" + docId + "]";
92
			sqlReport += " [" + id + "]";
81 93
			
82 94
			logMetacat.info(sqlReport);
83 95
			
......
96 108
			
97 109
		} catch (SQLException sqle) {
98 110
			throw new AccessException("XMLAccessAccess.getXMLAccessForDoc - SQL error when getting access " + 
99
					" for doc id: " + docId  + " : "  + sqle.getMessage());
111
					" for id: " + id  + " : "  + sqle.getMessage());
100 112
		} catch (PermOrderException poe) {
101 113
			String errorStr = "XMLAccessAccess.getXMLAccessForDoc - Permission order error when getting " + 
102
				"access record for doc id: " + docId + " : "  + poe.getMessage();
114
				"access record for doc id: " + id + " : "  + poe.getMessage();
103 115
			logMetacat.error(errorStr);
104 116
			throw new AccessException(errorStr);
105 117
		} finally {
......
110 122
	/**
111 123
	 * Get all xml access for a principal for a certain document
112 124
	 * 
113
	 * @param docId
125
	 * @param id
114 126
	 *            the id of the document
115 127
	 * @param principalName
116 128
	 *            the credentials of the principal in the database
117 129
	 * @return an xml access DAO list
118 130
	 */ 
119
	public Vector<XMLAccessDAO> getXMLAccessForPrincipal(String docId, String principalName) 
131
	public Vector<XMLAccessDAO> getXMLAccessForPrincipal(String id, String principalName) 
120 132
			throws AccessException {
121 133

  
122 134
		Vector<XMLAccessDAO> xmlAccessList = new Vector<XMLAccessDAO>();
123 135
		
124
		if (docId == null) { 
136
		if (id == null) { 
125 137
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + 
126 138
					"must be specified when selecting xml_access record");
127 139
		}
......
138 150
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.getXMLAccessForPrincipal");
139 151
    		serialNumber = conn.getCheckOutSerialNumber();
140 152
			
141
			String sql = "SELECT * FROM xml_access WHERE docid = ? AND principal_name = ?";
153
			String sql = "SELECT * FROM xml_access WHERE " + idAttribute + " = ? AND principal_name = ?";
142 154
			pstmt = conn.prepareStatement(sql);
143 155

  
144
			pstmt.setString(1, docId);
156
			pstmt.setString(1, id);
145 157
			pstmt.setString(2, principalName);
146 158
			
147 159
			String sqlReport = "XMLAccessAccess.getXMLAccessForPrincipal - SQL: " + sql;
148
			sqlReport += " [" + docId + "," + principalName + "]";
160
			sqlReport += " [" + id + "," + principalName + "]";
149 161
			
150 162
			logMetacat.info(sqlReport);
151 163
			
......
164 176
			
165 177
		} catch (SQLException sqle) {
166 178
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - SQL error when getting access " + 
167
					" for doc id: " + docId + ", principal: " + principalName  + " : "  + sqle.getMessage());
179
					" for id: " + id + ", principal: " + principalName  + " : "  + sqle.getMessage());
168 180
		} catch (PermOrderException poe) {
169 181
			String errorStr = "XMLAccessAccess.getXMLAccessForPrincipal - Permission order error when getting " + 
170
				"access record for doc id: " + docId + ", principal: " + principalName + " : "  + poe.getMessage();
182
				"access record for id: " + id + ", principal: " + principalName + " : "  + poe.getMessage();
171 183
			logMetacat.error(errorStr);
172 184
			throw new AccessException(errorStr);
173 185
		} finally {
......
178 190
	/**
179 191
	 * Get all xml access for a principal/permType/permOrder for a certain document
180 192
	 * 
181
	 * @param docId
193
	 * @param id
182 194
	 *            the id of the document
183 195
	 * @param principalName
184 196
	 *            the credentials of the principal in the database
185 197
	 * @return an xml access DAO list
186 198
	 */ 
187
	public Vector<XMLAccessDAO> getXMLAccessForPrincipal(String docId, String principalName, String permType, String permOrder) 
199
	public Vector<XMLAccessDAO> getXMLAccessForPrincipal(String id, String principalName, String permType, String permOrder) 
188 200
			throws AccessException {
189 201

  
190 202
		Vector<XMLAccessDAO> xmlAccessList = new Vector<XMLAccessDAO>();
191 203
		
192
		if (docId == null) { 
204
		if (id == null) { 
193 205
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + 
194 206
					"must be specified when selecting xml_access record");
195 207
		}
......
214 226
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.getXMLAccessForPrincipal");
215 227
    		serialNumber = conn.getCheckOutSerialNumber();
216 228
    		
217
			String sql = "SELECT * FROM xml_access WHERE docid = ? AND principal_name = ? " + 
229
			String sql = "SELECT * FROM xml_access WHERE " + idAttribute + " = ? AND principal_name = ? " + 
218 230
				"AND perm_type = ? AND perm_order = ?";
219 231
			pstmt = conn.prepareStatement(sql);
220 232

  
221
			pstmt.setString(1, docId);
233
			pstmt.setString(1, id);
222 234
			pstmt.setString(2, principalName);
223 235
			pstmt.setString(3, permType);			
224 236
			pstmt.setString(4, permOrder);
225 237
			
226 238
			String sqlReport = "XMLAccessAccess.getXMLAccessForPrincipal - SQL: " + sql;
227
			sqlReport += " [" + docId + "," + principalName + "," +  permType + "," + permOrder + "]";
239
			sqlReport += " [" + id + "," + principalName + "," +  permType + "," + permOrder + "]";
228 240
			
229 241
			logMetacat.info(sqlReport);
230 242
			
......
242 254
			
243 255
		} catch (SQLException sqle) {
244 256
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - SQL error when getting access " + 
245
					" for doc id: " + docId + ", principal: " + principalName  + " : "  + sqle.getMessage());
257
					" for id: " + id + ", principal: " + principalName  + " : "  + sqle.getMessage());
246 258
		} catch (PermOrderException poe) {
247 259
			String errorStr = "XMLAccessAccess.getXMLAccessForPrincipal - Permission order error when getting " + 
248
				"access record for doc id: " + docId + ", principal: " + principalName + " : "  + poe.getMessage();
260
				"access record for id: " + id + ", principal: " + principalName + " : "  + poe.getMessage();
249 261
			logMetacat.error(errorStr);
250 262
			throw new AccessException(errorStr);
251 263
		} finally {
......
258 270
	 * principal already exists, bitwise OR the permission to the existing
259 271
	 * permission and update.
260 272
	 * 
261
	 * @param docId
273
	 * @param id
262 274
	 *            document id
263 275
	 * @param principalName
264 276
	 *            principal credentials
......
269 281
	 * @param permOrder
270 282
	 *            permission order
271 283
	 */
272
	public void addXMLAccess(String docId, String principalName, Long permission, String permType, 
284
	public void addXMLAccess(String id, String principalName, Long permission, String permType, 
273 285
			String permOrder, String accessFileId, String subTreeId) throws AccessException, PermOrderException {
274 286
		
275
		permOrderConflict(docId, permOrder);
287
		permOrderConflict(id, permOrder);
276 288
		
277 289
		Vector<XMLAccessDAO> xmlAccessList = 
278
			getXMLAccessForPrincipal(docId, principalName, permType, permOrder);
290
			getXMLAccessForPrincipal(id, principalName, permType, permOrder);
279 291
		
280 292
		// if more than one record exists for this principal on this document with the same
281 293
		// access type / access order combination, call cleanup to combine common access and then
282 294
		// re-retrieve the access list.
283 295
		if (xmlAccessList.size() == 0) {
284
			insertXMLAccess(docId, principalName, permission, permType, permOrder, accessFileId, subTreeId);
296
			insertXMLAccess(id, principalName, permission, permType, permOrder, accessFileId, subTreeId);
285 297
			return;
286 298
		}
287 299
		
288 300
		if (xmlAccessList.size() > 1) {
289 301
			cleanupXMLAccessForPrincipal(xmlAccessList);
290
			xmlAccessList = getXMLAccessForPrincipal(docId, principalName, permType, permOrder);
302
			xmlAccessList = getXMLAccessForPrincipal(id, principalName, permType, permOrder);
291 303
		}
292 304
		
293 305
		if (xmlAccessList.size() == 0) {
294 306
			throw new AccessException("XMLAccessAccess.addXMLAccess - xml access list is empty when " + 
295
				"it shouldn't be for docid: " + docId + ", prinicpal name: " + principalName + ", perm type " + 
307
				"it shouldn't be for id: " + id + ", prinicpal name: " + principalName + ", perm type " + 
296 308
				permType + ", perm order: " + permOrder);	
297 309
		}
298 310
		
......
302 314
		//trying to add, update the access record with the existing permission bitwis OR-ed with our
303 315
		// new permission
304 316
		if ((xmlAccessDAO.getPermission() & permission) != permission) {		
305
			updateXMLAccessPermission(docId, principalName, xmlAccessDAO.getPermission() | permission);
317
			updateXMLAccessPermission(id, principalName, xmlAccessDAO.getPermission() | permission);
306 318
		}
307 319
	}
308 320
	
......
310 322
	 * Set permissions for a given document. This means first removing all access control for the
311 323
	 * document and then adding the given rules.
312 324
	 * 
313
	 * @param docId
325
	 * @param id
314 326
	 *            document id
315 327
	 * @param xmlAccessList
316 328
	 *            list of xml access dao objects that hold new access for the document
317 329
	 */
318
	public void replaceAccess(String docId, List<XMLAccessDAO> xmlAccessList) throws AccessException {
319
		deleteXMLAccessForDoc(docId);
330
	public void replaceAccess(String id, List<XMLAccessDAO> xmlAccessList) throws AccessException {
331
		deleteXMLAccessForDoc(id);
320 332
		
321 333
		// if more than one record exists for this principal on this document with the same
322 334
		// access type / access order combination, call cleanup to combine common access and then
323 335
		// re-retrieve the access list.
324 336
		for(XMLAccessDAO xmlAccessDAO : xmlAccessList) {
325
			insertXMLAccess(docId, xmlAccessDAO.getPrincipalName(), xmlAccessDAO.getPermission(), 
337
			insertXMLAccess(id, xmlAccessDAO.getPrincipalName(), xmlAccessDAO.getPermission(), 
326 338
					xmlAccessDAO.getPermType(), xmlAccessDAO.getPermOrder(), xmlAccessDAO.getAccessFileId(), xmlAccessDAO.getSubTreeId());
327 339
		}
328 340
	}
......
332 344
	 * make sure the principal does not already have an access record for this document.  If 
333 345
	 * one does already exist, that record should be updated and this insert not called.
334 346
	 * 
335
	 * @param docId
347
	 * @param id
336 348
	 *            document id
337 349
	 * @param principal
338 350
	 *            principal credentials
......
343 355
	 * @param permOrder
344 356
	 *            permission order
345 357
	 */
346
	private void insertXMLAccess(String docId, String principalName, Long permission, String permType,
358
	private void insertXMLAccess(String id, String principalName, Long permission, String permType,
347 359
			String permOrder, String accessFileId, String subTreeId) throws AccessException {
348 360
	    //System.out.println("permission in insertXMLAccess: " + permission);
349 361
	    try
......
359 371
	        logMetacat.warn(e.getMessage());
360 372
	    }
361 373
	    
362
		if (docId == null) {
363
			throw new AccessException("XMLAccessAccess.insertXMLAccess - docid is required when " + 
374
		if (id == null) {
375
			throw new AccessException("XMLAccessAccess.insertXMLAccess - id is required when " + 
364 376
					"inserting XML access record");
365 377
		}
366 378
		if (principalName == null) {
......
388 400
			serialNumber = conn.getCheckOutSerialNumber();
389 401
			
390 402
			String sql = "INSERT INTO xml_access " +
391
				"(docid, principal_name, permission, perm_type, perm_order, accessfileid, subtreeid ) " + 
403
				"(" + idAttribute + ", principal_name, permission, perm_type, perm_order, accessfileid, subtreeid ) " + 
392 404
				"VALUES (?,?,?,?,?,?,?)";
393 405
			pstmt = conn.prepareStatement(sql);
394 406

  
395 407
			// Bind the values to the query
396
			pstmt.setString(1, docId);
408
			pstmt.setString(1, id);
397 409
			pstmt.setString(2, principalName);
398 410
			pstmt.setLong(3, permission);
399 411
			pstmt.setString(4, permType);
......
402 414
			pstmt.setString(7, subTreeId);
403 415
			
404 416
			String sqlReport = "XMLAccessAccess.insertXMLAccess - SQL: " + sql;
405
			sqlReport += " [" + docId + "," + principalName + "," +  permission + "," +  permType + "," + permOrder + "]";
417
			sqlReport += " [" + id + "," + principalName + "," +  permission + "," +  permType + "," + permOrder + "]";
406 418
			
407 419
			logMetacat.info(sqlReport);
408 420

  
409 421
			pstmt.execute();
410 422
		} catch (SQLException sqle) {
411 423
			throw new AccessException("XMLAccessAccess.insertXMLAccess - SQL error when inserting"
412
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
424
					+ "xml access permissions for id: " + id + ", principal: " + 
413 425
					principalName + ":" + sqle.getMessage());
414 426
		} finally {
415 427
			closeDBObjects(pstmt, conn, serialNumber, logMetacat); 
......
420 432
	 * Update existing xml access permissions in the db.  The permission value should be the combined
421 433
	 * value of pre-existing permissions plus new permissions.
422 434
	 * 
423
	 * @param docId
435
	 * @param id
424 436
	 *            document id
425 437
	 * @param principalName
426 438
	 *            principal credentials
427 439
	 * @param permission
428 440
	 *            permission bitmap
429 441
	 */
430
	private void updateXMLAccessPermission(String docId, String principalName, Long permission)
442
	private void updateXMLAccessPermission(String id, String principalName, Long permission)
431 443
			throws AccessException {
432
		if (docId == null) {
433
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - docid is required when " + 
444
		if (id == null) {
445
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - id is required when " + 
434 446
					"updating XML access record");
435 447
		}
436 448
		if (principalName == null) {
......
451 463
			serialNumber = conn.getCheckOutSerialNumber();
452 464
			
453 465
			String sql = "UPDATE xml_access SET permission = ?" +
454
				"WHERE docid = ? AND principal_name = ?";
466
				"WHERE " + idAttribute + " = ? AND principal_name = ?";
455 467
			pstmt = conn.prepareStatement(sql);
456 468

  
457 469
			// Bind the values to the query
458 470
			pstmt.setLong(1, permission);
459
			pstmt.setString(2, docId);
471
			pstmt.setString(2, id);
460 472
			pstmt.setString(3, principalName);
461 473
			
462 474
			String sqlReport = "XMLAccessAccess.updateXMLAccessPermission - SQL: " + sql;
463
			sqlReport += " [" + permission + "," + docId + "," + principalName + "]";
475
			sqlReport += " [" + permission + "," + id + "," + principalName + "]";
464 476
			
465 477
			logMetacat.info(sqlReport);
466 478

  
467 479
			pstmt.execute();
468 480
		} catch (SQLException sqle) {
469 481
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - SQL error when updating"
470
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
482
					+ "xml access permissions for id: " + id + ", principal: " + 
471 483
					principalName + ":" + sqle.getMessage());
472 484
		} finally {
473 485
			closeDBObjects(pstmt, conn, serialNumber, logMetacat); 
......
480 492
	 * for a given document.  If the provided permission is exactly the same as what 
481 493
	 * the principal has, the record is deleted from the database.
482 494
	 * 
483
	 * @param docId
495
	 * @param id
484 496
	 *            document id
485 497
	 * @param principalName
486 498
	 *            principal credentials
487 499
	 */
488
	public void removeXMLAccessForPrincipal(String docId, String principalName, Long permission) throws AccessException {
489
		if (docId == null) {
490
			throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - docid is required when " + 
500
	public void removeXMLAccessForPrincipal(String id, String principalName, Long permission) throws AccessException {
501
		if (id == null) {
502
			throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - id is required when " + 
491 503
					"removing XML access");
492 504
		}
493 505
		if (principalName == null) {
......
499 511
					"updating XML access");
500 512
		}
501 513
		
502
		Vector<XMLAccessDAO> xmlAccessList = getXMLAccessForPrincipal(docId, principalName);
514
		Vector<XMLAccessDAO> xmlAccessList = getXMLAccessForPrincipal(id, principalName);
503 515
		if (xmlAccessList.size() == 0) {
504 516
			logMetacat.warn("XMLAccessAccess.removeXMLAccessForPrincipal - attempting to remove access when no " +
505
				"access record exists for docid: " + docId + ", principal: " + principalName);
517
				"access record exists for id: " + id + ", principal: " + principalName);
506 518
		} else {
507 519
			long permissionMask = 0;
508 520
			for (XMLAccessDAO xmlAccessDAO : xmlAccessList) {
......
513 525
			// in this case, the only existing permissions are the ones we want to remove, so 
514 526
			// delete the record(s) for this principal on this document
515 527
			if ((permissionMask & permission) == permission) {
516
				deleteXMLAccessForPrincipal(docId, principalName);
528
				deleteXMLAccessForPrincipal(id, principalName);
517 529
			}
518 530
			
519 531
			if (xmlAccessList.size() > 1) {
520 532
				
521 533
			} else {
522
				updateXMLAccessPermission(docId, principalName, permission);
534
				updateXMLAccessPermission(id, principalName, permission);
523 535
			}
524 536
		}
525 537
	   
......
528 540
	/**
529 541
	 * Delete xml access.  This removes all access records from the database for a given document
530 542
	 * 
531
	 * @param docId
543
	 * @param id
532 544
	 *            document id
533 545
	 */
534
	public void deleteXMLAccessForDoc(String docId) throws AccessException {
535
		if (docId == null) {
536
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - docid is required when " + 
546
	public void deleteXMLAccessForDoc(String id) throws AccessException {
547
		if (id == null) {
548
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - id is required when " + 
537 549
					"deleting XML access record");
538 550
		}
539 551
		
......
545 557
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForDoc");
546 558
    		serialNumber = conn.getCheckOutSerialNumber();
547 559
    		
548
			String sql = "DELETE FROM xml_access WHERE docid = ?";
560
			String sql = "DELETE FROM xml_access WHERE " + idAttribute + " = ?";
549 561
			pstmt = conn.prepareStatement(sql);
550 562

  
551 563
			// Bind the values to the query
552
			pstmt.setString(1, docId);
564
			pstmt.setString(1, id);
553 565

  
554 566
			String sqlReport = "XMLAccessAccess.deleteXMLAccessForDoc - SQL: " + sql;
555
			sqlReport += " [" + docId + "]";
567
			sqlReport += " [" + id + "]";
556 568
			
557 569
			logMetacat.info(sqlReport);
558 570

  
559 571
			pstmt.execute();
560 572
		} catch (SQLException sqle) {
561 573
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForDoc - SQL error when deleting"
562
					+ "xml access permissions for doc id: " + docId + ":" + sqle.getMessage());
574
					+ "xml access permissions for id: " + id + ":" + sqle.getMessage());
563 575
		} finally {
564 576
			closeDBObjects(pstmt, conn, serialNumber, logMetacat); 
565 577
		}	   
......
569 581
	 * Delete xml access.  This removes all access records from the database for a principal 
570 582
	 * for a given document
571 583
	 * 
572
	 * @param docId
584
	 * @param id
573 585
	 *            document id
574 586
	 * @param principal
575 587
	 *            principal credentials
576 588
	 */
577
	private void deleteXMLAccessForPrincipal(String docId, String principalName) throws AccessException {
578
		if (docId == null) {
579
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - docid is required when " + 
589
	private void deleteXMLAccessForPrincipal(String id, String principalName) throws AccessException {
590
		if (id == null) {
591
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - id is required when " + 
580 592
					"deleting XML access record");
581 593
		}
582 594
		if (principalName == null) {
......
592 604
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForPrincipal");
593 605
    		serialNumber = conn.getCheckOutSerialNumber();
594 606
    		
595
			String sql = "DELETE FROM xml_access WHERE docid = ? AND principal_name = ?";
607
			String sql = "DELETE FROM xml_access WHERE " + idAttribute + " = ? AND principal_name = ?";
596 608
			pstmt = conn.prepareStatement(sql);
597 609

  
598 610
			// Bind the values to the query
599
			pstmt.setString(1, docId);
611
			pstmt.setString(1, id);
600 612
			pstmt.setString(2, principalName);
601 613

  
602 614
			String sqlReport = "XMLAccessAccess.deleteXMLAccessForPrincipal - SQL: " + sql;
603
			sqlReport += " [" + docId + "," + principalName + "]";
615
			sqlReport += " [" + id + "," + principalName + "]";
604 616
			
605 617
			logMetacat.info(sqlReport);
606 618

  
607 619
			pstmt.execute();
608 620
		} catch (SQLException sqle) {
609 621
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when deleting"
610
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
622
					+ "xml access permissions for id: " + id + ", principal: " + 
611 623
					principalName + ":" + sqle.getMessage());
612 624
		} finally {
613 625
			closeDBObjects(pstmt, conn, serialNumber, logMetacat);
......
618 630
	 * Checks to see if there is a permission order conflict for a given document.  Each 
619 631
	 * document is only allowed to have a single permission order
620 632
	 * 
621
	 * @param docId
633
	 * @param id
622 634
	 *            document id
623 635
	 * @param principal
624 636
	 *            principal credentials
625 637
	 */
626
	private void permOrderConflict(String docId, String permOrder) throws AccessException, PermOrderException {
627
		if (docId == null) {
628
			throw new AccessException("XMLAccessAccess.permOrderConflict - docid is required when " + 
638
	private void permOrderConflict(String id, String permOrder) throws AccessException, PermOrderException {
639
		if (id == null) {
640
			throw new AccessException("XMLAccessAccess.permOrderConflict - id is required when " + 
629 641
					"determining perm order conflict");
630 642
		}
631 643
		if (permOrder == null) {
......
641 653
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.permOrderConflict");
642 654
    		serialNumber = conn.getCheckOutSerialNumber();
643 655
    		
644
			String sql = "SELECT * FROM xml_access WHERE docid = ? AND perm_order != ?";
656
			String sql = "SELECT * FROM xml_access WHERE " + idAttribute + " = ? AND perm_order != ?";
645 657
			pstmt = conn.prepareStatement(sql);
646 658

  
647 659
			// Bind the values to the query
648
			pstmt.setString(1, docId);
660
			pstmt.setString(1, id);
649 661
			pstmt.setString(2, permOrder);
650 662
			
651 663
			String sqlReport = "XMLAccessAccess.permOrderConflict - SQL: " + sql;
652
			sqlReport += " [" + docId + "," + permOrder + "]";
664
			sqlReport += " [" + id + "," + permOrder + "]";
653 665
			
654 666
			logMetacat.info(sqlReport);
655 667

  
......
658 670
			ResultSet resultSet = pstmt.getResultSet();
659 671
			if (resultSet.next()) {			
660 672
				throw new PermOrderException("XMLAccessAccess.addXMLAccess - cannot add permission " + 
661
					"record for doc id: " + docId + "with permOrder: " + permOrder + " due to permOrder conflict");
673
					"record for id: " + id + "with permOrder: " + permOrder + " due to permOrder conflict");
662 674
			}
663 675
		} catch (SQLException sqle) {
664 676
			throw new AccessException("XMLAccessAccess.permOrderConflict - SQL error when checking"
665
					+ "for perm order conflict on: " + docId + ":" + sqle.getMessage());
677
					+ "for perm order conflict on: " + id + ":" + sqle.getMessage());
666 678
		} finally {
667 679
			closeDBObjects(pstmt, conn, serialNumber, logMetacat); 
668 680
		}
......
673 685
	 * Delete xml access.  This removes all access records from the database for a principal 
674 686
	 * for a given document, perm type and perm order
675 687
	 * 
676
	 * @param docId
688
	 * @param id
677 689
	 *            document id
678 690
	 * @param principal
679 691
	 *            principal credentials
680 692
	 */
681
	private void deleteXMLAccessForPrincipal(String docId, String principalName, String permType, String permOrder) throws AccessException {
682
		if (docId == null) {
683
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - docid is required when " + 
693
	private void deleteXMLAccessForPrincipal(String id, String principalName, String permType, String permOrder) throws AccessException {
694
		if (id == null) {
695
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - id is required when " + 
684 696
					"deleting XML access record");
685 697
		}
686 698
		if (principalName == null) {
......
706 718
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForPrincipal");
707 719
    		serialNumber = conn.getCheckOutSerialNumber();
708 720
    		
709
			String sql = "DELETE FROM xml_access WHERE docid = ? AND principal_name = ? " +
721
			String sql = "DELETE FROM xml_access WHERE " + idAttribute + " = ? AND principal_name = ? " +
710 722
				"AND perm_type = ? AND perm_order = ?";
711 723
			pstmt = conn.prepareStatement(sql);
712 724

  
713 725
			// Bind the values to the query
714
			pstmt.setString(1, docId);
726
			pstmt.setString(1, id);
715 727
			pstmt.setString(2, principalName);
716 728
			pstmt.setString(3, permType);
717 729
			pstmt.setString(4, permOrder);
718 730
			
719 731
			String sqlReport = "XMLAccessAccess.deleteXMLAccessForPrincipal - SQL: " + sql;
720
			sqlReport += " [" + docId + "," + principalName + "," + permType + "," + permOrder + "]";
732
			sqlReport += " [" + id + "," + principalName + "," + permType + "," + permOrder + "]";
721 733
			
722 734
			logMetacat.info(sqlReport);
723 735

  
724 736
			pstmt.execute();
725 737
		} catch (SQLException sqle) {
726 738
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when deleting"
727
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
739
					+ "xml access permissions for id: " + id + ", principal: " + 
728 740
					principalName + ":" + sqle.getMessage());
729 741
		} finally {
730 742
			closeDBObjects(pstmt, conn, serialNumber, logMetacat); 
......
745 757
		int numDenyRecords = 0;
746 758
		long allowPermissionMask = 0;
747 759
		long denyPermissionMask = 0;
748
		String docId = null;
760
		String id = null;
749 761
		String principalName = null;
750 762
		String permType = null;
751 763
		String permOrder = null;
......
757 769
		// iterate through the list of access dao objects and bttwise or the permissions.  Most
758 770
		// of this is just doing some error checking to make sure each record is valid.
759 771
		for (XMLAccessDAO xmlAccessDAO : xmlAccessList) {
760
			if (docId == null) {
761
				docId = xmlAccessDAO.getDocId();
772
			String daoId = xmlAccessDAO.getDocId();
773
			if (idAttribute.equals(GUID)) {
774
				daoId = xmlAccessDAO.getGuid();
775
			}
776
			if (id == null) {
777
				id = daoId;
762 778
			} else {
763
				if (!docId.equals(xmlAccessDAO.getDocId())) {
779
				if (!id.equals(daoId)) {
764 780
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
765
							" Conflicting doc ids " + xmlAccessDAO.getDocId() +
766
							" and " + docId);
781
							" Conflicting ids " + daoId + " and " + id);
767 782
				}
768 783
			}
769 784
			if (principalName == null) {
......
780 795
			} else {
781 796
				if (!permType.equals(xmlAccessDAO.getPermType())) {
782 797
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
783
							" Conflicting permission orders for document " + xmlAccessDAO.getDocId() +
798
							" Conflicting permission orders for document " + daoId +
784 799
							"principalName " + principalName + ". Database intervention required ");
785 800
				}
786 801
			}
......
789 804
			} else {
790 805
				if (!permOrder.equals(xmlAccessDAO.getPermOrder())) {
791 806
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
792
							" Conflicting permission types for document " + xmlAccessDAO.getDocId() +
807
							" Conflicting permission types for document " + daoId +
793 808
							"principalName " + principalName + ". Database intervention required ");
794 809
				}
795 810
			}
......
798 813
			} else {
799 814
				if (!permType.equals(xmlAccessDAO.getPermType())) {
800 815
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
801
							" Conflicting permission orders for document " + xmlAccessDAO.getDocId() +
816
							" Conflicting permission orders for document " + daoId +
802 817
							"principalName " + principalName + ". Database intervention required ");
803 818
				}
804 819
			}
......
820 835
		// if there was more than one allow record, remove all allow records for this user on this doc 
821 836
		// with this perm type and perm order then insert a single record 
822 837
		if (numAllowRecords > 1) {
823
			deleteXMLAccessForPrincipal(docId, principalName, AccessControlInterface.ALLOW, permOrder);
824
			insertXMLAccess(docId, principalName, allowPermissionMask, AccessControlInterface.ALLOW, permOrder, accessFileId, subTreeId);
838
			deleteXMLAccessForPrincipal(id, principalName, AccessControlInterface.ALLOW, permOrder);
839
			insertXMLAccess(id, principalName, allowPermissionMask, AccessControlInterface.ALLOW, permOrder, accessFileId, subTreeId);
825 840
		}
826 841
		// if there was more than one deny record, remove all deny records for this user on this doc 
827 842
		// with this perm type and perm order then insert a single record 
828 843
		if (numDenyRecords > 1) {
829
			deleteXMLAccessForPrincipal(docId, principalName, AccessControlInterface.DENY, permOrder);
830
			insertXMLAccess(docId, principalName, denyPermissionMask, AccessControlInterface.DENY, permOrder, accessFileId, subTreeId);
844
			deleteXMLAccessForPrincipal(id, principalName, AccessControlInterface.DENY, permOrder);
845
			insertXMLAccess(id, principalName, denyPermissionMask, AccessControlInterface.DENY, permOrder, accessFileId, subTreeId);
831 846
		}
832 847
	}
833 848
	
......
841 856
	private void validateDocXMLAccessList(Vector<XMLAccessDAO> xmlAccessList) throws PermOrderException {
842 857
		String permOrder = null;
843 858
		for(XMLAccessDAO xmlAccessDAO : xmlAccessList) {
859
			String daoId = xmlAccessDAO.getDocId();
860
			if (idAttribute.equals(GUID)) {
861
				daoId = xmlAccessDAO.getGuid();
862
			}
844 863
			if (permOrder == null) {
845 864
				permOrder = xmlAccessDAO.getPermOrder();
846 865
			} else {
847 866
				if(!permOrder.equals(xmlAccessDAO.getPermOrder())) {
848 867
					throw new PermOrderException("XMLAccessAccess.validateXMLAccessList - " + 
849
						" Conflicting permission orders for document " + xmlAccessDAO.getDocId() +
868
						" Conflicting permission orders for document " + daoId +
850 869
						". Database intervention required ");
851 870
				}
852 871
			}
......
865 884
		
866 885
		boolean allowFirst = false;
867 886
		boolean denyFirst = false;
868
		String docId = null;
887
		String id = null;
869 888
		
870 889
		// These vectors will hold all combinations of access DAOs with different permission
871 890
		// orders and permission types.  
......
876 895
		
877 896
		// sort the access dao records into the appropriate vector
878 897
		for(XMLAccessDAO xmlAccessDAO : xmlAccessList) {
879
			if (docId == null) {
880
				docId = xmlAccessDAO.getDocId();
898
			String daoId = xmlAccessDAO.getDocId();
899
			if (idAttribute.equals(GUID)) {
900
				daoId = xmlAccessDAO.getGuid();
881 901
			}
902
			if (id == null) {
903
				id = daoId;
904
			}
882 905
			if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.ALLOWFIRST)) {
883 906
				allowFirst = true;
884 907
				if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
......
888 911
				} else {
889 912
					throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
890 913
							" Invalid permission type: " + xmlAccessDAO.getPermType() + " for document " + 
891
							xmlAccessDAO.getDocId() + ". Database intervention required "); 
914
							daoId + ". Database intervention required "); 
892 915
				}
893 916
			} else if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.DENYFIRST)) {
894 917
				denyFirst = true;
......
899 922
				} else {
900 923
					throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
901 924
							" Invalid permission type: " + xmlAccessDAO.getPermType() + " for document " + 
902
							xmlAccessDAO.getDocId() + ". Database intervention required "); 
925
							daoId + ". Database intervention required "); 
903 926
				}
904 927
			} else {
905 928
				throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
906 929
						" Invalid permission order: " + xmlAccessDAO.getPermOrder() + " for document " + 
907
						xmlAccessDAO.getDocId() + ". Database intervention required "); 
930
						daoId + ". Database intervention required "); 
908 931
			}
909 932
		}
910 933
		
......
912 935
		// document
913 936
		if(allowFirst && denyFirst) {
914 937
			throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
915
					" Conflicting permission orders for document " + docId +
938
					" Conflicting permission orders for document " + id +
916 939
					". Database intervention required ");
917 940
		}	
918 941
	}
......
927 950
	protected XMLAccessDAO populateDAO(ResultSet resultSet) throws SQLException {
928 951

  
929 952
		XMLAccessDAO xmlAccessDAO = new XMLAccessDAO();
930
		xmlAccessDAO.setDocId(resultSet.getString("docid"));
953
		xmlAccessDAO.setDocId(resultSet.getString(idAttribute));
931 954
		xmlAccessDAO.setAccessFileId(resultSet.getString("accessfileid"));
932 955
		xmlAccessDAO.setPrincipalName(resultSet.getString("principal_name"));
933 956
		xmlAccessDAO.setPermission(resultSet.getLong("permission"));
src/edu/ucsb/nceas/metacat/accesscontrol/XMLAccessDAO.java
40 40
public class XMLAccessDAO extends BaseDAO {
41 41

  
42 42
	private String _docId = null;
43
	private String _guid = null;
43 44
	private String _accessFileId = null;
44 45
	private String _principalName = null;
45 46
	private Long _permission = null;
......
63 64
			_docId = docId;
64 65
		}
65 66
	}
67
	
68
	public String getGuid() {
69
		return _guid;
70
	}
71
	
72
	public void setGuid(String guid) {
73
		if (guid != null && guid.equals("")) {
74
			guid = null;
75
		} else {
76
			_guid = guid;
77
		}
78
	}
66 79

  
67 80
	public String getAccessFileId() {
68 81
		return _accessFileId;
src/edu/ucsb/nceas/metacat/IdentifierManager.java
1242 1242
     */
1243 1243
    private void insertAccessPolicy(String guid, AccessPolicy accessPolicy) throws McdbDocNotFoundException, AccessException {
1244 1244
    	
1245
    	String docid = getLocalId(guid);
1246 1245
    	List<XMLAccessDAO> accessDAOs = new ArrayList<XMLAccessDAO>();
1247 1246
        for (AccessRule accessRule: accessPolicy.getAllowList()) {
1248 1247
        	List<Subject> subjects = accessRule.getSubjectList();
1249 1248
        	List<Identifier> resources = accessRule.getResourceList();
1250 1249
        	List<Permission> permissions = accessRule.getPermissionList();
1251 1250
        	for (Subject subject: subjects) {
1252
        		for (Identifier resource: resources) {
1253
        			docid = getLocalId(resource.getValue());
1254
        			XMLAccessDAO accessDAO = new XMLAccessDAO();
1255
            		accessDAO.setPrincipalName(subject.getValue());
1256
        			accessDAO.setDocId(docid);
1257
        			accessDAO.setPermType(AccessControlInterface.ALLOW);
1258
        			accessDAO.setPermOrder(AccessControlInterface.DENYFIRST);
1259
        			for (Permission permission: permissions) {
1260
        				Long metacatPermission = new Long(convertPermission(permission));
1261
	        			accessDAO.addPermission(metacatPermission);
1262
        			}
1263
        			accessDAOs.add(accessDAO);
1264
        		}
1251
    			XMLAccessDAO accessDAO = new XMLAccessDAO();
1252
        		accessDAO.setPrincipalName(subject.getValue());
1253
    			accessDAO.setGuid(guid);
1254
    			accessDAO.setPermType(AccessControlInterface.ALLOW);
1255
    			accessDAO.setPermOrder(AccessControlInterface.DENYFIRST);
1256
    			for (Permission permission: permissions) {
1257
    				Long metacatPermission = new Long(convertPermission(permission));
1258
        			accessDAO.addPermission(metacatPermission);
1259
    			}
1260
    			accessDAOs.add(accessDAO);
1265 1261
        	}
1266 1262
        }
1267 1263
        
1268
        XMLAccessAccess accessController  = new XMLAccessAccess();
1269
        accessController.replaceAccess(docid, accessDAOs);
1264
        // use GUID to update
1265
        XMLAccessAccess accessController  = new XMLAccessAccess(true);
1266
        accessController.replaceAccess(guid, accessDAOs);
1270 1267
        
1271 1268
        
1272 1269
    }
......
1279 1276
     * @throws AccessException
1280 1277
     */
1281 1278
    private AccessPolicy getAccessPolicy(String guid) throws McdbDocNotFoundException, AccessException {
1282
    	String docid = getLocalId(guid);
1283
        XMLAccessAccess accessController  = new XMLAccessAccess();
1284
    	List<XMLAccessDAO> accessDAOs = accessController.getXMLAccessForDoc(docid);
1285
    	AccessRule accessRule = new AccessRule();
1286
    	Identifier resource = new Identifier();
1287
    	resource.setValue(guid);
1288
    	accessRule.addResource(resource);
1279
    	// use GUID to look up the access
1280
        XMLAccessAccess accessController  = new XMLAccessAccess(true);
1281
    	List<XMLAccessDAO> accessDAOs = accessController.getXMLAccessForDoc(guid);
1282
    	AccessRule accessRule = new AccessRule();    	
1289 1283
        for (XMLAccessDAO accessDAO: accessDAOs) {
1290 1284
        	Permission permission = convertPermission(accessDAO.getPermission().intValue());
1291 1285
        	accessRule.addPermission(permission);

Also available in: Unified diff