Project

General

Profile

« Previous | Next » 

Revision 5091

Added by daigle about 15 years ago

Create access dao and centralized db access classes. Update create access code to combine access records for principal/doc/accesstype when multiple exist.

View differences:

src/edu/ucsb/nceas/workflowscheduler/WorkflowScheduler.java
45 45
import org.ecoinformatics.ecogrid.client.AuthenticationServiceClient;
46 46
import org.ecoinformatics.ecogrid.client.AuthorizationServiceClient;
47 47

  
48
import edu.ucsb.nceas.metacat.AccessControlInterface;
49 48
import edu.ucsb.nceas.metacat.scheduler.BaseScheduler;
50 49
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobAccess;
51 50
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobDAO;
52 51
import edu.ucsb.nceas.metacat.scheduler.SchedulerService;
53 52
import edu.ucsb.nceas.metacat.scheduler.MetacatSchedulerException;
53
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlInterface;
54 54
import edu.ucsb.nceas.metacat.properties.PropertyService;
55 55
import edu.ucsb.nceas.metacat.shared.AccessException;
56 56
import edu.ucsb.nceas.metacat.shared.ServiceException;
src/edu/ucsb/nceas/metacat/accesscontrol/AccessControlException.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: An Exception thrown when an error occurs because an 
4
 *             AccessionNumber was invalid or used incorrectly
5
 *  Copyright: 2008 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Michael Daigle
8
 *
9
 *   '$Author: daigle $'
10
 *     '$Date: 2008-07-06 21:25:34 -0700 (Sun, 06 Jul 2008) $'
11
 * '$Revision: 4080 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

  
28
package edu.ucsb.nceas.metacat.accesscontrol;
29

  
30
import edu.ucsb.nceas.metacat.shared.BaseException;
31

  
32

  
33
/**
34
 * Exception thrown when an error occurs in a configuration administrative
35
 * class
36
 */
37
public class AccessControlException extends BaseException {
38
	
39
	private static final long serialVersionUID = -8436697355629175917L;
40

  
41
	/**
42
	 * Create a new AccessControlException.
43
	 *
44
	 * @param message The error or warning message.
45
	 */
46
	public AccessControlException(String message) {
47
		super(message);
48
	}
49
	
50
	public AccessControlException(String message, BaseException deeperException) {
51
		super(message, deeperException);
52
	}
53
}
0 54

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

  
28
package edu.ucsb.nceas.metacat.accesscontrol;
29

  
30
import java.sql.PreparedStatement;
31
import java.sql.ResultSet;
32
import java.sql.SQLException;
33
import java.util.Vector;
34

  
35
import org.apache.log4j.Logger;
36

  
37
import edu.ucsb.nceas.metacat.database.DBConnection;
38
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
39
import edu.ucsb.nceas.metacat.shared.AccessException;
40
import edu.ucsb.nceas.metacat.shared.BaseAccess;
41

  
42
public class XMLAccessAccess extends BaseAccess {
43
	
44
	private Logger logMetacat = Logger.getLogger(XMLAccessAccess.class);
45
	
46
	// Constructor
47
	public XMLAccessAccess() throws AccessException {
48
		super("XMLAccessAccess");
49
	}
50
	
51
	/**
52
	 * Get all xml access for a document
53
	 * 
54
	 * @param docId
55
	 *            the id of the document
56
	 * @return an xml access DAO list
57
	 */ 
58
	public Vector<XMLAccessDAO> getXMLAccessForDoc(String docId) throws AccessException {
59

  
60
		Vector<XMLAccessDAO> xmlAccessList = new Vector<XMLAccessDAO>();
61
		
62
		if (docId == null) {
63
			throw new AccessException("XMLAccessAccess.getXMLAccessForDoc - doc id " + 
64
					"must be specified when selecting xml_access record");
65
		}
66
			
67
		// first get the job from the db and put it into a DAO
68
		PreparedStatement pstmt = null;
69
		try {
70
			String sql = "SELECT * FROM xml_access WHERE docid = ?";
71
			pstmt = conn.prepareStatement(sql);
72

  
73
			pstmt.setString(1, docId);
74
			
75
			String sqlReport = "XMLAccessAccess.getXMLAccessForDoc - SQL: " + sql;
76
			sqlReport += " [" + docId + "]";
77
			
78
			logMetacat.info(sqlReport);
79
			
80
			pstmt.execute();
81
			
82
			ResultSet resultSet = pstmt.getResultSet();
83
			while (resultSet.next()) {
84
				XMLAccessDAO xmlAccessDAO = populateDAO(resultSet);
85
				xmlAccessList.add(xmlAccessDAO);
86
			}
87
						
88
			validateDocXMLAccessList(xmlAccessList);
89
			
90
			return xmlAccessList;
91
			
92
		} catch (SQLException sqle) {
93
			throw new AccessException("XMLAccessAccess.getXMLAccessForDoc - SQL error when getting access " + 
94
					" for doc id: " + docId  + " : "  + sqle.getMessage());
95
		} catch (PermOrderException poe) {
96
			String errorStr = "XMLAccessAccess.getXMLAccessForDoc - Permission order error when getting " + 
97
				"access record for doc id: " + docId + " : "  + poe.getMessage();
98
			logMetacat.error(errorStr);
99
			throw new AccessException(errorStr);
100
		} finally {
101
			try {
102
				if (pstmt != null) {
103
					pstmt.close();
104
				}
105
			} catch (SQLException sqle) {
106
				logMetacat.error("XMLAccessAccess.getXMLAccessForDoc - An error occurred " 
107
						+ "closing prepared statement: " + sqle.getMessage());
108
			} 
109
		}		
110
	}
111
	
112
	/**
113
	 * Get all xml access for a principal for a certain document
114
	 * 
115
	 * @param docId
116
	 *            the id of the document
117
	 * @param principalName
118
	 *            the credentials of the principal in the database
119
	 * @return an xml access DAO list
120
	 */ 
121
	public Vector<XMLAccessDAO> getXMLAccessForPrincipal(String docId, String principalName) 
122
			throws AccessException {
123

  
124
		Vector<XMLAccessDAO> xmlAccessList = new Vector<XMLAccessDAO>();
125
		
126
		if (docId == null) { 
127
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + 
128
					"must be specified when selecting xml_access record");
129
		}
130
		if (principalName == null) { 
131
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + 
132
					"must be specified when selecting xml_access record");
133
		}
