001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/security/drm/SQLRegistry.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 package org.deegree.security.drm; 044 045 import java.io.BufferedReader; 046 import java.io.IOException; 047 import java.io.InputStreamReader; 048 import java.io.OutputStream; 049 import java.io.OutputStreamWriter; 050 import java.io.Reader; 051 import java.io.StringReader; 052 import java.sql.Clob; 053 import java.sql.Connection; 054 import java.sql.PreparedStatement; 055 import java.sql.ResultSet; 056 import java.sql.ResultSetMetaData; 057 import java.sql.SQLException; 058 import java.sql.Statement; 059 import java.sql.Types; 060 import java.util.ArrayList; 061 import java.util.Properties; 062 063 import oracle.jdbc.OracleConnection; 064 import oracle.sql.CLOB; 065 066 import org.deegree.framework.log.ILogger; 067 import org.deegree.framework.log.LoggerFactory; 068 import org.deegree.framework.util.DataBaseIDGenerator; 069 import org.deegree.framework.util.StringTools; 070 import org.deegree.framework.xml.XMLTools; 071 import org.deegree.io.DBConnectionPool; 072 import org.deegree.io.IDGeneratorFactory; 073 import org.deegree.model.filterencoding.AbstractFilter; 074 import org.deegree.model.filterencoding.ComplexFilter; 075 import org.deegree.model.filterencoding.Filter; 076 import org.deegree.model.filterencoding.FilterConstructionException; 077 import org.deegree.security.GeneralSecurityException; 078 import org.deegree.security.drm.model.Group; 079 import org.deegree.security.drm.model.Privilege; 080 import org.deegree.security.drm.model.Right; 081 import org.deegree.security.drm.model.RightType; 082 import org.deegree.security.drm.model.Role; 083 import org.deegree.security.drm.model.SecurableObject; 084 import org.deegree.security.drm.model.SecuredObject; 085 import org.deegree.security.drm.model.User; 086 import org.w3c.dom.Document; 087 import org.w3c.dom.Element; 088 089 /** 090 * This is an implementation of a <code>Registry</code> using an SQL-Database (via JDBC) as 091 * backend. 092 * 093 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 094 * @version $Revision: 9346 $ 095 */ 096 public final class SQLRegistry implements SecurityRegistry { 097 098 private static final ILogger LOG = LoggerFactory.getLogger( SQLRegistry.class ); 099 100 private String dbDriver; 101 102 private String dbName; 103 104 private String dbUser; 105 106 private String dbPassword; 107 108 /** Exclusive connection for a transaction (only one at a time). */ 109 private Connection transactionalConnection = null; 110 111 public void clean( SecurityTransaction transaction ) 112 throws GeneralSecurityException { 113 114 PreparedStatement pstmt = null; 115 try { 116 BufferedReader reader = new BufferedReader( 117 new InputStreamReader( 118 SQLRegistry.class.getResourceAsStream( "clean.sql" ) ) ); 119 StringBuffer sb = new StringBuffer( 5000 ); 120 String line = null; 121 while ( ( line = reader.readLine() ) != null ) { 122 sb.append( line ); 123 } 124 String tmp = sb.toString(); 125 String[] commands = StringTools.toArray( tmp, ";", false ); 126 for ( int i = 0; i < commands.length; i++ ) { 127 String command = commands[i].trim(); 128 if ( !command.equals( "" ) ) { 129 pstmt = transactionalConnection.prepareStatement( command ); 130 pstmt.executeUpdate(); 131 closeStatement( pstmt ); 132 pstmt = null; 133 } 134 } 135 } catch ( SQLException e ) { 136 LOG.logError( e.getMessage(), e ); 137 closeStatement( pstmt ); 138 abortTransaction( transaction ); 139 throw new GeneralSecurityException( "SQLRegistry.clean() failed. Rollback performed. " + "Error message: " 140 + e.getMessage() ); 141 } catch ( IOException e ) { 142 LOG.logError( e.getMessage(), e ); 143 throw new GeneralSecurityException( "SQLRegistry.clean() failed. Problem reading sql command file. " 144 + "Error message: " + e.getMessage() ); 145 } 146 } 147 148 /** 149 * Adds a new user account to the <code>Registry</code>. 150 * 151 * @param transaction 152 * @param name 153 * @throws GeneralSecurityException 154 * this is a <code>DuplicateException</code> if the group already existed 155 */ 156 public User registerUser( SecurityTransaction transaction, String name, String password, String lastName, 157 String firstName, String emailAddress ) 158 throws GeneralSecurityException { 159 try { 160 getUserByName( transaction, name ); 161 throw new DuplicateException( "Registration of user '" + name + "' failed! A user with " 162 + "this name already exists." ); 163 } catch ( UnknownException e ) { 164 } 165 166 User user = new User( getID( transaction, "SEC_SECURABLE_OBJECTS" ), name, password, firstName, lastName, 167 emailAddress, this ); 168 PreparedStatement pstmt = null; 169 170 try { 171 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_SECURABLE_OBJECTS (ID,NAME,TITLE) VALUES (?,?,?)" ); 172 pstmt.setInt( 1, user.getID() ); 173 pstmt.setString( 2, user.getName() ); 174 pstmt.setString( 3, user.getTitle() ); 175 pstmt.executeUpdate(); 176 closeStatement( pstmt ); 177 pstmt = null; 178 179 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_USERS (ID,PASSWORD,FIRSTNAME,LASTNAME,EMAIL) VALUES (?,?,?,?,?)" ); 180 pstmt.setInt( 1, user.getID() ); 181 pstmt.setString( 2, password ); 182 pstmt.setString( 3, user.getFirstName() ); 183 pstmt.setString( 4, user.getLastName() ); 184 pstmt.setString( 5, user.getEmailAddress() ); 185 pstmt.executeUpdate(); 186 closeStatement( pstmt ); 187 } catch ( SQLException e ) { 188 LOG.logError( e.getMessage(), e ); 189 closeStatement( pstmt ); 190 abortTransaction( transaction ); 191 throw new GeneralSecurityException( "SQLRegistry.registerUser() failed. Rollback performed. " 192 + "Error message: " + e.getMessage() ); 193 } 194 return user; 195 } 196 197 /** 198 * Removes an existing <code>User<code> from the <code>Registry</code> 199 * (including its relations). 200 * 201 * @param transaction 202 * @param user 203 * @throws GeneralSecurityException 204 */ 205 public void deregisterUser( SecurityTransaction transaction, User user ) 206 throws GeneralSecurityException { 207 PreparedStatement pstmt = null; 208 209 try { 210 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_GROUPS WHERE FK_USERS=?" ); 211 pstmt.setInt( 1, user.getID() ); 212 pstmt.executeUpdate(); 213 pstmt.close(); 214 pstmt = null; 215 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_ROLES WHERE FK_USERS=?" ); 216 pstmt.setInt( 1, user.getID() ); 217 pstmt.executeUpdate(); 218 pstmt.close(); 219 pstmt = null; 220 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_USERS WHERE ID=?" ); 221 pstmt.setInt( 1, user.getID() ); 222 pstmt.executeUpdate(); 223 pstmt.close(); 224 pstmt = null; 225 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_SECURABLE_OBJECTS=?" ); 226 pstmt.setInt( 1, user.getID() ); 227 pstmt.executeUpdate(); 228 pstmt.close(); 229 pstmt = null; 230 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_SECURABLE_OBJECTS WHERE ID=?" ); 231 pstmt.setInt( 1, user.getID() ); 232 pstmt.executeUpdate(); 233 pstmt.close(); 234 } catch ( SQLException e ) { 235 LOG.logError( e.getMessage(), e ); 236 closeStatement( pstmt ); 237 abortTransaction( transaction ); 238 throw new GeneralSecurityException( "SQLRegistry.deregisterUser() failed. Rollback performed. " 239 + "Error message: " + e.getMessage() ); 240 } 241 } 242 243 /** 244 * Updates the metadata (name, email, etc.) of a <code>User</code> in the 245 * <code>Registry</code>. 246 * 247 * @throws GeneralSecurityException 248 * this is a <code>DuplicateException</code> if a user with the new name already 249 * existed 250 */ 251 public void updateUser( SecurityTransaction transaction, User user ) 252 throws GeneralSecurityException { 253 254 PreparedStatement pstmt = null; 255 256 try { 257 pstmt = transactionalConnection.prepareStatement( "UPDATE SEC_SECURABLE_OBJECTS SET NAME=?,TITLE=? WHERE ID=?" ); 258 pstmt.setString( 1, user.getName() ); 259 pstmt.setString( 2, user.getTitle() ); 260 pstmt.setInt( 3, user.getID() ); 261 pstmt.executeUpdate(); 262 closeStatement( pstmt ); 263 pstmt = null; 264 265 pstmt = transactionalConnection.prepareStatement( "UPDATE SEC_USERS SET PASSWORD=?,FIRSTNAME=?,LASTNAME=?,EMAIL=? WHERE ID=?" ); 266 pstmt.setString( 1, user.getPassword() ); 267 pstmt.setString( 2, user.getFirstName() ); 268 pstmt.setString( 3, user.getLastName() ); 269 pstmt.setString( 4, user.getEmailAddress() ); 270 pstmt.setInt( 5, user.getID() ); 271 pstmt.executeUpdate(); 272 closeStatement( pstmt ); 273 } catch ( SQLException e ) { 274 LOG.logError( e.getMessage(), e ); 275 closeStatement( pstmt ); 276 abortTransaction( transaction ); 277 throw new GeneralSecurityException( "SQLRegistry.registerUser() failed. Rollback performed. " 278 + "Error message: " + e.getMessage() ); 279 } 280 } 281 282 /** 283 * Retrieves a <code>User</code> from the <code>Registry</code>. 284 * 285 * @param securityAccess 286 * @param name 287 * @throws GeneralSecurityException 288 * this is an <code>UnknownException</code> if the user is not known to the 289 * <code>Registry</code> 290 * 291 */ 292 public User getUserByName( SecurityAccess securityAccess, String name ) 293 throws GeneralSecurityException { 294 User user = null; 295 Connection con = acquireLocalConnection( securityAccess ); 296 PreparedStatement pstmt = null; 297 ResultSet rs = null; 298 299 try { 300 pstmt = con.prepareStatement( "SELECT SEC_USERS.ID,SEC_USERS.PASSWORD,SEC_USERS.FIRSTNAME,SEC_USERS.LASTNAME,SEC_USERS.EMAIL " 301 + "FROM SEC_USERS,SEC_SECURABLE_OBJECTS " 302 + "WHERE SEC_USERS.ID=SEC_SECURABLE_OBJECTS.ID AND " 303 + "SEC_SECURABLE_OBJECTS.NAME=?" ); 304 pstmt.setString( 1, name ); 305 rs = pstmt.executeQuery(); 306 if ( rs.next() ) { 307 user = new User( rs.getInt( 1 ), name, rs.getString( 2 ), rs.getString( 3 ), rs.getString( 4 ), 308 rs.getString( 5 ), this ); 309 } else { 310 throw new UnknownException( "Lookup of user '" + name 311 + "' failed! A user with this name does not exist." ); 312 } 313 } catch ( SQLException e ) { 314 LOG.logError( e.getMessage(), e ); 315 throw new GeneralSecurityException( e ); 316 } finally { 317 closeResultSet( rs ); 318 closeStatement( pstmt ); 319 releaseLocalConnection( securityAccess, con ); 320 } 321 322 return user; 323 } 324 325 /** 326 * Retrieves a <code>User</code> from the <code>Registry</code>. 327 * 328 * @param securityAccess 329 * @param id 330 * @throws GeneralSecurityException 331 * this is an <code>UnknownException</code> if the user is not known to the 332 * <code>Registry</code> 333 */ 334 public User getUserById( SecurityAccess securityAccess, int id ) 335 throws GeneralSecurityException { 336 User user = null; 337 Connection con = acquireLocalConnection( securityAccess ); 338 PreparedStatement pstmt = null; 339 ResultSet rs = null; 340 341 try { 342 pstmt = con.prepareStatement( "SELECT SEC_SECURABLE_OBJECTS.NAME," 343 + "SEC_USERS.PASSWORD,SEC_USERS.FIRSTNAME,SEC_USERS.LASTNAME," 344 + "SEC_USERS.EMAIL FROM SEC_USERS,SEC_SECURABLE_OBJECTS " 345 + "WHERE SEC_SECURABLE_OBJECTS.ID=? AND SEC_USERS.ID=SEC_SECURABLE_OBJECTS.ID" ); 346 pstmt.setInt( 1, id ); 347 rs = pstmt.executeQuery(); 348 if ( rs.next() ) { 349 user = new User( id, rs.getString( 1 ), rs.getString( 2 ), rs.getString( 3 ), rs.getString( 4 ), 350 rs.getString( 5 ), this ); 351 } else { 352 throw new UnknownException( "Lookup of user with id: " + id 353 + " failed! A user with this id does not exist." ); 354 } 355 } catch ( SQLException e ) { 356 throw new GeneralSecurityException( e ); 357 } finally { 358 closeResultSet( rs ); 359 closeStatement( pstmt ); 360 releaseLocalConnection( securityAccess, con ); 361 } 362 return user; 363 } 364 365 /** 366 * Retrieves all <code>User</code> s from the <code>Registry</code>. 367 * 368 * @param securityAccess 369 * @throws GeneralSecurityException 370 */ 371 public User[] getAllUsers( SecurityAccess securityAccess ) 372 throws GeneralSecurityException { 373 ArrayList<User> users = new ArrayList<User>( 500 ); 374 Connection con = acquireLocalConnection( securityAccess ); 375 PreparedStatement pstmt = null; 376 ResultSet rs = null; 377 378 try { 379 pstmt = con.prepareStatement( "SELECT SEC_USERS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_USERS.PASSWORD,SEC_USERS.FIRSTNAME,SEC_USERS.LASTNAME,SEC_USERS.EMAIL " 380 + "FROM SEC_USERS,SEC_SECURABLE_OBJECTS " 381 + "WHERE SEC_USERS.ID=SEC_SECURABLE_OBJECTS.ID" ); 382 rs = pstmt.executeQuery(); 383 while ( rs.next() ) { 384 users.add( new User( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), rs.getString( 4 ), 385 rs.getString( 5 ), rs.getString( 6 ), this ) ); 386 } 387 } catch ( SQLException e ) { 388 LOG.logError( e.getMessage(), e ); 389 throw new GeneralSecurityException( e ); 390 } finally { 391 closeResultSet( rs ); 392 closeStatement( pstmt ); 393 releaseLocalConnection( securityAccess, con ); 394 } 395 return users.toArray( new User[users.size()] ); 396 } 397 398 /** 399 * Retrieves all <code>Users</code> s from the <code>Registry</code> that are associated 400 * DIRECTLY (i.e. not via group memberships) with a given <code>Role</code>. 401 * 402 * @param securityAccess 403 * @param role 404 * @throws GeneralSecurityException 405 */ 406 public User[] getUsersWithRole( SecurityAccess securityAccess, Role role ) 407 throws GeneralSecurityException { 408 ArrayList<User> users = new ArrayList<User>( 500 ); 409 Connection con = acquireLocalConnection( securityAccess ); 410 PreparedStatement pstmt = null; 411 ResultSet rs = null; 412 413 try { 414 pstmt = con.prepareStatement( "SELECT SEC_USERS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_USERS.PASSWORD,SEC_USERS.FIRSTNAME,SEC_USERS.LASTNAME," 415 + "SEC_USERS.EMAIL " 416 + "FROM SEC_USERS,SEC_SECURABLE_OBJECTS,SEC_JT_USERS_ROLES " 417 + "WHERE SEC_SECURABLE_OBJECTS.ID=SEC_USERS.ID AND SEC_JT_USERS_ROLES.FK_USERS=SEC_USERS.ID" 418 + " AND SEC_JT_USERS_ROLES.FK_ROLES=?" ); 419 pstmt.setInt( 1, role.getID() ); 420 rs = pstmt.executeQuery(); 421 while ( rs.next() ) { 422 users.add( new User( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), rs.getString( 4 ), 423 rs.getString( 5 ), rs.getString( 6 ), this ) ); 424 } 425 } catch ( SQLException e ) { 426 LOG.logError( e.getMessage(), e ); 427 throw new GeneralSecurityException( e ); 428 } finally { 429 closeResultSet( rs ); 430 closeStatement( pstmt ); 431 releaseLocalConnection( securityAccess, con ); 432 } 433 return users.toArray( new User[users.size()] ); 434 } 435 436 /** 437 * Retrieves all <code>User</code> s from the <code>Registry</code> that belong to the given 438 * <code>Group</code> DIRECTLY (i.e. not via inheritance). 439 * 440 * @param securityAccess 441 * @param group 442 * @throws GeneralSecurityException 443 */ 444 public User[] getUsersInGroup( SecurityAccess securityAccess, Group group ) 445 throws GeneralSecurityException { 446 ArrayList<User> users = new ArrayList<User>( 500 ); 447 Connection con = acquireLocalConnection( securityAccess ); 448 PreparedStatement pstmt = null; 449 ResultSet rs = null; 450 451 try { 452 pstmt = con.prepareStatement( "SELECT SEC_USERS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_USERS.PASSWORD,SEC_USERS.FIRSTNAME,SEC_USERS.LASTNAME," 453 + "SEC_USERS.EMAIL " 454 + "FROM SEC_USERS,SEC_SECURABLE_OBJECTS,SEC_JT_USERS_GROUPS " 455 + "WHERE SEC_SECURABLE_OBJECTS.ID=SEC_USERS.ID AND SEC_JT_USERS_GROUPS.FK_USERS=SEC_USERS.ID" 456 + " AND SEC_JT_USERS_GROUPS.FK_GROUPS=?" ); 457 pstmt.setInt( 1, group.getID() ); 458 rs = pstmt.executeQuery(); 459 while ( rs.next() ) { 460 users.add( new User( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), rs.getString( 4 ), 461 rs.getString( 5 ), rs.getString( 6 ), this ) ); 462 } 463 } catch ( SQLException e ) { 464 LOG.logError( e.getMessage(), e ); 465 throw new GeneralSecurityException( e ); 466 } finally { 467 closeResultSet( rs ); 468 closeStatement( pstmt ); 469 releaseLocalConnection( securityAccess, con ); 470 } 471 return users.toArray( new User[users.size()] ); 472 } 473 474 /** 475 * Adds a new group account to the <code>Registry</code>. 476 * 477 * 478 * @param transaction 479 * @param name 480 * @throws GeneralSecurityException 481 * this is a <code>DuplicateException</code> if the group already existed 482 */ 483 public Group registerGroup( SecurityTransaction transaction, String name, String title ) 484 throws GeneralSecurityException { 485 try { 486 getGroupByName( transaction, name ); 487 throw new DuplicateException( "Registration of group '" + name + "' failed! A group with " 488 + "this name already exists." ); 489 } catch ( UnknownException e ) { 490 } 491 492 Group group = new Group( getID( transaction, "SEC_SECURABLE_OBJECTS" ), name, title, this ); 493 PreparedStatement pstmt = null; 494 495 try { 496 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_SECURABLE_OBJECTS (ID,NAME,TITLE) VALUES (?,?,?)" ); 497 pstmt.setInt( 1, group.getID() ); 498 pstmt.setString( 2, group.getName() ); 499 pstmt.setString( 3, group.getTitle() ); 500 pstmt.executeUpdate(); 501 pstmt.close(); 502 pstmt = null; 503 504 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_GROUPS (ID) VALUES (?)" ); 505 pstmt.setInt( 1, group.getID() ); 506 pstmt.executeUpdate(); 507 pstmt.close(); 508 } catch ( SQLException e ) { 509 LOG.logError( e.getMessage(), e ); 510 closeStatement( pstmt ); 511 abortTransaction( transaction ); 512 throw new GeneralSecurityException( "SQLRegistry.registerGroup() failed. Rollback performed. " 513 + "Error message: " + e.getMessage() ); 514 } 515 return group; 516 } 517 518 /** 519 * Removes an existing <code>Group</code> from the <code>Registry</code> (including its 520 * relations). 521 * 522 * @param transaction 523 * @param group 524 * @throws GeneralSecurityException 525 */ 526 public void deregisterGroup( SecurityTransaction transaction, Group group ) 527 throws GeneralSecurityException { 528 PreparedStatement pstmt = null; 529 530 try { 531 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_GROUPS WHERE FK_GROUPS=?" ); 532 pstmt.setInt( 1, group.getID() ); 533 pstmt.executeUpdate(); 534 pstmt.close(); 535 pstmt = null; 536 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_GROUPS WHERE FK_GROUPS=? OR FK_GROUPS_MEMBER=?" ); 537 pstmt.setInt( 1, group.getID() ); 538 pstmt.setInt( 2, group.getID() ); 539 pstmt.executeUpdate(); 540 pstmt.close(); 541 pstmt = null; 542 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_ROLES WHERE FK_GROUPS=?" ); 543 pstmt.setInt( 1, group.getID() ); 544 pstmt.executeUpdate(); 545 pstmt.close(); 546 pstmt = null; 547 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_GROUPS WHERE ID=?" ); 548 pstmt.setInt( 1, group.getID() ); 549 pstmt.executeUpdate(); 550 pstmt.close(); 551 pstmt = null; 552 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_SECURABLE_OBJECTS=?" ); 553 pstmt.setInt( 1, group.getID() ); 554 pstmt.executeUpdate(); 555 pstmt.close(); 556 pstmt = null; 557 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_SECURABLE_OBJECTS WHERE ID=?" ); 558 pstmt.setInt( 1, group.getID() ); 559 pstmt.executeUpdate(); 560 pstmt.close(); 561 pstmt = null; 562 } catch ( SQLException e ) { 563 LOG.logError( e.getMessage(), e ); 564 closeStatement( pstmt ); 565 abortTransaction( transaction ); 566 throw new GeneralSecurityException( "SQLRegistry.deregisterGroup() failed. Rollback performed. " 567 + "Error message: " + e.getMessage() ); 568 } 569 } 570 571 /** 572 * Retrieves a <code>Group</code> from the <code>Registry</code>. 573 * 574 * @param securityAccess 575 * @param name 576 * @throws GeneralSecurityException 577 * this is an <code>UnknownException</code> if the group is not known to the 578 * <code>Registry</code> 579 */ 580 public Group getGroupByName( SecurityAccess securityAccess, String name ) 581 throws GeneralSecurityException { 582 Group group = null; 583 Connection con = acquireLocalConnection( securityAccess ); 584 PreparedStatement pstmt = null; 585 ResultSet rs = null; 586 587 try { 588 pstmt = con.prepareStatement( "SELECT SEC_GROUPS.ID,SEC_SECURABLE_OBJECTS.TITLE " 589 + "FROM SEC_GROUPS,SEC_SECURABLE_OBJECTS " 590 + "WHERE SEC_GROUPS.ID=SEC_SECURABLE_OBJECTS.ID AND " 591 + "SEC_SECURABLE_OBJECTS.NAME=?" ); 592 pstmt.setString( 1, name ); 593 rs = pstmt.executeQuery(); 594 if ( rs.next() ) { 595 group = new Group( rs.getInt( 1 ), name, rs.getString( 2 ), this ); 596 } else { 597 throw new UnknownException( "Lookup of group '" + name 598 + "' failed! A group with this name does not exist." ); 599 } 600 } catch ( SQLException e ) { 601 LOG.logError( e.getMessage(), e ); 602 throw new GeneralSecurityException( e ); 603 } finally { 604 closeResultSet( rs ); 605 closeStatement( pstmt ); 606 releaseLocalConnection( securityAccess, con ); 607 } 608 return group; 609 } 610 611 /** 612 * Retrieves a <code>Group</code> from the <code>Registry</code>. 613 * 614 * @param securityAccess 615 * @param id 616 * @throws GeneralSecurityException 617 * this is an <code>UnknownException</code> if the group is not known to the 618 * <code>Registry</code> 619 */ 620 public Group getGroupById( SecurityAccess securityAccess, int id ) 621 throws GeneralSecurityException { 622 Group group = null; 623 Connection con = acquireLocalConnection( securityAccess ); 624 PreparedStatement pstmt = null; 625 ResultSet rs = null; 626 627 try { 628 pstmt = con.prepareStatement( "SELECT SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 629 + "FROM SEC_GROUPS,SEC_SECURABLE_OBJECTS " 630 + "WHERE SEC_SECURABLE_OBJECTS.ID=? AND SEC_GROUPS.ID=SEC_SECURABLE_OBJECTS.ID" ); 631 pstmt.setInt( 1, id ); 632 rs = pstmt.executeQuery(); 633 if ( rs.next() ) { 634 group = new Group( id, rs.getString( 1 ), rs.getString( 2 ), this ); 635 } else { 636 throw new UnknownException( "Lookup of group with id: " + id 637 + " failed! A group with this id does not exist." ); 638 } 639 } catch ( SQLException e ) { 640 LOG.logError( e.getMessage(), e ); 641 throw new GeneralSecurityException( e ); 642 } finally { 643 closeResultSet( rs ); 644 closeStatement( pstmt ); 645 releaseLocalConnection( securityAccess, con ); 646 } 647 return group; 648 } 649 650 /** 651 * Retrieves all <code>Group</code> s from the <code>Registry</code>. 652 * 653 * @param securityAccess 654 * @throws GeneralSecurityException 655 */ 656 public Group[] getAllGroups( SecurityAccess securityAccess ) 657 throws GeneralSecurityException { 658 ArrayList<Group> groups = new ArrayList<Group>( 50 ); 659 Connection con = acquireLocalConnection( securityAccess ); 660 PreparedStatement pstmt = null; 661 ResultSet rs = null; 662 663 try { 664 pstmt = con.prepareStatement( "SELECT SEC_GROUPS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 665 + "FROM SEC_GROUPS,SEC_SECURABLE_OBJECTS " 666 + "WHERE SEC_GROUPS.ID=SEC_SECURABLE_OBJECTS.ID" ); 667 rs = pstmt.executeQuery(); 668 while ( rs.next() ) { 669 groups.add( new Group( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), this ) ); 670 } 671 } catch ( SQLException e ) { 672 LOG.logError( e.getMessage(), e ); 673 throw new GeneralSecurityException( e ); 674 } finally { 675 closeResultSet( rs ); 676 closeStatement( pstmt ); 677 releaseLocalConnection( securityAccess, con ); 678 } 679 return groups.toArray( new Group[groups.size()] ); 680 } 681 682 /** 683 * Adds a new role to the <code>Registry</code>. 684 * 685 * @param transaction 686 * @param name 687 * @throws GeneralSecurityException 688 * this is a <code>DuplicateException</code> if the role already existed 689 */ 690 public Role registerRole( SecurityTransaction transaction, String name ) 691 throws GeneralSecurityException { 692 try { 693 getRoleByName( transaction, name ); 694 throw new DuplicateException( "Registration of role '" + name + "' failed! A role with " 695 + "this name already exists." ); 696 } catch ( UnknownException e ) { 697 } 698 699 Role role = new Role( getID( transaction, "SEC_SECURABLE_OBJECTS" ), name, this ); 700 PreparedStatement pstmt = null; 701 702 try { 703 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_SECURABLE_OBJECTS (ID,NAME,TITLE) VALUES (?,?,?)" ); 704 pstmt.setInt( 1, role.getID() ); 705 pstmt.setString( 2, role.getName() ); 706 pstmt.setString( 3, role.getTitle() ); 707 pstmt.executeUpdate(); 708 pstmt.close(); 709 pstmt = null; 710 711 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_ROLES (ID) VALUES (?)" ); 712 pstmt.setInt( 1, role.getID() ); 713 pstmt.executeUpdate(); 714 pstmt.close(); 715 pstmt = null; 716 } catch ( SQLException e ) { 717 LOG.logError( e.getMessage(), e ); 718 closeStatement( pstmt ); 719 abortTransaction( transaction ); 720 throw new GeneralSecurityException( "SQLRegistry.registerRole() failed. Rollback performed. " 721 + "Error message: " + e.getMessage() ); 722 } 723 return role; 724 } 725 726 /** 727 * Removes an existing <code>Role</code> from the <code>Registry</code> (including its 728 * relations). 729 * 730 * @param transaction 731 * @param role 732 * @throws GeneralSecurityException 733 */ 734 public void deregisterRole( SecurityTransaction transaction, Role role ) 735 throws GeneralSecurityException { 736 PreparedStatement pstmt = null; 737 738 try { 739 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_ROLES WHERE FK_ROLES=?" ); 740 pstmt.setInt( 1, role.getID() ); 741 pstmt.executeUpdate(); 742 pstmt.close(); 743 pstmt = null; 744 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_ROLES WHERE FK_ROLES=?" ); 745 pstmt.setInt( 1, role.getID() ); 746 pstmt.executeUpdate(); 747 pstmt.close(); 748 pstmt = null; 749 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_ROLES=? OR FK_SECURABLE_OBJECTS=?" ); 750 pstmt.setInt( 1, role.getID() ); 751 pstmt.setInt( 2, role.getID() ); 752 pstmt.executeUpdate(); 753 pstmt.close(); 754 pstmt = null; 755 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_ROLES WHERE ID=?" ); 756 pstmt.setInt( 1, role.getID() ); 757 pstmt.executeUpdate(); 758 pstmt.close(); 759 pstmt = null; 760 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_SECURABLE_OBJECTS WHERE ID=?" ); 761 pstmt.setInt( 1, role.getID() ); 762 pstmt.executeUpdate(); 763 pstmt.close(); 764 pstmt = null; 765 } catch ( SQLException e ) { 766 LOG.logError( e.getMessage(), e ); 767 closeStatement( pstmt ); 768 abortTransaction( transaction ); 769 throw new GeneralSecurityException( "SQLRegistry.deregisterRole() failed. Rollback performed. " 770 + "Error message: " + e.getMessage() ); 771 } 772 } 773 774 /** 775 * Retrieves a <code>Role</code> from the <code>Registry</code>. 776 * 777 * @param securityAccess 778 * @param name 779 * @throws GeneralSecurityException 780 * this is an <code>UnknownException</code> if the role is not known to the 781 * <code>Registry</code> 782 */ 783 public Role getRoleByName( SecurityAccess securityAccess, String name ) 784 throws GeneralSecurityException { 785 Role role = null; 786 Connection con = acquireLocalConnection( securityAccess ); 787 PreparedStatement pstmt = null; 788 ResultSet rs = null; 789 790 try { 791 pstmt = con.prepareStatement( "SELECT SEC_ROLES.ID " + "FROM SEC_ROLES,SEC_SECURABLE_OBJECTS " 792 + "WHERE SEC_ROLES.ID=SEC_SECURABLE_OBJECTS.ID AND " 793 + "SEC_SECURABLE_OBJECTS.NAME=?" ); 794 pstmt.setString( 1, name ); 795 rs = pstmt.executeQuery(); 796 if ( rs.next() ) { 797 role = new Role( rs.getInt( 1 ), name, this ); 798 } else { 799 throw new UnknownException( "Lookup of role '" + name 800 + "' failed! A role with this name does not exist." ); 801 } 802 } catch ( SQLException e ) { 803 LOG.logError( e.getMessage(), e ); 804 throw new GeneralSecurityException( e ); 805 } finally { 806 closeResultSet( rs ); 807 closeStatement( pstmt ); 808 releaseLocalConnection( securityAccess, con ); 809 } 810 return role; 811 } 812 813 /** 814 * Retrieves all <code>Roles</code> s from the <code>Registry</code> that have a certain 815 * namespace. 816 * 817 * @param securityAccess 818 * @param ns 819 * null for default namespace 820 * @throws GeneralSecurityException 821 */ 822 public Role[] getRolesByNS( SecurityAccess securityAccess, String ns ) 823 throws GeneralSecurityException { 824 ArrayList<Role> roles = new ArrayList<Role>( 100 ); 825 Connection con = acquireLocalConnection( securityAccess ); 826 PreparedStatement pstmt = null; 827 ResultSet rs = null; 828 try { 829 if ( ns != null && ( !ns.equals( "" ) ) ) { 830 pstmt = con.prepareStatement( "SELECT SEC_ROLES.ID,SEC_SECURABLE_OBJECTS.NAME " 831 + "FROM SEC_ROLES,SEC_SECURABLE_OBJECTS " 832 + "WHERE SEC_SECURABLE_OBJECTS.ID=SEC_ROLES.ID AND SEC_SECURABLE_OBJECTS.NAME LIKE ?" ); 833 pstmt.setString( 1, ns + ":%" ); 834 } else { 835 pstmt = con.prepareStatement( "SELECT SEC_ROLES.ID,SEC_SECURABLE_OBJECTS.NAME " 836 + "FROM SEC_ROLES,SEC_SECURABLE_OBJECTS " 837 + "WHERE SEC_SECURABLE_OBJECTS.ID=SEC_ROLES.ID AND " 838 + "SEC_SECURABLE_OBJECTS.NAME NOT LIKE '%:%'" ); 839 } 840 841 rs = pstmt.executeQuery(); 842 while ( rs.next() ) { 843 roles.add( new Role( rs.getInt( 1 ), rs.getString( 2 ), this ) ); 844 } 845 } catch ( SQLException e ) { 846 LOG.logError( e.getMessage(), e ); 847 throw new GeneralSecurityException( e ); 848 } finally { 849 closeResultSet( rs ); 850 closeStatement( pstmt ); 851 releaseLocalConnection( securityAccess, con ); 852 } 853 return roles.toArray( new Role[roles.size()] ); 854 } 855 856 /** 857 * Retrieves a <code>Role</code> from the <code>Registry</code>. 858 * 859 * @param securityAccess 860 * @param id 861 * @throws GeneralSecurityException 862 * this is an <code>UnknownException</code> if the role is not known to the 863 * <code>Registry</code> 864 */ 865 public Role getRoleById( SecurityAccess securityAccess, int id ) 866 throws GeneralSecurityException { 867 Role role = null; 868 Connection con = acquireLocalConnection( securityAccess ); 869 PreparedStatement pstmt = null; 870 ResultSet rs = null; 871 872 try { 873 pstmt = con.prepareStatement( "SELECT SEC_SECURABLE_OBJECTS.NAME " 874 + "FROM SEC_ROLES,SEC_SECURABLE_OBJECTS " 875 + "WHERE SEC_SECURABLE_OBJECTS.ID=? AND SEC_ROLES.ID=SEC_SECURABLE_OBJECTS.ID" ); 876 pstmt.setInt( 1, id ); 877 rs = pstmt.executeQuery(); 878 if ( rs.next() ) { 879 role = new Role( id, rs.getString( 1 ), this ); 880 } else { 881 throw new UnknownException( "Lookup of role with id: " + id 882 + " failed! A role with this id does not exist." ); 883 } 884 } catch ( SQLException e ) { 885 LOG.logError( e.getMessage(), e ); 886 throw new GeneralSecurityException( e ); 887 } finally { 888 closeResultSet( rs ); 889 closeStatement( pstmt ); 890 releaseLocalConnection( securityAccess, con ); 891 } 892 return role; 893 } 894 895 /** 896 * Retrieves all <code>Role</code> s from the <code>Registry</code>, except those that are 897 * only used internally (these have namespaces that begin with $). 898 * 899 * @param securityAccess 900 * @throws GeneralSecurityException 901 */ 902 public Role[] getAllRoles( SecurityAccess securityAccess ) 903 throws GeneralSecurityException { 904 ArrayList<Role> roles = new ArrayList<Role>( 50 ); 905 Connection con = acquireLocalConnection( securityAccess ); 906 PreparedStatement pstmt = null; 907 ResultSet rs = null; 908 909 try { 910 pstmt = con.prepareStatement( "SELECT SEC_ROLES.ID,SEC_SECURABLE_OBJECTS.NAME " 911 + "FROM SEC_ROLES,SEC_SECURABLE_OBJECTS " 912 + "WHERE SEC_ROLES.ID=SEC_SECURABLE_OBJECTS.ID AND " 913 + "SEC_SECURABLE_OBJECTS.NAME NOT LIKE '$%:%'" ); 914 rs = pstmt.executeQuery(); 915 while ( rs.next() ) { 916 roles.add( new Role( rs.getInt( 1 ), rs.getString( 2 ), this ) ); 917 } 918 } catch ( SQLException e ) { 919 LOG.logError( e.getMessage(), e ); 920 throw new GeneralSecurityException( e ); 921 } finally { 922 closeResultSet( rs ); 923 closeStatement( pstmt ); 924 releaseLocalConnection( securityAccess, con ); 925 } 926 return roles.toArray( new Role[roles.size()] ); 927 } 928 929 /** 930 * Adds a new <code>SecuredObject</code> to the <code>Registry</code>. 931 * 932 * @param transaction 933 * @param type 934 * @param name 935 * @param title 936 * @throws GeneralSecurityException 937 * this is a <code>DuplicateException</code> if the object already existed 938 */ 939 public SecuredObject registerSecuredObject( SecurityTransaction transaction, String type, String name, String title ) 940 throws GeneralSecurityException { 941 try { 942 getSecuredObjectByName( transaction, name, type ); 943 throw new DuplicateException( "Registration of secured object '" + name + "' with type '" + type 944 + "' failed! A secured object with this name and type " + "already exists." ); 945 } catch ( UnknownException e ) { 946 } 947 948 PreparedStatement pstmt = null; 949 SecuredObject object = null; 950 ResultSet rs = null; 951 952 try { 953 // check for ID of object type (add type if necessary) 954 int typeId = 0; 955 pstmt = transactionalConnection.prepareStatement( "SELECT ID FROM SEC_SECURED_OBJECT_TYPES WHERE NAME=?" ); 956 pstmt.setString( 1, type ); 957 rs = pstmt.executeQuery(); 958 if ( rs.next() ) { 959 typeId = rs.getInt( 1 ); 960 rs.close(); 961 rs = null; 962 pstmt.close(); 963 pstmt = null; 964 } else { 965 typeId = getID( transaction, "SEC_SECURED_OBJECT_TYPES" ); 966 rs.close(); 967 rs = null; 968 pstmt.close(); 969 pstmt = null; 970 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_SECURED_OBJECT_TYPES (ID,NAME) VALUES (?,?)" ); 971 pstmt.setInt( 1, typeId ); 972 pstmt.setString( 2, type ); 973 pstmt.executeUpdate(); 974 pstmt.close(); 975 pstmt = null; 976 } 977 978 // insert securable object part 979 object = new SecuredObject( getID( transaction, "SEC_SECURABLE_OBJECTS" ), typeId, name, title, this ); 980 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_SECURABLE_OBJECTS (ID,NAME,TITLE) VALUES (?,?,?)" ); 981 pstmt.setInt( 1, object.getID() ); 982 pstmt.setString( 2, object.getName() ); 983 pstmt.setString( 3, object.getTitle() ); 984 pstmt.executeUpdate(); 985 pstmt.close(); 986 pstmt = null; 987 988 // insert secured object 989 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_SECURED_OBJECTS (ID, FK_SECURED_OBJECT_TYPES) VALUES (?,?)" ); 990 pstmt.setInt( 1, object.getID() ); 991 pstmt.setInt( 2, typeId ); 992 pstmt.executeUpdate(); 993 pstmt.close(); 994 pstmt = null; 995 } catch ( SQLException e ) { 996 LOG.logError( e.getMessage(), e ); 997 closeResultSet( rs ); 998 closeStatement( pstmt ); 999 abortTransaction( transaction ); 1000 throw new GeneralSecurityException( "SQLRegistry.registerSecuredObject() failed. Rollback performed. " 1001 + "Error message: " + e.getMessage() ); 1002 } 1003 return object; 1004 } 1005 1006 /** 1007 * Removes an existing <code>SecuredObject</code> from the <code>Registry</code> (including 1008 * its associations). 1009 * 1010 * @param transaction 1011 * @param object 1012 * @throws GeneralSecurityException 1013 */ 1014 public void deregisterSecuredObject( SecurityTransaction transaction, SecuredObject object ) 1015 throws GeneralSecurityException { 1016 PreparedStatement pstmt = null; 1017 1018 try { 1019 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_SECURED_OBJECTS WHERE ID=?" ); 1020 pstmt.setInt( 1, object.getID() ); 1021 pstmt.executeUpdate(); 1022 pstmt.close(); 1023 pstmt = null; 1024 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_SECURABLE_OBJECTS=?" ); 1025 pstmt.setInt( 1, object.getID() ); 1026 pstmt.executeUpdate(); 1027 pstmt.close(); 1028 pstmt = null; 1029 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_SECURABLE_OBJECTS WHERE ID=?" ); 1030 pstmt.setInt( 1, object.getID() ); 1031 pstmt.executeUpdate(); 1032 pstmt = null; 1033 } catch ( SQLException e ) { 1034 LOG.logError( e.getMessage(), e ); 1035 closeStatement( pstmt ); 1036 abortTransaction( transaction ); 1037 throw new GeneralSecurityException( "SQLRegistry.deregisterSecuredObject() failed. Rollback performed. " 1038 + "Error message: " + e.getMessage() ); 1039 } 1040 } 1041 1042 /** 1043 * Retrieves a <code>SecuredObject</code> from the <code>Registry</code>. 1044 * 1045 * @param securityAccess 1046 * @param name 1047 * @throws GeneralSecurityException 1048 * this is an <code>UnknownException</code> if the object is not known to the 1049 * <code>Registry</code> 1050 */ 1051 public SecuredObject getSecuredObjectByName( SecurityAccess securityAccess, String name, String type ) 1052 throws GeneralSecurityException { 1053 SecuredObject object = null; 1054 Connection con = acquireLocalConnection( securityAccess ); 1055 PreparedStatement pstmt = null; 1056 ResultSet rs = null; 1057 1058 try { 1059 pstmt = con.prepareStatement( "SELECT SEC_SECURED_OBJECTS.ID,SEC_SECURED_OBJECT_TYPES.ID, " 1060 + "SEC_SECURABLE_OBJECTS.TITLE " 1061 + "FROM SEC_SECURED_OBJECTS,SEC_SECURED_OBJECT_TYPES,SEC_SECURABLE_OBJECTS " 1062 + "WHERE SEC_SECURED_OBJECTS.FK_SECURED_OBJECT_TYPES=SEC_SECURED_OBJECT_TYPES.ID AND " 1063 + "SEC_SECURED_OBJECTS.ID=SEC_SECURABLE_OBJECTS.ID AND SEC_SECURABLE_OBJECTS.NAME LIKE ? AND " 1064 + "SEC_SECURED_OBJECT_TYPES.NAME=?" ); 1065 pstmt.setString( 1, name ); 1066 pstmt.setString( 2, type ); 1067 rs = pstmt.executeQuery(); 1068 if ( rs.next() ) { 1069 object = new SecuredObject( rs.getInt( 1 ), rs.getInt( 2 ), name, rs.getString( 3 ), this ); 1070 } else { 1071 throw new UnknownException( "Lookup of secured object '" + name + "' with type '" + type 1072 + "' failed! A secured object with this " + "name and type does not exist." ); 1073 } 1074 } catch ( SQLException e ) { 1075 LOG.logError( e.getMessage(), e ); 1076 throw new GeneralSecurityException( e ); 1077 } finally { 1078 closeResultSet( rs ); 1079 closeStatement( pstmt ); 1080 releaseLocalConnection( securityAccess, con ); 1081 } 1082 return object; 1083 } 1084 1085 /** 1086 * Retrieves a <code>SecuredObject</code> from the <code>Registry</code>. 1087 * 1088 * @param securityAccess 1089 * @param id 1090 * @throws GeneralSecurityException 1091 * this is an <code>UnknownException</code> if the object is not known to the 1092 * <code>Registry</code> 1093 */ 1094 public SecuredObject getSecuredObjectById( SecurityAccess securityAccess, int id ) 1095 throws GeneralSecurityException { 1096 SecuredObject object = null; 1097 Connection con = acquireLocalConnection( securityAccess ); 1098 PreparedStatement pstmt = null; 1099 ResultSet rs = null; 1100 1101 try { 1102 pstmt = con.prepareStatement( "SELECT SEC_SECURED_OBJECTS.FK_SECURED_OBJECT_TYPES,SEC_SECURABLE_OBJECTS.NAME," 1103 + "SEC_SECURABLE_OBJECTS.TITLE " 1104 + "FROM SEC_SECURED_OBJECTS,SEC_SECURABLE_OBJECTS " 1105 + "WHERE SEC_SECURED_OBJECTS.ID=SEC_SECURABLE_OBJECTS.ID AND SEC_SECURABLE_OBJECTS.ID=?" ); 1106 pstmt.setInt( 1, id ); 1107 rs = pstmt.executeQuery(); 1108 if ( rs.next() ) { 1109 object = new SecuredObject( id, rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), this ); 1110 } else { 1111 throw new UnknownException( "Lookup of secured object with id: " + id 1112 + " failed! A secured object with this id does not exist." ); 1113 } 1114 } catch ( SQLException e ) { 1115 LOG.logError( e.getMessage(), e ); 1116 throw new GeneralSecurityException( e ); 1117 } finally { 1118 closeResultSet( rs ); 1119 closeStatement( pstmt ); 1120 releaseLocalConnection( securityAccess, con ); 1121 } 1122 return object; 1123 } 1124 1125 /** 1126 * Retrieves all <code>SecuredObject</code> s from the <code>Registry</code> that have a 1127 * certain namespace. 1128 * 1129 * @param securityAccess 1130 * @param ns 1131 * null for default namespace 1132 * @param type 1133 * @throws GeneralSecurityException 1134 */ 1135 public SecuredObject[] getSecuredObjectsByNS( SecurityAccess securityAccess, String ns, String type ) 1136 throws GeneralSecurityException { 1137 ArrayList<SecuredObject> objects = new ArrayList<SecuredObject>( 100 ); 1138 Connection con = acquireLocalConnection( securityAccess ); 1139 PreparedStatement pstmt = null; 1140 ResultSet rs = null; 1141 try { 1142 if ( ns != null && ( !ns.equals( "" ) ) ) { 1143 pstmt = con.prepareStatement( "SELECT SEC_SECURED_OBJECTS.ID,SEC_SECURED_OBJECT_TYPES.ID, " 1144 + "SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1145 + "FROM SEC_SECURED_OBJECTS,SEC_SECURED_OBJECT_TYPES,SEC_SECURABLE_OBJECTS " 1146 + "WHERE SEC_SECURED_OBJECTS.FK_SECURED_OBJECT_TYPES=SEC_SECURED_OBJECT_TYPES.ID AND " 1147 + "SEC_SECURABLE_OBJECTS.ID=SEC_SECURED_OBJECTS.ID AND SEC_SECURED_OBJECT_TYPES.NAME=? " 1148 + "AND SEC_SECURABLE_OBJECTS.NAME LIKE ?" ); 1149 pstmt.setString( 1, type ); 1150 pstmt.setString( 2, ns + ":%" ); 1151 } else { 1152 pstmt = con.prepareStatement( "SELECT SEC_SECURED_OBJECTS.ID,SEC_SECURED_OBJECT_TYPES.ID, " 1153 + "SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1154 + "FROM SEC_SECURED_OBJECTS,SEC_SECURED_OBJECT_TYPES,SEC_SECURABLE_OBJECTS " 1155 + "WHERE SEC_SECURED_OBJECTS.FK_SECURED_OBJECT_TYPES=SEC_SECURED_OBJECT_TYPES.ID AND " 1156 + "SEC_SECURABLE_OBJECTS.ID=SEC_SECURED_OBJECTS.ID AND SEC_SECURED_OBJECT_TYPES.NAME=? " 1157 + "AND SEC_SECURABLE_OBJECTS.NAME NOT LIKE '%:%'" ); 1158 pstmt.setString( 1, type ); 1159 } 1160 rs = pstmt.executeQuery(); 1161 while ( rs.next() ) { 1162 objects.add( new SecuredObject( rs.getInt( 1 ), rs.getInt( 2 ), rs.getString( 3 ), rs.getString( 4 ), 1163 this ) ); 1164 } 1165 } catch ( SQLException e ) { 1166 LOG.logError( e.getMessage(), e ); 1167 throw new GeneralSecurityException( e ); 1168 } finally { 1169 closeResultSet( rs ); 1170 closeStatement( pstmt ); 1171 releaseLocalConnection( securityAccess, con ); 1172 } 1173 return objects.toArray( new SecuredObject[objects.size()] ); 1174 } 1175 1176 /** 1177 * Retrieves all <code>SecuredObject</code> s with the given type from the 1178 * <code>Registry</code>. 1179 * 1180 * @param securityAccess 1181 * @param type 1182 * @throws GeneralSecurityException 1183 */ 1184 public SecuredObject[] getAllSecuredObjects( SecurityAccess securityAccess, String type ) 1185 throws GeneralSecurityException { 1186 ArrayList<SecuredObject> objects = new ArrayList<SecuredObject>( 100 ); 1187 Connection con = acquireLocalConnection( securityAccess ); 1188 PreparedStatement pstmt = null; 1189 ResultSet rs = null; 1190 1191 try { 1192 pstmt = con.prepareStatement( "SELECT SEC_SECURED_OBJECTS.ID,SEC_SECURED_OBJECT_TYPES.ID, " 1193 + "SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1194 + "FROM SEC_SECURED_OBJECTS,SEC_SECURED_OBJECT_TYPES,SEC_SECURABLE_OBJECTS " 1195 + "WHERE SEC_SECURED_OBJECTS.FK_SECURED_OBJECT_TYPES=SEC_SECURED_OBJECT_TYPES.ID AND " 1196 + "SEC_SECURABLE_OBJECTS.ID=SEC_SECURED_OBJECTS.ID AND SEC_SECURED_OBJECT_TYPES.NAME=?" ); 1197 pstmt.setString( 1, type ); 1198 rs = pstmt.executeQuery(); 1199 while ( rs.next() ) { 1200 objects.add( new SecuredObject( rs.getInt( 1 ), rs.getInt( 2 ), rs.getString( 3 ), rs.getString( 4 ), 1201 this ) ); 1202 } 1203 } catch ( SQLException e ) { 1204 LOG.logError( e.getMessage(), e ); 1205 throw new GeneralSecurityException( e ); 1206 } finally { 1207 closeResultSet( rs ); 1208 closeStatement( pstmt ); 1209 releaseLocalConnection( securityAccess, con ); 1210 } 1211 return objects.toArray( new SecuredObject[objects.size()] ); 1212 } 1213 1214 /** 1215 * Adds a new <code>Privilege</code> to the <code>Registry</code>. 1216 * 1217 * @param transaction 1218 * @param name 1219 * @throws GeneralSecurityException 1220 * this is a <code>DuplicateException</code> if the <code>Privilege</code> 1221 * already existed 1222 */ 1223 public Privilege registerPrivilege( SecurityTransaction transaction, String name ) 1224 throws GeneralSecurityException { 1225 try { 1226 getPrivilegeByName( transaction, name ); 1227 throw new DuplicateException( "Registration of privilege '" + name + "' failed! A privilege with " 1228 + "this name already exists." ); 1229 } catch ( UnknownException e ) { 1230 } 1231 1232 int id = getID( transaction, "SEC_PRIVILEGES" ); 1233 Privilege privilege = new Privilege( id, name ); 1234 PreparedStatement pstmt = null; 1235 1236 try { 1237 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_PRIVILEGES (ID, NAME) VALUES (?,?)" ); 1238 pstmt.setInt( 1, id ); 1239 pstmt.setString( 2, name ); 1240 pstmt.executeUpdate(); 1241 pstmt.close(); 1242 } catch ( SQLException e ) { 1243 LOG.logError( e.getMessage(), e ); 1244 closeStatement( pstmt ); 1245 abortTransaction( transaction ); 1246 throw new GeneralSecurityException( "SQLRegistry.registerPrivilege() failed. Rollback performed. " 1247 + "Error message: " + e.getMessage() ); 1248 } 1249 return privilege; 1250 } 1251 1252 /** 1253 * Removes an existing</code> Privilege</code> from the <code>Registry </code> (including its 1254 * relations). 1255 * 1256 * @param transaction 1257 * @param privilege 1258 * @throws GeneralSecurityException 1259 */ 1260 public void deregisterPrivilege( SecurityTransaction transaction, Privilege privilege ) 1261 throws GeneralSecurityException { 1262 PreparedStatement pstmt = null; 1263 1264 try { 1265 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_PRIVILEGES WHERE FK_PRIVILEGES=?" ); 1266 pstmt.setInt( 1, privilege.getID() ); 1267 pstmt.executeUpdate(); 1268 pstmt.close(); 1269 pstmt = null; 1270 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_PRIVILEGES WHERE ID=?" ); 1271 pstmt.setInt( 1, privilege.getID() ); 1272 pstmt.executeUpdate(); 1273 pstmt.close(); 1274 } catch ( SQLException e ) { 1275 LOG.logError( e.getMessage(), e ); 1276 closeStatement( pstmt ); 1277 abortTransaction( transaction ); 1278 throw new GeneralSecurityException( "SQLRegistry.deregisterPrivilege() failed. Rollback performed. " 1279 + "Error message: " + e.getMessage() ); 1280 } 1281 } 1282 1283 /** 1284 * Retrieves a <code>Privilege</code> from the <code>Registry</code>. 1285 * 1286 * @param securityAccess 1287 * @param name 1288 * @throws GeneralSecurityException 1289 * this is an <code>UnknownException</code> if the privilege is not known to the 1290 * <code>Registry</code> 1291 */ 1292 public Privilege getPrivilegeByName( SecurityAccess securityAccess, String name ) 1293 throws GeneralSecurityException { 1294 Privilege privilege = null; 1295 Connection con = acquireLocalConnection( securityAccess ); 1296 PreparedStatement pstmt = null; 1297 ResultSet rs = null; 1298 1299 try { 1300 pstmt = con.prepareStatement( "SELECT ID FROM SEC_PRIVILEGES WHERE NAME=?" ); 1301 pstmt.setString( 1, name ); 1302 rs = pstmt.executeQuery(); 1303 if ( rs.next() ) { 1304 privilege = new Privilege( rs.getInt( 1 ), name ); 1305 } else { 1306 throw new UnknownException( "Lookup of privilege '" + name 1307 + "' failed! A privilege with this name does not exist." ); 1308 } 1309 } catch ( SQLException e ) { 1310 LOG.logError( e.getMessage(), e ); 1311 throw new GeneralSecurityException( e ); 1312 } finally { 1313 closeResultSet( rs ); 1314 closeStatement( pstmt ); 1315 releaseLocalConnection( securityAccess, con ); 1316 } 1317 return privilege; 1318 } 1319 1320 /** 1321 * Retrieves all <code>Privileges</code> s from the <code>Registry</code> that are 1322 * associated DIRECTLY (i.e. not via group memberships) with a given <code>Role</code>. 1323 * 1324 * @param securityAccess 1325 * @param role 1326 * @throws GeneralSecurityException 1327 */ 1328 public Privilege[] getPrivilegesForRole( SecurityAccess securityAccess, Role role ) 1329 throws GeneralSecurityException { 1330 ArrayList<Privilege> privileges = new ArrayList<Privilege>(); 1331 Connection con = acquireLocalConnection( securityAccess ); 1332 PreparedStatement pstmt = null; 1333 ResultSet rs = null; 1334 1335 try { 1336 pstmt = con.prepareStatement( "SELECT SEC_PRIVILEGES.ID,SEC_PRIVILEGES.NAME " 1337 + "FROM SEC_JT_ROLES_PRIVILEGES, SEC_PRIVILEGES WHERE " 1338 + "SEC_JT_ROLES_PRIVILEGES.FK_ROLES=? AND " 1339 + "SEC_JT_ROLES_PRIVILEGES.FK_PRIVILEGES=SEC_PRIVILEGES.ID" ); 1340 pstmt.setInt( 1, role.getID() ); 1341 rs = pstmt.executeQuery(); 1342 while ( rs.next() ) { 1343 privileges.add( new Privilege( rs.getInt( 1 ), rs.getString( 2 ) ) ); 1344 } 1345 } catch ( SQLException e ) { 1346 LOG.logError( e.getMessage(), e ); 1347 throw new GeneralSecurityException( e ); 1348 } finally { 1349 closeResultSet( rs ); 1350 closeStatement( pstmt ); 1351 releaseLocalConnection( securityAccess, con ); 1352 } 1353 return privileges.toArray( new Privilege[privileges.size()] ); 1354 } 1355 1356 /** 1357 * Sets all <code>Privilege</code> s that are associated with a given <code>Role</code>. 1358 * 1359 * @param transaction 1360 * @param role 1361 * @param privileges 1362 * @throws GeneralSecurityException 1363 */ 1364 public void setPrivilegesForRole( SecurityTransaction transaction, Role role, Privilege[] privileges ) 1365 throws GeneralSecurityException { 1366 PreparedStatement pstmt = null; 1367 1368 try { 1369 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_PRIVILEGES WHERE FK_ROLES=?" ); 1370 pstmt.setInt( 1, role.getID() ); 1371 pstmt.executeUpdate(); 1372 pstmt.close(); 1373 pstmt = null; 1374 1375 for ( int i = 0; i < privileges.length; i++ ) { 1376 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_ROLES_PRIVILEGES (FK_ROLES, FK_PRIVILEGES) VALUES (?,?)" ); 1377 pstmt.setInt( 1, role.getID() ); 1378 pstmt.setInt( 2, privileges[i].getID() ); 1379 pstmt.executeUpdate(); 1380 pstmt.close(); 1381 pstmt = null; 1382 } 1383 } catch ( SQLException e ) { 1384 LOG.logError( e.getMessage(), e ); 1385 closeStatement( pstmt ); 1386 abortTransaction( transaction ); 1387 throw new GeneralSecurityException( "SQLRegistry.setPrivilegesForRols() failed. Rollback performed. " 1388 + "Error message: " + e.getMessage() ); 1389 } 1390 } 1391 1392 /** 1393 * Adds a new <code>Right</code> to the <code>Registry</code>. 1394 * 1395 * @param transaction 1396 * @param name 1397 * @throws GeneralSecurityException 1398 * this is a <code>DuplicateException</code> if the <code>Right</code> already 1399 * existed 1400 */ 1401 public RightType registerRightType( SecurityTransaction transaction, String name ) 1402 throws GeneralSecurityException { 1403 try { 1404 getRightTypeByName( transaction, name ); 1405 throw new DuplicateException( "Registration of right '" + name + "' failed! A right with " 1406 + "this name already exists." ); 1407 } catch ( UnknownException e ) { 1408 } 1409 1410 int id = getID( transaction, "SEC_RIGHTS" ); 1411 RightType right = new RightType( id, name ); 1412 PreparedStatement pstmt = null; 1413 1414 try { 1415 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_RIGHTS (ID, NAME) VALUES (?,?)" ); 1416 pstmt.setInt( 1, id ); 1417 pstmt.setString( 2, name ); 1418 pstmt.executeUpdate(); 1419 pstmt.close(); 1420 } catch ( SQLException e ) { 1421 LOG.logError( e.getMessage(), e ); 1422 closeStatement( pstmt ); 1423 abortTransaction( transaction ); 1424 throw new GeneralSecurityException( "SQLRegistry.registerRight() failed. Rollback " 1425 + "performed. Error message: " + e.getMessage() ); 1426 } 1427 return right; 1428 } 1429 1430 /** 1431 * Removes an existing <code>RightType</code> from the <code>Registry</code> (including its 1432 * relations). 1433 * 1434 * @param transaction 1435 * @param type 1436 * @throws GeneralSecurityException 1437 */ 1438 public void deregisterRightType( SecurityTransaction transaction, RightType type ) 1439 throws GeneralSecurityException { 1440 PreparedStatement pstmt = null; 1441 1442 try { 1443 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_RIGHTS=?" ); 1444 pstmt.setInt( 1, type.getID() ); 1445 pstmt.executeUpdate(); 1446 pstmt.close(); 1447 pstmt = null; 1448 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_RIGHTS WHERE ID=?" ); 1449 pstmt.setInt( 1, type.getID() ); 1450 pstmt.executeUpdate(); 1451 pstmt.close(); 1452 } catch ( SQLException e ) { 1453 LOG.logError( e.getMessage(), e ); 1454 closeStatement( pstmt ); 1455 abortTransaction( transaction ); 1456 throw new GeneralSecurityException( "SQLRegistry.deregisterRight() failed. Rollback performed. " 1457 + "Error message: " + e.getMessage() ); 1458 } 1459 } 1460 1461 /** 1462 * Retrieves a <code>Right</code> from the <code>Registry</code>. 1463 * 1464 * @param securityAccess 1465 * @param name 1466 * @throws GeneralSecurityException 1467 * this is an <code>UnknownException</code> if the <code>Right</code> is not 1468 * known to the <code>Registry</code> 1469 */ 1470 public RightType getRightTypeByName( SecurityAccess securityAccess, String name ) 1471 throws GeneralSecurityException { 1472 RightType right = null; 1473 Connection con = acquireLocalConnection( securityAccess ); 1474 PreparedStatement pstmt = null; 1475 ResultSet rs = null; 1476 1477 try { 1478 pstmt = con.prepareStatement( "SELECT ID FROM SEC_RIGHTS WHERE NAME=?" ); 1479 pstmt.setString( 1, name ); 1480 rs = pstmt.executeQuery(); 1481 if ( rs.next() ) { 1482 right = new RightType( rs.getInt( 1 ), name ); 1483 } else { 1484 throw new UnknownException( "Lookup of right '" + name 1485 + "' failed! A right with this name does not exist." ); 1486 } 1487 } catch ( SQLException e ) { 1488 LOG.logError( e.getMessage(), e ); 1489 throw new GeneralSecurityException( e ); 1490 } finally { 1491 closeResultSet( rs ); 1492 closeStatement( pstmt ); 1493 releaseLocalConnection( securityAccess, con ); 1494 } 1495 return right; 1496 } 1497 1498 /** 1499 * Retrieves the <code>Rights</code> from the <code>Registry</code> that are associated with 1500 * a given <code>Role</code> and a <code>SecurableObject</code>. 1501 * 1502 * @param securityAccess 1503 * @param object 1504 * @param role 1505 * @throws GeneralSecurityException 1506 */ 1507 public Right[] getRights( SecurityAccess securityAccess, SecurableObject object, Role role ) 1508 throws GeneralSecurityException { 1509 ArrayList<Right> rights = new ArrayList<Right>(); 1510 Connection con = acquireLocalConnection( securityAccess ); 1511 PreparedStatement pstmt = null; 1512 ResultSet rs = null; 1513 1514 try { 1515 pstmt = con.prepareStatement( "SELECT SEC_RIGHTS.ID,SEC_RIGHTS.NAME," 1516 + "SEC_JT_ROLES_SECOBJECTS.CONSTRAINTS FROM SEC_JT_ROLES_SECOBJECTS," 1517 + "SEC_RIGHTS WHERE SEC_JT_ROLES_SECOBJECTS.FK_ROLES=? AND " 1518 + "SEC_JT_ROLES_SECOBJECTS.FK_SECURABLE_OBJECTS=? AND " 1519 + "SEC_JT_ROLES_SECOBJECTS.FK_RIGHTS=SEC_RIGHTS.ID" ); 1520 pstmt.setInt( 1, role.getID() ); 1521 pstmt.setInt( 2, object.getID() ); 1522 rs = pstmt.executeQuery(); 1523 ResultSetMetaData metadata = rs.getMetaData(); 1524 int constraintType = metadata.getColumnType( 3 ); 1525 1526 while ( rs.next() ) { 1527 Right right = null; 1528 RightType type = new RightType( rs.getInt( 1 ), rs.getString( 2 ) ); 1529 String constraints = null; 1530 Object o = rs.getObject( 3 ); 1531 if ( o != null ) { 1532 if ( constraintType == Types.CLOB ) { 1533 Reader reader = ( (Clob) o ).getCharacterStream(); 1534 StringBuffer sb = new StringBuffer( 2000 ); 1535 int c; 1536 try { 1537 while ( ( c = reader.read() ) > -1 ) { 1538 sb.append( (char) c ); 1539 } 1540 reader.close(); 1541 } catch ( IOException e ) { 1542 throw new GeneralSecurityException( "Error converting CLOB to constraint string: " 1543 + e.getMessage() ); 1544 } 1545 constraints = sb.toString(); 1546 } else { 1547 constraints = o.toString(); 1548 } 1549 } 1550 1551 // check if the right has constraints 1552 if ( constraints != null && constraints.length() > 3 ) { 1553 right = new Right( object, type, buildFilter( constraints ) ); 1554 } else { 1555 right = new Right( object, type, null ); 1556 } 1557 1558 rights.add( right ); 1559 } 1560 } catch ( SQLException e ) { 1561 LOG.logError( e.getMessage(), e ); 1562 throw new GeneralSecurityException( e ); 1563 } finally { 1564 closeResultSet( rs ); 1565 closeStatement( pstmt ); 1566 releaseLocalConnection( securityAccess, con ); 1567 } 1568 return rights.toArray( new Right[rights.size()] ); 1569 } 1570 1571 /** 1572 * Sets the <code>Rights</code> to be associated with a given <code>Role</code> and 1573 * <code>SecurableObject</code>. 1574 * 1575 * @param transaction 1576 * @param object 1577 * @param role 1578 * @param rights 1579 * @throws GeneralSecurityException 1580 */ 1581 public void setRights( SecurityTransaction transaction, SecurableObject object, Role role, Right[] rights ) 1582 throws GeneralSecurityException { 1583 PreparedStatement pstmt = null; 1584 1585 try { 1586 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_ROLES=? AND FK_SECURABLE_OBJECTS=?" ); 1587 pstmt.setInt( 1, role.getID() ); 1588 pstmt.setInt( 2, object.getID() ); 1589 pstmt.executeUpdate(); 1590 pstmt.close(); 1591 1592 for ( int i = 0; i < rights.length; i++ ) { 1593 1594 String constraints = null; 1595 if ( rights[i].getConstraints() != null ) { 1596 constraints = rights[i].getConstraints().toXML().toString(); 1597 } 1598 LOG.logDebug( "constraints to add: ", constraints ); 1599 if ( transactionalConnection instanceof OracleConnection ) { 1600 handleOracle( object, role, rights[i], constraints ); 1601 } else { 1602 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_ROLES_SECOBJECTS (FK_ROLES, FK_SECURABLE_OBJECTS, FK_RIGHTS,CONSTRAINTS) VALUES (?,?,?,?)" ); 1603 pstmt.setInt( 1, role.getID() ); 1604 pstmt.setInt( 2, object.getID() ); 1605 pstmt.setInt( 3, rights[i].getType().getID() ); 1606 pstmt.setString( 4, constraints ); 1607 pstmt.executeUpdate(); 1608 pstmt.close(); 1609 } 1610 1611 } 1612 } catch ( SQLException e ) { 1613 LOG.logError( e.getMessage(), e ); 1614 closeStatement( pstmt ); 1615 abortTransaction( transaction ); 1616 throw new GeneralSecurityException( "SQLRegistry.setRights() failed. Rollback performed. " 1617 + "Error message: " + e.getMessage() ); 1618 } 1619 } 1620 1621 private void handleOracle( SecurableObject object, Role role, Right right, String constraints ) 1622 throws SQLException { 1623 1624 PreparedStatement pstmt; 1625 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_ROLES_SECOBJECTS (FK_ROLES, FK_SECURABLE_OBJECTS, FK_RIGHTS, CONSTRAINTS) VALUES (?,?,?, EMPTY_CLOB() )" ); 1626 pstmt.setInt( 1, role.getID() ); 1627 pstmt.setInt( 2, object.getID() ); 1628 pstmt.setInt( 3, right.getType().getID() ); 1629 pstmt.executeUpdate(); 1630 pstmt.close(); 1631 transactionalConnection.commit(); 1632 1633 if ( constraints != null ) { 1634 pstmt = transactionalConnection.prepareStatement( "select CONSTRAINTS from SEC_JT_ROLES_SECOBJECTS where FK_ROLES = ? and FK_SECURABLE_OBJECTS = ? and FK_RIGHTS = ? FOR UPDATE" ); 1635 pstmt.setInt( 1, role.getID() ); 1636 pstmt.setInt( 2, object.getID() ); 1637 pstmt.setInt( 3, right.getType().getID() ); 1638 ResultSet rs = pstmt.executeQuery(); 1639 rs.next(); 1640 1641 CLOB clob = (oracle.sql.CLOB) rs.getClob( 1 ); 1642 try { 1643 // clob.getAsciiOutputStream().write( constraints.getBytes() ); 1644 OutputStream os = clob.getAsciiOutputStream(); 1645 OutputStreamWriter osw = new OutputStreamWriter( os ); 1646 1647 // use that output stream to write character data to the Oracle data store 1648 osw.write( constraints.toCharArray() ); 1649 // write data and commit 1650 osw.flush(); 1651 osw.close(); 1652 os.close(); 1653 } catch ( IOException e ) { 1654 e.printStackTrace(); 1655 } 1656 } 1657 pstmt.close(); 1658 } 1659 1660 /** 1661 * Sets one <code>Right</code> to be associated with a given <code>Role</code> and all given 1662 * <code>SecurableObjects</code>. 1663 * 1664 * @param transaction 1665 * @param objects 1666 * @param role 1667 * @param right 1668 * @throws GeneralSecurityException 1669 */ 1670 public void setRights( SecurityTransaction transaction, SecurableObject[] objects, Role role, Right right ) 1671 throws GeneralSecurityException { 1672 PreparedStatement pstmt = null; 1673 1674 try { 1675 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_ROLES_SECOBJECTS WHERE FK_ROLES=? AND FK_RIGHTS=?" ); 1676 pstmt.setInt( 1, role.getID() ); 1677 pstmt.setInt( 2, right.getType().getID() ); 1678 pstmt.executeUpdate(); 1679 pstmt.close(); 1680 pstmt = null; 1681 1682 for ( int i = 0; i < objects.length; i++ ) { 1683 String constraints = null; 1684 if ( right.getConstraints() != null ) { 1685 constraints = right.getConstraints().toXML().toString(); 1686 } 1687 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_ROLES_SECOBJECTS (FK_ROLES, FK_SECURABLE_OBJECTS, FK_RIGHTS, CONSTRAINTS) VALUES (?,?,?,?)" ); 1688 pstmt.setInt( 1, role.getID() ); 1689 pstmt.setInt( 2, objects[i].getID() ); 1690 pstmt.setInt( 3, right.getType().getID() ); 1691 pstmt.setString( 4, constraints ); 1692 pstmt.executeUpdate(); 1693 pstmt.close(); 1694 pstmt = null; 1695 } 1696 } catch ( SQLException e ) { 1697 closeStatement( pstmt ); 1698 abortTransaction( transaction ); 1699 throw new GeneralSecurityException( "SQLRegistry.setRights() failed. Rollback performed. " 1700 + "Error message: " + e.getMessage() ); 1701 } 1702 } 1703 1704 /** 1705 * Retrieves all <code>Group</code> s from the <code>Registry</code> that the given 1706 * <code>User</code> is a DIRECT (i.e. not via inheritance) member of. 1707 * 1708 * @param securityAccess 1709 * @param user 1710 * @throws GeneralSecurityException 1711 */ 1712 public Group[] getGroupsForUser( SecurityAccess securityAccess, User user ) 1713 throws GeneralSecurityException { 1714 ArrayList<Group> groups = new ArrayList<Group>( 100 ); 1715 Connection con = acquireLocalConnection( securityAccess ); 1716 PreparedStatement pstmt = null; 1717 ResultSet rs = null; 1718 1719 try { 1720 pstmt = con.prepareStatement( "SELECT SEC_GROUPS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1721 + "FROM SEC_SECURABLE_OBJECTS,SEC_GROUPS,SEC_JT_USERS_GROUPS WHERE " 1722 + "SEC_SECURABLE_OBJECTS.ID=SEC_GROUPS.ID AND " 1723 + "SEC_JT_USERS_GROUPS.FK_GROUPS=SEC_GROUPS.ID AND " 1724 + "SEC_JT_USERS_GROUPS.FK_USERS=?" ); 1725 pstmt.setInt( 1, user.getID() ); 1726 rs = pstmt.executeQuery(); 1727 while ( rs.next() ) { 1728 groups.add( new Group( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), this ) ); 1729 } 1730 } catch ( SQLException e ) { 1731 throw new GeneralSecurityException( e ); 1732 } finally { 1733 closeResultSet( rs ); 1734 closeStatement( pstmt ); 1735 releaseLocalConnection( securityAccess, con ); 1736 } 1737 return groups.toArray( new Group[groups.size()] ); 1738 } 1739 1740 /** 1741 * Retrieves all <code>Groups</code> s from the <code>Registry</code> that are members of 1742 * another <code>Group</code> DIRECTLY (i.e. not via inheritance). 1743 * 1744 * @param securityAccess 1745 * @param group 1746 * @throws GeneralSecurityException 1747 */ 1748 public Group[] getGroupsInGroup( SecurityAccess securityAccess, Group group ) 1749 throws GeneralSecurityException { 1750 ArrayList<Group> groups = new ArrayList<Group>( 100 ); 1751 Connection con = acquireLocalConnection( securityAccess ); 1752 PreparedStatement pstmt = null; 1753 ResultSet rs = null; 1754 1755 try { 1756 pstmt = con.prepareStatement( "SELECT SEC_GROUPS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1757 + "FROM SEC_GROUPS,SEC_SECURABLE_OBJECTS,SEC_JT_GROUPS_GROUPS " 1758 + "WHERE SEC_SECURABLE_OBJECTS.ID=SEC_GROUPS.ID" 1759 + " AND SEC_JT_GROUPS_GROUPS.FK_GROUPS_MEMBER=SEC_GROUPS.ID" 1760 + " AND SEC_JT_GROUPS_GROUPS.FK_GROUPS=?" ); 1761 pstmt.setInt( 1, group.getID() ); 1762 rs = pstmt.executeQuery(); 1763 while ( rs.next() ) { 1764 groups.add( new Group( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), this ) ); 1765 } 1766 } catch ( SQLException e ) { 1767 throw new GeneralSecurityException( e ); 1768 } finally { 1769 closeResultSet( rs ); 1770 closeStatement( pstmt ); 1771 releaseLocalConnection( securityAccess, con ); 1772 } 1773 return groups.toArray( new Group[groups.size()] ); 1774 } 1775 1776 /** 1777 * Retrieves all <code>Group</code> s from the <code>Registry</code> that the given 1778 * <code>Group</code> is a DIRECT member (i.e. not via inheritance) of. 1779 * 1780 * @param securityAccess 1781 * @param group 1782 * @throws GeneralSecurityException 1783 */ 1784 public Group[] getGroupsForGroup( SecurityAccess securityAccess, Group group ) 1785 throws GeneralSecurityException { 1786 ArrayList<Group> groups = new ArrayList<Group>( 100 ); 1787 Connection con = acquireLocalConnection( securityAccess ); 1788 PreparedStatement pstmt = null; 1789 ResultSet rs = null; 1790 1791 try { 1792 pstmt = con.prepareStatement( "SELECT SEC_GROUPS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1793 + "FROM SEC_SECURABLE_OBJECTS,SEC_GROUPS,SEC_JT_GROUPS_GROUPS WHERE " 1794 + "SEC_SECURABLE_OBJECTS.ID=SEC_GROUPS.ID AND " 1795 + "SEC_JT_GROUPS_GROUPS.FK_GROUPS=SEC_GROUPS.ID AND " 1796 + "SEC_JT_GROUPS_GROUPS.FK_GROUPS_MEMBER=?" ); 1797 pstmt.setInt( 1, group.getID() ); 1798 rs = pstmt.executeQuery(); 1799 while ( rs.next() ) { 1800 groups.add( new Group( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), this ) ); 1801 } 1802 } catch ( SQLException e ) { 1803 throw new GeneralSecurityException( e ); 1804 } finally { 1805 closeResultSet( rs ); 1806 closeStatement( pstmt ); 1807 releaseLocalConnection( securityAccess, con ); 1808 } 1809 return groups.toArray( new Group[groups.size()] ); 1810 } 1811 1812 /** 1813 * Retrieves all <code>Group</code> s from the <code>Registry</code> that are associated 1814 * with a given <code>Role</code> DIRECTLY (i.e. not via inheritance). 1815 * 1816 * @param securityAccess 1817 * @param role 1818 * @throws GeneralSecurityException 1819 */ 1820 public Group[] getGroupsWithRole( SecurityAccess securityAccess, Role role ) 1821 throws GeneralSecurityException { 1822 ArrayList<Group> groups = new ArrayList<Group>( 100 ); 1823 Connection con = acquireLocalConnection( securityAccess ); 1824 PreparedStatement pstmt = null; 1825 ResultSet rs = null; 1826 1827 try { 1828 pstmt = con.prepareStatement( "SELECT SEC_GROUPS.ID,SEC_SECURABLE_OBJECTS.NAME,SEC_SECURABLE_OBJECTS.TITLE " 1829 + "FROM SEC_SECURABLE_OBJECTS,SEC_GROUPS,SEC_JT_GROUPS_ROLES WHERE " 1830 + "SEC_SECURABLE_OBJECTS.ID=SEC_GROUPS.ID AND " 1831 + "SEC_JT_GROUPS_ROLES.FK_GROUPS=SEC_GROUPS.ID AND " 1832 + "SEC_JT_GROUPS_ROLES.FK_ROLES=?" ); 1833 pstmt.setInt( 1, role.getID() ); 1834 rs = pstmt.executeQuery(); 1835 while ( rs.next() ) { 1836 groups.add( new Group( rs.getInt( 1 ), rs.getString( 2 ), rs.getString( 3 ), this ) ); 1837 } 1838 } catch ( SQLException e ) { 1839 throw new GeneralSecurityException( e ); 1840 } finally { 1841 closeResultSet( rs ); 1842 closeStatement( pstmt ); 1843 releaseLocalConnection( securityAccess, con ); 1844 } 1845 return groups.toArray( new Group[groups.size()] ); 1846 } 1847 1848 /** 1849 * Retrieves all <code>Role</code> s from the <code>Registry</code> that are associated with 1850 * a given <code>User</code> DIRECTLY (i.e. not via group memberships). 1851 * 1852 * @param securityAccess 1853 * @param user 1854 * @throws GeneralSecurityException 1855 */ 1856 public Role[] getRolesForUser( SecurityAccess securityAccess, User user ) 1857 throws GeneralSecurityException { 1858 ArrayList<Role> roles = new ArrayList<Role>( 100 ); 1859 Connection con = acquireLocalConnection( securityAccess ); 1860 PreparedStatement pstmt = null; 1861 ResultSet rs = null; 1862 1863 try { 1864 pstmt = con.prepareStatement( "SELECT SEC_ROLES.ID,SEC_SECURABLE_OBJECTS.NAME " 1865 + "FROM SEC_SECURABLE_OBJECTS,SEC_ROLES,SEC_JT_USERS_ROLES WHERE " 1866 + "SEC_SECURABLE_OBJECTS.ID=SEC_ROLES.ID AND SEC_JT_USERS_ROLES.FK_ROLES=SEC_ROLES.ID " 1867 + "AND SEC_JT_USERS_ROLES.FK_USERS=?" ); 1868 pstmt.setInt( 1, user.getID() ); 1869 rs = pstmt.executeQuery(); 1870 while ( rs.next() ) { 1871 roles.add( new Role( rs.getInt( 1 ), rs.getString( 2 ), this ) ); 1872 } 1873 } catch ( SQLException e ) { 1874 throw new GeneralSecurityException( e ); 1875 } finally { 1876 closeResultSet( rs ); 1877 closeStatement( pstmt ); 1878 releaseLocalConnection( securityAccess, con ); 1879 } 1880 return roles.toArray( new Role[roles.size()] ); 1881 } 1882 1883 /** 1884 * Retrieves all <code>Role</code> s from the <code>Registry</code> that are associated with 1885 * a given <code>Group</code> DIRECTLY (i.e. not via inheritance). 1886 * 1887 * @param securityAccess 1888 * @param group 1889 * @throws GeneralSecurityException 1890 */ 1891 public Role[] getRolesForGroup( SecurityAccess securityAccess, Group group ) 1892 throws GeneralSecurityException { 1893 ArrayList<Role> roles = new ArrayList<Role>( 100 ); 1894 Connection con = acquireLocalConnection( securityAccess ); 1895 PreparedStatement pstmt = null; 1896 ResultSet rs = null; 1897 1898 try { 1899 pstmt = con.prepareStatement( "SELECT SEC_ROLES.ID,SEC_SECURABLE_OBJECTS.NAME " 1900 + "FROM SEC_SECURABLE_OBJECTS,SEC_ROLES,SEC_JT_GROUPS_ROLES WHERE " 1901 + "SEC_SECURABLE_OBJECTS.ID=SEC_ROLES.ID AND SEC_JT_GROUPS_ROLES.FK_ROLES=SEC_ROLES.ID " 1902 + "AND SEC_JT_GROUPS_ROLES.FK_GROUPS=?" ); 1903 pstmt.setInt( 1, group.getID() ); 1904 rs = pstmt.executeQuery(); 1905 while ( rs.next() ) { 1906 roles.add( new Role( rs.getInt( 1 ), rs.getString( 2 ), this ) ); 1907 } 1908 } catch ( SQLException e ) { 1909 throw new GeneralSecurityException( e ); 1910 } finally { 1911 closeResultSet( rs ); 1912 closeStatement( pstmt ); 1913 releaseLocalConnection( securityAccess, con ); 1914 } 1915 return roles.toArray( new Role[roles.size()] ); 1916 } 1917 1918 /** 1919 * Sets the <code>Group</code> s that a given <code>User</code> is member of DIRECTLY (i.e. 1920 * not via inheritance). 1921 * 1922 * @param transaction 1923 * @param user 1924 * @param groups 1925 * @throws GeneralSecurityException 1926 */ 1927 public void setGroupsForUser( SecurityTransaction transaction, User user, Group[] groups ) 1928 throws GeneralSecurityException { 1929 PreparedStatement pstmt = null; 1930 1931 try { 1932 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_GROUPS WHERE FK_USERS=?" ); 1933 pstmt.setInt( 1, user.getID() ); 1934 pstmt.executeUpdate(); 1935 pstmt.close(); 1936 pstmt = null; 1937 1938 for ( int i = 0; i < groups.length; i++ ) { 1939 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_USERS_GROUPS (FK_USERS, FK_GROUPS) VALUES (?,?)" ); 1940 pstmt.setInt( 1, user.getID() ); 1941 pstmt.setInt( 2, groups[i].getID() ); 1942 pstmt.executeUpdate(); 1943 pstmt.close(); 1944 pstmt = null; 1945 } 1946 } catch ( SQLException e ) { 1947 closeStatement( pstmt ); 1948 abortTransaction( transaction ); 1949 throw new GeneralSecurityException( "SQLRegistry.setGroupsForUser() failed. Rollback performed. " 1950 + "Error message: " + e.getMessage() ); 1951 } 1952 } 1953 1954 /** 1955 * Sets the <code>Group</code> s that a given <code>Group</code> is member of DIRECTLY (i.e. 1956 * not via inheritance). 1957 * 1958 * @param transaction 1959 * @param group 1960 * @param groups 1961 * @throws GeneralSecurityException 1962 */ 1963 public void setGroupsForGroup( SecurityTransaction transaction, Group group, Group[] groups ) 1964 throws GeneralSecurityException { 1965 PreparedStatement pstmt = null; 1966 1967 try { 1968 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_GROUPS WHERE FK_GROUPS_MEMBER=?" ); 1969 pstmt.setInt( 1, group.getID() ); 1970 pstmt.executeUpdate(); 1971 pstmt.close(); 1972 pstmt = null; 1973 1974 for ( int i = 0; i < groups.length; i++ ) { 1975 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_GROUPS_GROUPS (FK_GROUPS_MEMBER, FK_GROUPS) VALUES (?,?)" ); 1976 pstmt.setInt( 1, group.getID() ); 1977 pstmt.setInt( 2, groups[i].getID() ); 1978 pstmt.executeUpdate(); 1979 pstmt.close(); 1980 pstmt = null; 1981 } 1982 } catch ( SQLException e ) { 1983 closeStatement( pstmt ); 1984 abortTransaction( transaction ); 1985 throw new GeneralSecurityException( "SQLRegistry.setGroupsForGroup() failed. Rollback performed. " 1986 + "Error message: " + e.getMessage() ); 1987 } 1988 } 1989 1990 /** 1991 * Sets the <code>Group</code> s that a given <code>Role</code> is associated to DIRECTLY 1992 * (i.e. not via inheritance). 1993 * 1994 * @param transaction 1995 * @param role 1996 * @param groups 1997 * @throws GeneralSecurityException 1998 */ 1999 public void setGroupsWithRole( SecurityTransaction transaction, Role role, Group[] groups ) 2000 throws GeneralSecurityException { 2001 PreparedStatement pstmt = null; 2002 2003 try { 2004 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_ROLES WHERE FK_ROLES=?" ); 2005 pstmt.setInt( 1, role.getID() ); 2006 pstmt.executeUpdate(); 2007 pstmt.close(); 2008 pstmt = null; 2009 2010 for ( int i = 0; i < groups.length; i++ ) { 2011 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_GROUPS_ROLES (FK_GROUPS, FK_ROLES) VALUES (?,?)" ); 2012 pstmt.setInt( 1, groups[i].getID() ); 2013 pstmt.setInt( 2, role.getID() ); 2014 pstmt.executeUpdate(); 2015 pstmt.close(); 2016 pstmt = null; 2017 } 2018 } catch ( SQLException e ) { 2019 closeStatement( pstmt ); 2020 abortTransaction( transaction ); 2021 throw new GeneralSecurityException( "SQLRegistry.setGroupsWithRole() failed. Rollback performed. " 2022 + "Error message: " + e.getMessage() ); 2023 } 2024 } 2025 2026 /** 2027 * Sets the <code>User</code> s that a given <code>Role</code> is associated to DIRECTLY 2028 * (i.e. not via <code>Group</code> membership). 2029 * 2030 * @param transaction 2031 * @param role 2032 * @param users 2033 * @throws GeneralSecurityException 2034 */ 2035 public void setUsersWithRole( SecurityTransaction transaction, Role role, User[] users ) 2036 throws GeneralSecurityException { 2037 2038 PreparedStatement pstmt = null; 2039 2040 try { 2041 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_ROLES WHERE FK_ROLES=?" ); 2042 pstmt.setInt( 1, role.getID() ); 2043 pstmt.executeUpdate(); 2044 pstmt.close(); 2045 pstmt = null; 2046 2047 for ( int i = 0; i < users.length; i++ ) { 2048 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_USERS_ROLES (FK_USERS, FK_ROLES) VALUES (?,?)" ); 2049 pstmt.setInt( 1, users[i].getID() ); 2050 pstmt.setInt( 2, role.getID() ); 2051 pstmt.executeUpdate(); 2052 pstmt.close(); 2053 pstmt = null; 2054 } 2055 } catch ( SQLException e ) { 2056 closeStatement( pstmt ); 2057 abortTransaction( transaction ); 2058 throw new GeneralSecurityException( "SQLRegistry.setUsersWithRole() failed. Rollback performed. " 2059 + "Error message: " + e.getMessage() ); 2060 } 2061 } 2062 2063 /** 2064 * Sets the <code>User</code> s that are members of a given <code>Group</code> DIRECTLY 2065 * (i.e. not via inheritance). 2066 * 2067 * @param transaction 2068 * @param group 2069 * @param users 2070 * @throws GeneralSecurityException 2071 */ 2072 public void setUsersInGroup( SecurityTransaction transaction, Group group, User[] users ) 2073 throws GeneralSecurityException { 2074 PreparedStatement pstmt = null; 2075 2076 try { 2077 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_GROUPS WHERE FK_GROUPS=?" ); 2078 pstmt.setInt( 1, group.getID() ); 2079 pstmt.executeUpdate(); 2080 pstmt.close(); 2081 pstmt = null; 2082 2083 for ( int i = 0; i < users.length; i++ ) { 2084 closeStatement( pstmt ); 2085 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_USERS_GROUPS (FK_USERS, FK_GROUPS) VALUES (?,?)" ); 2086 pstmt.setInt( 1, users[i].getID() ); 2087 pstmt.setInt( 2, group.getID() ); 2088 pstmt.executeUpdate(); 2089 pstmt.close(); 2090 pstmt = null; 2091 } 2092 } catch ( SQLException e ) { 2093 closeStatement( pstmt ); 2094 abortTransaction( transaction ); 2095 throw new GeneralSecurityException( "SQLRegistry.setUsersInGroup() failed. Rollback performed. " 2096 + "Error message: " + e.getMessage() ); 2097 } 2098 } 2099 2100 /** 2101 * Sets the <code>Groups</code> s that are members of a given <code>Group</code> DIRECTLY 2102 * (i.e. not via inheritance). 2103 * 2104 * @param transaction 2105 * @param group 2106 * @param groups 2107 * @throws GeneralSecurityException 2108 */ 2109 public void setGroupsInGroup( SecurityTransaction transaction, Group group, Group[] groups ) 2110 throws GeneralSecurityException { 2111 PreparedStatement pstmt = null; 2112 2113 try { 2114 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_GROUPS WHERE FK_GROUPS=?" ); 2115 pstmt.setInt( 1, group.getID() ); 2116 pstmt.executeUpdate(); 2117 pstmt.close(); 2118 pstmt = null; 2119 2120 for ( int i = 0; i < groups.length; i++ ) { 2121 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_GROUPS_GROUPS (FK_GROUPS_MEMBER, FK_GROUPS) VALUES (?,?)" ); 2122 pstmt.setInt( 1, groups[i].getID() ); 2123 pstmt.setInt( 2, group.getID() ); 2124 pstmt.executeUpdate(); 2125 pstmt.close(); 2126 pstmt = null; 2127 } 2128 } catch ( SQLException e ) { 2129 closeStatement( pstmt ); 2130 abortTransaction( transaction ); 2131 throw new GeneralSecurityException( "SQLRegistry.setGroupsInGroup() failed. Rollback performed. " 2132 + "Error message: " + e.getMessage() ); 2133 } 2134 } 2135 2136 /** 2137 * Sets the <code>Role</code> s that a given <code>User</code> is directly associated to 2138 * (i.e. not via <code>Group</code> membership). 2139 * 2140 * @param transaction 2141 * @param user 2142 * @param roles 2143 * @throws GeneralSecurityException 2144 */ 2145 public void setRolesForUser( SecurityTransaction transaction, User user, Role[] roles ) 2146 throws GeneralSecurityException { 2147 PreparedStatement pstmt = null; 2148 2149 try { 2150 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_USERS_ROLES WHERE FK_USERS=?" ); 2151 pstmt.setInt( 1, user.getID() ); 2152 pstmt.executeUpdate(); 2153 pstmt.close(); 2154 pstmt = null; 2155 2156 for ( int i = 0; i < roles.length; i++ ) { 2157 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_USERS_ROLES (FK_USERS, FK_ROLES) VALUES (?,?)" ); 2158 pstmt.setInt( 1, user.getID() ); 2159 pstmt.setInt( 2, roles[i].getID() ); 2160 pstmt.executeUpdate(); 2161 pstmt.close(); 2162 pstmt = null; 2163 } 2164 } catch ( SQLException e ) { 2165 closeStatement( pstmt ); 2166 abortTransaction( transaction ); 2167 throw new GeneralSecurityException( "SQLRegistry.setRolesForUser() failed. Rollback performed. " 2168 + "Error message: " + e.getMessage() ); 2169 } 2170 } 2171 2172 /** 2173 * Sets the <code>Role</code> s that a given <code>Group</code> is associated to directly 2174 * (i.e. not via inheritance). 2175 * 2176 * @param transaction 2177 * @param group 2178 * @param roles 2179 * @throws GeneralSecurityException 2180 */ 2181 public void setRolesForGroup( SecurityTransaction transaction, Group group, Role[] roles ) 2182 throws GeneralSecurityException { 2183 PreparedStatement pstmt = null; 2184 2185 try { 2186 pstmt = transactionalConnection.prepareStatement( "DELETE FROM SEC_JT_GROUPS_ROLES WHERE FK_GROUPS=?" ); 2187 pstmt.setInt( 1, group.getID() ); 2188 pstmt.executeUpdate(); 2189 pstmt.close(); 2190 pstmt = null; 2191 2192 for ( int i = 0; i < roles.length; i++ ) { 2193 pstmt = transactionalConnection.prepareStatement( "INSERT INTO SEC_JT_GROUPS_ROLES (FK_GROUPS, FK_ROLES) VALUES (?,?)" ); 2194 pstmt.setInt( 1, group.getID() ); 2195 pstmt.setInt( 2, roles[i].getID() ); 2196 pstmt.executeUpdate(); 2197 pstmt.close(); 2198 pstmt = null; 2199 } 2200 } catch ( SQLException e ) { 2201 closeStatement( pstmt ); 2202 abortTransaction( transaction ); 2203 throw new GeneralSecurityException( "SQLRegistry.setRolesForGroup() failed. Rollback performed. " 2204 + "Error message: " + e.getMessage() ); 2205 } 2206 } 2207 2208 /** 2209 * Initializes the <code>SQLRegistry</code> -instance according to the contents of the 2210 * submitted <code>Properties</code>. 2211 * 2212 * @param properties 2213 * @throws GeneralSecurityException 2214 */ 2215 public void initialize( Properties properties ) 2216 throws GeneralSecurityException { 2217 this.dbDriver = properties.getProperty( "driver" ); 2218 this.dbName = properties.getProperty( "url" ); 2219 this.dbUser = properties.getProperty( "user" ); 2220 this.dbPassword = properties.getProperty( "password" ); 2221 } 2222 2223 /** 2224 * Signals the <code>SQLRegistry</code> that a new transaction begins. 2225 * 2226 * Only one transaction can be active at a time. 2227 * 2228 * 2229 * @param transaction 2230 * @throws GeneralSecurityException 2231 */ 2232 public synchronized void beginTransaction( SecurityTransaction transaction ) 2233 throws GeneralSecurityException { 2234 try { 2235 transactionalConnection = DBConnectionPool.getInstance().acquireConnection( dbDriver, dbName, dbUser, 2236 dbPassword ); 2237 // transactionalConnection.setAutoCommit(false); 2238 } catch ( Exception e ) { 2239 throw new GeneralSecurityException( e ); 2240 } 2241 } 2242 2243 /** 2244 * Signals the <code>SQLRegistry</code> that the current transaction ends, i.e. the changes 2245 * made by the transaction are made persistent. 2246 * 2247 * @param transaction 2248 * @throws GeneralSecurityException 2249 */ 2250 public void commitTransaction( SecurityTransaction transaction ) 2251 throws GeneralSecurityException { 2252 try { 2253 transactionalConnection.commit(); 2254 } catch ( SQLException e ) { 2255 throw new GeneralSecurityException( "Committing of transaction failed: " + e.getMessage() ); 2256 } finally { 2257 try { 2258 DBConnectionPool.getInstance().releaseConnection( transactionalConnection, dbDriver, dbName, dbUser, 2259 dbPassword ); 2260 } catch ( Exception e ) { 2261 e.printStackTrace(); 2262 } 2263 } 2264 } 2265 2266 /** 2267 * Signals the <code>SQLRegistry</code> that the current transaction shall be aborted. Changes 2268 * made during the transaction are undone. 2269 * 2270 * @param transaction 2271 * @throws GeneralSecurityException 2272 */ 2273 public void abortTransaction( SecurityTransaction transaction ) 2274 throws GeneralSecurityException { 2275 try { 2276 transactionalConnection.rollback(); 2277 } catch ( SQLException e ) { 2278 throw new GeneralSecurityException( "Aborting of transaction failed: " + e.getMessage() ); 2279 } finally { 2280 try { 2281 DBConnectionPool.getInstance().releaseConnection( transactionalConnection, dbDriver, dbName, dbUser, 2282 dbPassword ); 2283 } catch ( Exception e ) { 2284 e.printStackTrace(); 2285 } 2286 } 2287 } 2288 2289 /** 2290 * Acquires a new <code>Connection</code>. If the given securityAccess is the exclusive 2291 * Read/Write-transaction holder, the transactionalConnection is returned, else a new 2292 * <code>Connection</code> is taken from the pool. 2293 * 2294 * @param securityAccess 2295 * @return 2296 * @throws GeneralSecurityException 2297 */ 2298 private Connection acquireLocalConnection( SecurityAccess securityAccess ) 2299 throws GeneralSecurityException { 2300 2301 Connection con = null; 2302 2303 if ( securityAccess instanceof SecurityTransaction ) { 2304 con = transactionalConnection; 2305 } else { 2306 try { 2307 con = DBConnectionPool.getInstance().acquireConnection( dbDriver, dbName, dbUser, dbPassword ); 2308 // con.setAutoCommit(false); 2309 } catch ( Exception e ) { 2310 throw new GeneralSecurityException( e ); 2311 } 2312 } 2313 return con; 2314 } 2315 2316 /** 2317 * Releases a <code>Connection</code>. If the given securityAccess is the exclusive 2318 * Read/Write-transaction holder, nothing happens, else it is returned to the pool. 2319 * 2320 * @param securityAccess 2321 * @param con 2322 * @return 2323 * @throws GeneralSecurityException 2324 */ 2325 private void releaseLocalConnection( SecurityAccess securityAccess, Connection con ) 2326 throws GeneralSecurityException { 2327 2328 if ( !( securityAccess instanceof SecurityTransaction ) ) { 2329 if ( con != null ) { 2330 try { 2331 DBConnectionPool.getInstance().releaseConnection( con, dbDriver, dbName, dbUser, dbPassword ); 2332 } catch ( Exception e ) { 2333 throw new GeneralSecurityException( e ); 2334 } 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Closes the given <code>Statement</code> if it is not null. 2341 * 2342 * @param stmt 2343 * @throws GeneralSecurityException 2344 */ 2345 private void closeStatement( Statement stmt ) 2346 throws GeneralSecurityException { 2347 if ( stmt != null ) { 2348 try { 2349 stmt.close(); 2350 } catch ( SQLException e ) { 2351 throw new GeneralSecurityException( e ); 2352 } 2353 } 2354 } 2355 2356 /** 2357 * Closes the given <code>ResultSet</code> if it is not null. 2358 * 2359 * @param rs 2360 * @throws GeneralSecurityException 2361 */ 2362 private void closeResultSet( ResultSet rs ) 2363 throws GeneralSecurityException { 2364 if ( rs != null ) { 2365 try { 2366 rs.close(); 2367 } catch ( SQLException e ) { 2368 throw new GeneralSecurityException( e ); 2369 } 2370 } 2371 } 2372 2373 /** 2374 * Retrieves an unused PrimaryKey-value for the given table. The table must have its PrimaryKey 2375 * in an Integer-field named 'ID'. 2376 * 2377 * @param table 2378 * @return 2379 */ 2380 private int getID( SecurityTransaction transaction, String table ) 2381 throws GeneralSecurityException { 2382 int id = 0; 2383 Connection con = acquireLocalConnection( transaction ); 2384 2385 try { 2386 DataBaseIDGenerator idGenerator = IDGeneratorFactory.createIDGenerator( con, table, "ID" ); 2387 Object o = idGenerator.generateUniqueId(); 2388 if ( !( o instanceof Integer ) ) { 2389 throw new GeneralSecurityException( "Error generating new PrimaryKey for table '" + table + "'." ); 2390 } 2391 id = ( (Integer) o ).intValue(); 2392 } catch ( SQLException e ) { 2393 throw new GeneralSecurityException( e ); 2394 } finally { 2395 releaseLocalConnection( transaction, con ); 2396 } 2397 return id; 2398 } 2399 2400 /** 2401 * Tries to build a <code>ComplexFilter</code> from the given string representation. 2402 * 2403 * @param constraints 2404 * @return 2405 * @throws GeneralSecurityException 2406 */ 2407 private ComplexFilter buildFilter( String constraints ) 2408 throws GeneralSecurityException { 2409 Filter filter = null; 2410 try { 2411 Document document = XMLTools.parse( new StringReader( constraints ) ); 2412 Element element = document.getDocumentElement(); 2413 filter = AbstractFilter.buildFromDOM( element ); 2414 } catch ( FilterConstructionException e ) { 2415 throw new GeneralSecurityException( "The stored constraint is not a valid filter: " + e.getMessage() ); 2416 } catch ( Exception e ) { 2417 throw new GeneralSecurityException( "Error parsing the stored constraint: " + e.getMessage() ); 2418 } 2419 if ( !( filter instanceof ComplexFilter ) ) { 2420 throw new GeneralSecurityException( "The stored constraint is not of type 'ComplexFilter'." ); 2421 } 2422 return (ComplexFilter) filter; 2423 } 2424 }