134
			
135
		// first get the job from the db and put it into a DAO
136
		PreparedStatement pstmt = null;
137
		try {
138
			String sql = "SELECT * FROM xml_access WHERE docid = ? AND principal_name = ?";
139
			pstmt = conn.prepareStatement(sql);
140

  
141
			pstmt.setString(1, docId);
142
			pstmt.setString(2, principalName);
143
			
144
			String sqlReport = "XMLAccessAccess.getXMLAccessForPrincipal - SQL: " + sql;
145
			sqlReport += " [" + docId + "," + principalName + "]";
146
			
147
			logMetacat.info(sqlReport);
148
			
149
			pstmt.execute();
150
			
151
			ResultSet resultSet = pstmt.getResultSet();
152
			while (resultSet.next()) {
153
				XMLAccessDAO xmlAccessDAO = populateDAO(resultSet);
154
				xmlAccessList.add(xmlAccessDAO);
155
			}
156
			
157
			validatePrincipalXMLAccessList(xmlAccessList);
158
			
159
			return xmlAccessList;
160
			
161
		} catch (SQLException sqle) {
162
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - SQL error when getting access " + 
163
					" for doc id: " + docId + ", principal: " + principalName  + " : "  + sqle.getMessage());
164
		} catch (PermOrderException poe) {
165
			String errorStr = "XMLAccessAccess.getXMLAccessForPrincipal - Permission order error when getting " + 
166
				"access record for doc id: " + docId + ", principal: " + principalName + " : "  + poe.getMessage();
167
			logMetacat.error(errorStr);
168
			throw new AccessException(errorStr);
169
		} finally {
170
			try {
171
				if (pstmt != null) {
172
					pstmt.close();
173
				}
174
			} catch (SQLException sqle) {
175
				logMetacat.error("XMLAccessAccess.getXMLAccessForPrincipal - An error occurred " 
176
						+ "closing prepared statement: " + sqle.getMessage());
177
			} 
178
		}		
179
	}
180
	
181
	/**
182
	 * Get all xml access for a principal for a certain document
183
	 * 
184
	 * @param docId
185
	 *            the id of the document
186
	 * @param principalName
187
	 *            the credentials of the principal in the database
188
	 * @return an xml access DAO list
189
	 */ 
190
	public Vector<XMLAccessDAO> getXMLAccessForPrincipal(String docId, String principalName, String permType, String permOrder) 
191
			throws AccessException {
192

  
193
		Vector<XMLAccessDAO> xmlAccessList = new Vector<XMLAccessDAO>();
194
		
195
		if (docId == null) { 
196
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + 
197
					"must be specified when selecting xml_access record");
198
		}
199
		if (principalName == null) { 
200
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - doc id " + 
201
					"must be specified when selecting xml_access record");
202
		}
203
		if (permType == null) { 
204
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - permission type " + 
205
					"must be specified when selecting xml_access record");
206
		}
207
		if (permOrder == null) { 
208
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - permission order " + 
209
					"must be specified when selecting xml_access record");
210
		}
211
					
212
		// first get the job from the db and put it into a DAO
213
		PreparedStatement pstmt = null;
214
		try {
215
			String sql = "SELECT * FROM xml_access WHERE docid = ? AND principal_name = ? " + 
216
				"AND perm_type = ? AND perm_order = ?";
217
			pstmt = conn.prepareStatement(sql);
218

  
219
			pstmt.setString(1, docId);
220
			pstmt.setString(2, principalName);
221
			pstmt.setString(3, permType);			
222
			pstmt.setString(4, permOrder);
223
			
224
			String sqlReport = "XMLAccessAccess.getXMLAccessForPrincipal - SQL: " + sql;
225
			sqlReport += " [" + docId + "," + principalName + "," +  permType + "," + permOrder + "]";
226
			
227
			logMetacat.info(sqlReport);
228
			
229
			pstmt.execute();
230
			
231
			ResultSet resultSet = pstmt.getResultSet();
232
			while (resultSet.next()) {
233
				XMLAccessDAO xmlAccessDAO = populateDAO(resultSet);
234
				xmlAccessList.add(xmlAccessDAO);
235
			}
236
			
237
			validatePrincipalXMLAccessList(xmlAccessList);
238
			
239
			return xmlAccessList;
240
			
241
		} catch (SQLException sqle) {
242
			throw new AccessException("XMLAccessAccess.getXMLAccessForPrincipal - SQL error when getting access " + 
243
					" for doc id: " + docId + ", principal: " + principalName  + " : "  + sqle.getMessage());
244
		} catch (PermOrderException poe) {
245
			String errorStr = "XMLAccessAccess.getXMLAccessForPrincipal - Permission order error when getting " + 
246
				"access record for doc id: " + docId + ", principal: " + principalName + " : "  + poe.getMessage();
247
			logMetacat.error(errorStr);
248
			throw new AccessException(errorStr);
249
		} finally {
250
			try {
251
				if (pstmt != null) {
252
					pstmt.close();
253
				}
254
			} catch (SQLException sqle) {
255
				logMetacat.error("XMLAccessAccess.getXMLAccessForPrincipal - An error occurred " 
256
						+ "closing prepared statement: " + sqle.getMessage());
257
			} 
258
		}		
259
	}
260
	
261
	/**
262
	 * Add permissions for a given prinicpal on a given document. If the
263
	 * prinicpal already exists, bitwise OR the permission to the existing
264
	 * permission and update.
265
	 * 
266
	 * @param docId
267
	 *            document id
268
	 * @param principalName
269
	 *            principal credentials
270
	 * @param permission
271
	 *            permission bitmap
272
	 * @param permType
273
	 *            permission type
274
	 * @param permOrder
275
	 *            permission order
276
	 */
277
	public void addXMLAccess(String docId, String principalName, Long permission, String permType, 
278
			String permOrder) throws AccessException {
279
		Vector<XMLAccessDAO> xmlAccessList = 
280
			getXMLAccessForPrincipal(docId, principalName, permType, permOrder);
281
		
282
		// if more than one record exists for this principal on this document with the same
283
		// access type / access order combination, call cleanup to combine common access and then
284
		// re-retrieve the access list.
285
		if (xmlAccessList.size() == 0) {
286
			insertXMLAccess(docId, principalName, permission, permType, permOrder);
287
			return;
288
		}
289
		
290
		if (xmlAccessList.size() > 1) {
291
			cleanupXMLAccessForPrincipal(xmlAccessList);
292
			xmlAccessList = getXMLAccessForPrincipal(docId, principalName, permType, permOrder);
293
		}
294
		
295
		if (xmlAccessList.size() == 0) {
296
			throw new AccessException("XMLAccessAccess.addXMLAccess - xml access list is empty when " + 
297
				"it shouldn't be for docid: " + docId + ", prinicpal name: " + principalName + ", perm type " + 
298
				permType + ", perm order: " + permOrder);	
299
		}
300
		
301
		XMLAccessDAO xmlAccessDAO = xmlAccessList.get(0);
302
		
303
		
304
		// if the permission on the xml access dao does not already contain the permission we are 
305
		//trying to add, update the access record with the existing permission bitwis OR-ed with our
306
		// new permission
307
		if ((xmlAccessDAO.getPermission() & permission) != permission) {		
308
			updateXMLAccessPermission(docId, principalName, xmlAccessDAO.getPermission() | permission);
309
		}
310
	}
311
	
312
	/**
313
	 * Insert an xml access record
314
	 * @param docId
315
	 *            document id
316
	 * @param principal
317
	 *            principal credentials
318
	 * @param permission
319
	 *            permission bitmap
320
	 * @param permType
321
	 *            permission type
322
	 * @param permOrder
323
	 *            permission order
324
	 */
325
	private void insertXMLAccess(String docId, String principalName, Long permission, String permType,
326
			String permOrder) throws AccessException {
327
		if (docId == null) {
328
			throw new AccessException("XMLAccessAccess.insertXMLAccess - docid is required when " + 
329
					"inserting XML access record");
330
		}
331
		if (principalName == null) {
332
			throw new AccessException("XMLAccessAccess.insertXMLAccess - principal is required when " + 
333
					"inserting XML access record");
334
		}
335
		if (permission == null) {
336
			throw new AccessException("XMLAccessAccess.insertXMLAccess - permission is required when " + 
337
					"inserting XML access record");
338
		}
339
		if (permType == null) {
340
			throw new AccessException("XMLAccessAccess.insertXMLAccess - permType is required when " + 
341
					"inserting XML access record");
342
		}
343
		if (permOrder == null) {
344
			permOrder = AccessControlInterface.ALLOWFIRST;
345
		}
346
		
347
	    PreparedStatement pstmt = null;
348
		DBConnection conn = null;
349
		int serialNumber = -1;
350
		try {
351
			// check out DBConnection
352
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.insertXMLAccess");
353
			serialNumber = conn.getCheckOutSerialNumber();
354
			String sql = "INSERT INTO xml_access " +
355
				"(docid, principal_name, permission, perm_type, perm_order ) " + 
356
				"VALUES (?,?,?,?,?)";
357
			pstmt = conn.prepareStatement(sql);
358

  
359
			// Bind the values to the query
360
			pstmt.setString(1, docId);
361
			pstmt.setString(2, principalName);
362
			pstmt.setLong(3, permission);
363
			pstmt.setString(4, permType);
364
			pstmt.setString(5, permOrder);
365
			
366
			String sqlReport = "XMLAccessAccess.insertXMLAccess - SQL: " + sql;
367
			sqlReport += " [" + docId + "," + principalName + "," +  permission + "," +  permType + "," + permOrder + "]";
368
			
369
			logMetacat.info(sqlReport);
370

  
371
			pstmt.execute();
372
		} catch (SQLException sqle) {
373
			throw new AccessException("XMLAccessAccess.insertXMLAccess - SQL error when inserting"
374
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
375
					principalName + ":" + sqle.getMessage());
376
		} finally {
377
			try {
378
				if (pstmt != null) {
379
					pstmt.close();
380
				}
381
			} catch (SQLException sqle) {
382
				logMetacat.error("XMLAccessAccess.insertXMLAccess - SQL error when closing prepared " + 
383
						"statement after inserting xml access permissions for doc id: " + docId + 
384
						", principal: " +  principalName + ":" + sqle.getMessage());
385
			} finally {
386
				DBConnectionPool.returnDBConnection(conn, serialNumber);
387
			}
388
		}   
389
	}
390
	
391
	/**
392
	 * Update existing xml access permissions in the db
393
	 * @param docId
394
	 *            document id
395
	 * @param principalName
396
	 *            principal credentials
397
	 * @param permission
398
	 *            permission bitmap
399
	 */
400
	private void updateXMLAccessPermission(String docId, String principalName, Long permission)
401
			throws AccessException {
402
		if (docId == null) {
403
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - docid is required when " + 
404
					"updating XML access record");
405
		}
406
		if (principalName == null) {
407
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - principal is required when " + 
408
					"updating XML access record");
409
		}
410
		if (permission == null) {
411
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - permission is required when " + 
412
					"updating XML access record");
413
		}
414
		
415
	    PreparedStatement pstmt = null;
416
		DBConnection conn = null;
417
		int serialNumber = -1;
418
		try {
419
			// check out DBConnection
420
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.updateXMLAccessPermission");
421
			serialNumber = conn.getCheckOutSerialNumber();
422
			String sql = "UPDATE xml_access SET permission = ?" +
423
				"WHERE docid = ? AND principal_name = ?";
424
			pstmt = conn.prepareStatement(sql);
425

  
426
			// Bind the values to the query
427
			pstmt.setLong(1, permission);
428
			pstmt.setString(2, docId);
429
			pstmt.setString(3, principalName);
430
			
431
			String sqlReport = "XMLAccessAccess.updateXMLAccessPermission - SQL: " + sql;
432
			sqlReport += " [" + permission + "," + docId + "," + principalName + "]";
433
			
434
			logMetacat.info(sqlReport);
435

  
436
			pstmt.execute();
437
		} catch (SQLException sqle) {
438
			throw new AccessException("XMLAccessAccess.updateXMLAccessPermission - SQL error when updating"
439
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
440
					principalName + ":" + sqle.getMessage());
441
		} finally {
442
			try {
443
				if (pstmt != null) {
444
					pstmt.close();
445
				}
446
			} catch (SQLException sqle) {
447
				logMetacat.error("XMLAccessAccess.updateXMLAccessPermission - SQL error when closing prepared " + 
448
						"statement after updating xml access permissions for doc id: " + docId + 
449
						", principal: " +  principalName + ":" + sqle.getMessage());
450
			} finally {
451
				DBConnectionPool.returnDBConnection(conn, serialNumber);
452
			}
453
		}
454
		
455
	}
456
	
457
	/**
458
	 * Delete xml access.  This modifies the access in the database for a principal 
459
	 * for a given document.  If the provided permission is exactly the same as what 
460
	 * the principal has, the record is removed from the database.
461
	 * @param docId
462
	 *            document id
463
	 * @param principalName
464
	 *            principal credentials
465
	 */
466
	private void removeXMLAccessForPrincipal(String docId, String principalName, Long permission) throws AccessException {
467
		if (docId == null) {
468
			throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - docid is required when " + 
469
					"removing XML access");
470
		}
471
		if (principalName == null) {
472
			throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - principal is required when " + 
473
					"deleting XML access");
474
		}
475
		if (permission == null) {
476
			throw new AccessException("XMLAccessAccess.removeXMLAccessForPrincipal - permission is required when " + 
477
					"updating XML access");
478
		}
479
		
480
		Vector<XMLAccessDAO> xmlAccessList = getXMLAccessForPrincipal(docId, principalName);
481
		if (xmlAccessList.size() == 0) {
482
			logMetacat.warn("XMLAccessAccess.removeXMLAccessForPrincipal - attempting to remove access when no " +
483
				"access record exists for docid: " + docId + ", principal: " + principalName);
484
		} else {
485
			long permissionMask = 0;
486
			for (XMLAccessDAO xmlAccessDAO : xmlAccessList) {
487
				permissionMask |= xmlAccessDAO.getPermission();
488
			}
489
			permissionMask |= permission;
490
			
491
			// in this case, the only existing permissions are the ones we want to remove, so 
492
			// delete the record(s) for this principal on this document
493
			if ((permissionMask & permission) == permission) {
494
				deleteXMLAccessForPrincipal(docId, principalName);
495
			}
496
			
497
			if (xmlAccessList.size() > 1) {
498
				
499
			} else {
500
				updateXMLAccessPermission(docId, principalName, permission);
501
			}
502
		}
503
	   
504
	}
505
	
506
	/**
507
	 * Delete xml access.  This removes all access records from the database for a principal 
508
	 * for a given document
509
	 * @param docId
510
	 *            document id
511
	 * @param principal
512
	 *            principal credentials
513
	 */
514
	private void deleteXMLAccessForPrincipal(String docId, String principalName) throws AccessException {
515
		if (docId == null) {
516
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - docid is required when " + 
517
					"deleting XML access record");
518
		}
519
		if (principalName == null) {
520
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - principal is required when " + 
521
					"deleting XML access record");
522
		}
523
		
524
	    PreparedStatement pstmt = null;
525
		DBConnection conn = null;
526
		int serialNumber = -1;
527
		try {
528
			// check out DBConnection
529
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForPrincipal");
530
			String sql = "DELETE FROM xml_access WHERE docid = ? AND principal_name = ?";
531
			pstmt = conn.prepareStatement(sql);
532

  
533
			// Bind the values to the query
534
			pstmt.setString(1, docId);
535
			pstmt.setString(2, principalName);
536

  
537
			String sqlReport = "XMLAccessAccess.deleteXMLAccessForPrincipal - SQL: " + sql;
538
			sqlReport += " [" + docId + "," + principalName + "]";
539
			
540
			logMetacat.info(sqlReport);
541

  
542
			pstmt.execute();
543
		} catch (SQLException sqle) {
544
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when deleting"
545
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
546
					principalName + ":" + sqle.getMessage());
547
		} finally {
548
			try {
549
				if (pstmt != null) {
550
					pstmt.close();
551
				}
552
			} catch (SQLException sqle) {
553
				logMetacat.error("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when closing prepared " + 
554
						"statement after deleting xml access permissions for doc id: " + docId + 
555
						", principal: " +  principalName + ":" + sqle.getMessage());
556
			} finally {
557
				DBConnectionPool.returnDBConnection(conn, serialNumber);
558
			}
559
		}	   
560
	}
561
	
562
	/**
563
	 * Delete xml access.  This removes all access records from the database for a principal 
564
	 * for a given document, perm type and perm order
565
	 * @param docId
566
	 *            document id
567
	 * @param principal
568
	 *            principal credentials
569
	 */
570
	private void deleteXMLAccessForPrincipal(String docId, String principalName, String permType, String permOrder) throws AccessException {
571
		if (docId == null) {
572
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - docid is required when " + 
573
					"deleting XML access record");
574
		}
575
		if (principalName == null) {
576
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - principal is required when " + 
577
					"deleting XML access record");
578
		}
579
		if (permType == null) {
580
			throw new AccessException(
581
					"XMLAccessAccess.deleteXMLAccessForPrincipal - perm type is required when "
582
							+ "deleting XML access record");
583
		}
584
		if (permOrder == null) {
585
			throw new AccessException(
586
					"XMLAccessAccess.deleteXMLAccessForPrincipal - perm order is required when "
587
							+ "deleting XML access record");
588
		}
589
		
590
	    PreparedStatement pstmt = null;
591
		DBConnection conn = null;
592
		int serialNumber = -1;
593
		try {
594
			// check out DBConnection
595
			conn = DBConnectionPool.getDBConnection("XMLAccessAccess.deleteXMLAccessForPrincipal");
596
			String sql = "DELETE FROM xml_access WHERE docid = ? AND principal_name = ?" +
597
				"AND perm_type = ? AND perm_ord";
598
			pstmt = conn.prepareStatement(sql);
599

  
600
			// Bind the values to the query
601
			pstmt.setString(1, docId);
602
			pstmt.setString(2, principalName);
603
			pstmt.setString(3, permType);
604
			pstmt.setString(4, permOrder);
605
			
606
			String sqlReport = "XMLAccessAccess.deleteXMLAccessForPrincipal - SQL: " + sql;
607
			sqlReport += " [" + docId + "," + principalName + "," + permType + "," + permOrder + "]";
608
			
609
			logMetacat.info(sqlReport);
610

  
611
			pstmt.execute();
612
		} catch (SQLException sqle) {
613
			throw new AccessException("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when deleting"
614
					+ "xml access permissions for doc id: " + docId + ", principal: " + 
615
					principalName + ":" + sqle.getMessage());
616
		} finally {
617
			try {
618
				if (pstmt != null) {
619
					pstmt.close();
620
				}
621
			} catch (SQLException sqle) {
622
				logMetacat.error("XMLAccessAccess.deleteXMLAccessForPrincipal - SQL error when closing prepared " + 
623
						"statement after deleting xml access permissions for doc id: " + docId + 
624
						", principal: " +  principalName + ":" + sqle.getMessage());
625
			} finally {
626
				DBConnectionPool.returnDBConnection(conn, serialNumber);
627
			}
628
		}
629
	   
630
	}
631
	
632
	private void cleanupXMLAccessForPrincipal(Vector<XMLAccessDAO> xmlAccessList) throws AccessException{
633
		
634
		long permissionMask = 0;
635
		String docId = null;
636
		String principalName = null;
637
		String permType = null;
638
		String permOrder = null;
639
	
640
		if (xmlAccessList.size() == 1) {
641
			return;
642
		}
643
		
644
		// iterate through the list of access dao objects and bttwise or the permissions.  Most
645
		// of this is just doing some error checking to make sure each record is valid.
646
		for (XMLAccessDAO xmlAccessDAO : xmlAccessList) {
647
			if (docId == null) {
648
				docId = xmlAccessDAO.getDocId();
649
			} else {
650
				if (!docId.equals(xmlAccessDAO.getDocId())) {
651
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
652
							" Conflicting doc ids " + xmlAccessDAO.getDocId() +
653
							" and " + docId);
654
				}
655
			}
656
			if (principalName == null) {
657
				principalName = xmlAccessDAO.getPrincipalName();
658
			} else {
659
				if (!principalName.equals(xmlAccessDAO.getPrincipalName())) {
660
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
661
							" Conflicting prinicpal names " + xmlAccessDAO.getPrincipalName() +
662
							" and principalName " + principalName);
663
				}
664
			}
665
			if (permType == null) {
666
				permType = xmlAccessDAO.getPermType();
667
			} else {
668
				if (!permType.equals(xmlAccessDAO.getPermType())) {
669
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
670
							" Conflicting permission orders for document " + xmlAccessDAO.getDocId() +
671
							"principalName " + principalName + ". Database intervention required ");
672
				}
673
			}
674
			if (permOrder == null) {
675
				permOrder = xmlAccessDAO.getPermOrder();
676
			} else {
677
				if (!permOrder.equals(xmlAccessDAO.getPermOrder())) {
678
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
679
							" Conflicting permission types for document " + xmlAccessDAO.getDocId() +
680
							"principalName " + principalName + ". Database intervention required ");
681
				}
682
			}
683
			if (permType == null) {
684
				permType = xmlAccessDAO.getPermType();
685
			} else {
686
				if (!permType.equals(xmlAccessDAO.getPermType())) {
687
					throw new AccessException("XMLAccessAccess.cleanupXMLAccessForPrincipal - " + 
688
							" Conflicting permission orders for document " + xmlAccessDAO.getDocId() +
689
							"principalName " + principalName + ". Database intervention required ");
690
				}
691
			}
692
			permissionMask |= xmlAccessDAO.getPermission();
693
		}
694
		
695
		// remove all records for this user on this doc with this perm type and perm order
696
		// then insert a single record 
697
		deleteXMLAccessForPrincipal(docId, principalName, permType, permOrder);
698
		insertXMLAccess(docId, principalName, permissionMask, permType, permOrder);
699
	}
700
	
701
	private void validateDocXMLAccessList(Vector<XMLAccessDAO> xmlAccessList) throws PermOrderException {
702
		String permOrder = null;
703
		for(XMLAccessDAO xmlAccessDAO : xmlAccessList) {
704
			if (permOrder == null) {
705
				permOrder = xmlAccessDAO.getPermOrder();
706
			} else {
707
				if(!permOrder.equals(xmlAccessDAO.getPermOrder())) {
708
					throw new PermOrderException("XMLAccessAccess.validateXMLAccessList - " + 
709
						" Conflicting permission orders for document " + xmlAccessDAO.getDocId() +
710
						". Database intervention required ");
711
				}
712
			}
713
		}		
714
	}
715
	
716
	private void validatePrincipalXMLAccessList(Vector<XMLAccessDAO> xmlAccessList) 
717
			throws PermOrderException {
718
		
719
		boolean allowFirst = false;
720
		boolean denyFirst = false;
721
		String docId = null;
722
		
723
		// These vectors will hold all combinations of access DAOs with different permission
724
		// orders and permission types.  
725
		Vector<XMLAccessDAO> allowFirstAllows = new Vector<XMLAccessDAO>();
726
		Vector<XMLAccessDAO> allowFirstDenys = new Vector<XMLAccessDAO>();
727
		Vector<XMLAccessDAO> denyFirstAllows = new Vector<XMLAccessDAO>();
728
		Vector<XMLAccessDAO> denyFirstDenys = new Vector<XMLAccessDAO>();
729
		
730
		// sort the access dao records into the appropriate vector
731
		for(XMLAccessDAO xmlAccessDAO : xmlAccessList) {
732
			if (docId == null) {
733
				docId = xmlAccessDAO.getDocId();
734
			}
735
			if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.ALLOWFIRST)) {
736
				allowFirst = true;
737
				if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
738
					allowFirstAllows.add(xmlAccessDAO);
739
				} else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) {
740
					allowFirstDenys.add(xmlAccessDAO);
741
				} else {
742
					throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
743
							" Invalid permission type: " + xmlAccessDAO.getPermType() + " for document " + 
744
							xmlAccessDAO.getDocId() + ". Database intervention required "); 
745
				}
746
			} else if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.DENYFIRST)) {
747
				denyFirst = true;
748
				if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
749
					denyFirstAllows.add(xmlAccessDAO);
750
				} else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) {
751
					denyFirstDenys.add(xmlAccessDAO);
752
				} else {
753
					throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
754
							" Invalid permission type: " + xmlAccessDAO.getPermType() + " for document " + 
755
							xmlAccessDAO.getDocId() + ". Database intervention required "); 
756
				}
757
			} else {
758
				throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
759
						" Invalid permission order: " + xmlAccessDAO.getPermOrder() + " for document " + 
760
						xmlAccessDAO.getDocId() + ". Database intervention required "); 
761
			}
762
		}
763
		
764
		// for a given user, there cannot be allowfirst and denyfirst records on the same 
765
		// document
766
		if(allowFirst && denyFirst) {
767
			throw new PermOrderException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
768
					" Conflicting permission orders for document " + docId +
769
					". Database intervention required ");
770
		}	
771
	}
772

  
773
	/**
774
	 * Check if the given list of XML access DAOs has redundant access.  This occurs if there is 
775
	 * more than one instance of any combination of access type and access order.  Note that we
776
	 * assume that the list contains access records for one principal on one document.
777
	 * @param xmlAccessList
778
	 * @return
779
	 * @throws AccessException
780
	 */
781
	private boolean hasRedundantPrincipalAccess(Vector<XMLAccessDAO> xmlAccessList) throws AccessException {
782
		
783
		// These will hold counts of all combinations of access DAOs with different permission
784
		// orders and permission types.  
785
		int allowFirstAllows = 0;
786
		int allowFirstDenys = 0;
787
		int denyFirstAllows = 0;
788
		int denyFirstDenys = 0;
789
		
790
		for(XMLAccessDAO xmlAccessDAO : xmlAccessList) {
791
			if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.ALLOWFIRST)) {
792
				if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
793
					allowFirstAllows++;
794
				} else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) {
795
					allowFirstDenys++;
796
				} else {
797
					throw new AccessException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
798
						"Invalid permission type: "+ xmlAccessDAO.getPermType() + " for document " + 
799
						xmlAccessDAO.getDocId() + ". Database intervention required ");
800
				}
801
			} else if (xmlAccessDAO.getPermOrder().equals(AccessControlInterface.DENYFIRST)) {
802
				if (xmlAccessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
803
					denyFirstAllows++;
804
				} else if (xmlAccessDAO.getPermType().equals(AccessControlInterface.DENY)) {
805
					denyFirstDenys++;
806
				} else {
807
					throw new AccessException("XMLAccessAccess.validatePrincipalXMLAccessList - " + 
808
						"Invalid permission type: " + xmlAccessDAO.getPermType() + " for document "+ 
809
						xmlAccessDAO.getDocId() + ". Database intervention required ");
810
				}
811
			}
812
		}
813
		return (allowFirstAllows > 1) || (allowFirstDenys > 1) || (denyFirstAllows > 1)
814
				|| (denyFirstDenys > 1);
815
	}
816
	
817
	/**
818
	 * Populate a job data object with the current row in a resultset
819
	 * 
820
	 * @param resultSet
821
	 *            the result set which is already pointing to the desired row.
822
	 * @return a scheduled job data object
823
	 */
824
	protected XMLAccessDAO populateDAO(ResultSet resultSet) throws SQLException {
825

  
826
		XMLAccessDAO xmlAccessDAO = new XMLAccessDAO();
827
		xmlAccessDAO.setDocId(resultSet.getString("docid"));
828
		xmlAccessDAO.setAccessFileId(resultSet.getString("accessfileid"));
829
		xmlAccessDAO.setPrincipalName(resultSet.getString("principal_name"));
830
		xmlAccessDAO.setPermission(resultSet.getLong("permission"));
831
		xmlAccessDAO.setPermType(resultSet.getString("perm_type"));
832
		xmlAccessDAO.setPermOrder(resultSet.getString("perm_order"));
833
		xmlAccessDAO.setBeginTime(resultSet.getDate("begin_time"));
834
		xmlAccessDAO.setEndTime(resultSet.getDate("end_time"));
835
		xmlAccessDAO.setTicketCount(resultSet.getLong("ticket_count"));
836
		xmlAccessDAO.setSubTreeId(resultSet.getString("subtreeid"));
837
		xmlAccessDAO.setStartNodeId(resultSet.getString("startnodeid"));
838
		xmlAccessDAO.setEndNodeId(resultSet.getString("endnodeid"));
839

  
840
		return xmlAccessDAO;
841
	}
842
	
843
}
src/edu/ucsb/nceas/metacat/accesscontrol/XMLAccessDAO.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that represents an XML Text node and its contents,
4
 *             and can build itself from a database connection
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Matt Jones
8
 *
9
 *   '$Author: daigle $'
10
 *     '$Date: 2008-10-21 15:20:52 -0700 (Tue, 21 Oct 2008) $'
11
 * '$Revision: 4468 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

  
28
package edu.ucsb.nceas.metacat.accesscontrol;
29

  
30
import java.sql.Date;
31

  
32
import org.apache.log4j.Logger;
33

  
34
import edu.ucsb.nceas.metacat.shared.BaseDAO;
35

  
36
/**
37
 * A Class that represents an XML access rule. It include principal and 
38
 * permission
39
 */
40
public class XMLAccessDAO extends BaseDAO {
41

  
42
	private String _docId = null;
43
	private String _accessFileId = null;
44
	private String _principalName = null;
45
	private Long _permission = null;
46
	private String _permType = null;
47
	private String _permOrder = null;
48
	private Date _beginTime = null;
49
	private Date _endTime = null;
50
	private Long _ticketCount = null;
51
	private String _subTreeId = null;
52
	private String _startNodeId = null;
53
	private String _endNodeId = null;
54

  
55
	public String getDocId() {
56
		return _docId;
57
	}
58
	
59
	public void setDocId(String docId) {
60
		_docId = docId;
61
	}
62

  
63
	public String getAccessFileId() {
64
		return _accessFileId;
65
	}
66
	
67
	public void setAccessFileId(String accessFileId) {
68
		_accessFileId = accessFileId;
69
	}
70
	
71
	public String getPrincipalName() {
72
		return _principalName;
73
	}
74
	
75
	public void setPrincipalName(String principalName) {
76
		_principalName = principalName;
77
	}
78
	
79
	public Long getPermission() {
80
		return _permission;
81
	}
82
	
83
	public void setPermission(Long permission) {
84
		_permission = permission;
85
	}
86
	
87
	public String getPermType() {
88
		return _permType;
89
	}
90
	
91
	public void setPermType(String permType) {
92
		_permType = permType;
93
	}
94
	
95
	public String getPermOrder() {
96
		return _permOrder;
97
	}
98
	
99
	public void setPermOrder(String permOrder) {
100
		_permOrder = permOrder;
101
	}
102
	
103
	public Date getBeginTime() {
104
		return _beginTime;
105
	}
106
	
107
	public void setBeginTime(Date beginTime) {
108
		_beginTime = beginTime;
109
	}
110
	
111
	public Date getEndTime() {
112
		return _endTime;
113
	}
114
	
115
	public void setEndTime(Date endTime) {
116
		_endTime = endTime;
117
	}
118
	
119
	public Long getTicketCount() {
120
		return _ticketCount;
121
	}
122
	
123
	public void setTicketCount(Long ticketCount) {
124
		_ticketCount = ticketCount;
125
	}
126
	
127
	public String getSubTreeId() {
128
		return _subTreeId;
129
	}
130
	
131
	public void setSubTreeId(String subTreeId) {
132
		_subTreeId = subTreeId;
133
	}
134
	
135
	public String getStartNodeId() {
136
		return _startNodeId;
137
	}
138
	
139
	public void setStartNodeId(String startNodeId) {
140
		_startNodeId = startNodeId;
141
	}
142
	
143
	public String getEndNodeId() {
144
		return _endNodeId;
145
	}
146
	
147
	public void setEndNodeId(String endNodeId) {
148
		_endNodeId = endNodeId;
149
	}
150

  
151
}
0 152

  
src/edu/ucsb/nceas/metacat/accesscontrol/PermOrderException.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: An Exception thrown when an error occurs because an 
4
 *             AccessionNumber was invalid or used incorrectly
5
 *  Copyright: 2008 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Michael Daigle
8
 *
9
 *   '$Author: daigle $'
10
 *     '$Date: 2008-07-06 21:25:34 -0700 (Sun, 06 Jul 2008) $'
11
 * '$Revision: 4080 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

  
28
package edu.ucsb.nceas.metacat.accesscontrol;
29

  
30
import edu.ucsb.nceas.metacat.shared.BaseException;
31

  
32

  
33
/**
34
 * Exception thrown when an error occurs in a configuration administrative
35
 * class
36
 */
37
public class PermOrderException extends BaseException {
38
	
39
	private static final long serialVersionUID = -8436697355629175917L;
40

  
41
	/**
42
	 * Create a new PermOrderException.
43
	 *
44
	 * @param message The error or warning message.
45
	 */
46
	public PermOrderException(String message) {
47
		super(message);
48
	}
49
	
50
	public PermOrderException(String message, BaseException deeperException) {
51
		super(message, deeperException);
52
	}
53
}
0 54

  

Also available in: Unified diff