001package com.randomnoun.common.security.impl; 002 003/* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a 004 * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html) 005 */ 006 007import java.io.IOException; 008import java.util.*; 009 010import org.apache.log4j.Logger; 011import org.springframework.dao.DataIntegrityViolationException; 012import org.springframework.jdbc.core.*; 013 014import com.randomnoun.common.CamelCaser; 015import com.randomnoun.common.Struct; 016import com.randomnoun.common.Text; 017import com.randomnoun.common.jexl.sql.SqlGenerator; 018import com.randomnoun.common.security.Permission; 019import com.randomnoun.common.security.SecurityContext; 020import com.randomnoun.common.security.SecurityLoader; 021import com.randomnoun.common.security.User; 022import com.randomnoun.common.security.impl.ResourceCriteriaImpl; 023import com.randomnoun.common.security.impl.SpringSecurityLoaderImpl; 024import com.randomnoun.common.spring.StringRowMapper; 025 026 027/** 028 * An implementation of the {@link com.randomnoun.common.security.SecurityLoader} 029 * class, using the Spring framework to populate the SecurityContext from a JDBC 030 * datasource. 031 * 032 * <p>This security context used to optionally take a customerId (used to partition 033 * users across separate SaaS contexts), or an applicationId (used to partition 034 * permissions across separate software products). If not defined, then these 035 * columns did not need to be present in the database. This functionality 036 * has been deprecated. 037 * 038 * <p>I think we had String userids at one point as well, so look out for that. 039 * 040 * <p>This class has a number of initialisation properties that are specific 041 * to this class (in addition to those initialisation properties that are 042 * set by the SecurityContext itself): 043 * 044 * <ul> 045 * <li> {@link #INIT_JDBCTEMPLATE} - The Spring JdbcTemplate class used to retrieve 046 * information from a database. 047 * <li> {@link #INIT_DATABASE_VENDOR} - Set to one of the SqlGenerator.DATABASE_* constants, 048 * which specifies what syntax of SQL to use (DB2, Oracle or SqlServer). 049 * </ul> 050 * 051 * @author knoxg 052 */ 053public class SpringSecurityLoaderImpl 054 implements SecurityLoader 055{ 056 057 /** Logger for this class */ 058 public static final Logger logger = Logger.getLogger(SpringSecurityLoaderImpl.class); 059 060 /** Properties used in this loader */ 061 private Map<String, Object> properties = null; 062 063 /** Used as parameter to {@link #convertPermissionList(List, int)} method */ 064 private static final int PERMISSION_USER = 1; 065 /** Used as parameter to {@link #convertPermissionList(List, int)} method */ 066 private static final int PERMISSION_ROLE = 2; 067 /** Used as parameter to {@link #convertPermissionList(List, int)} method */ 068 private static final int PERMISSION_NONE = 3; 069 070 /** Initialisation property key to set JdbcTemplate. */ 071 public final static String INIT_JDBCTEMPLATE = "jdbcTemplate"; 072 073 /* * Initialisation property key to set the username mask. */ 074 // public final static String INIT_USERNAME_MASK = "usernameMask"; 075 076 /** Database vendor for generated SQL. Should be one of the SqlGenerator.DB_* constants */ 077 public final static String INIT_DATABASE_VENDOR = "databaseVendor"; 078 079 /** Boolean object version of SecurityContext.INIT_CASE_INSENSITIVE string; set to 080 * false if missing */ 081 public final static String INIT_CASE_INSENSITIVE_OBJ = "caseInsensitiveObj"; 082 083 /** Column renamer for the shouty ROLETABLE table */ 084 public final CamelCaser roleCamelCaser = new CamelCaser("roleId,roleName,description"); 085 086 /** Column renamer for the USERS table */ 087 public final CamelCaser userCamelCaser = new CamelCaser("userId,name"); 088 089 /** Column renamer for the PERMISSION table */ 090 public final CamelCaser permissionCamelCaser = new CamelCaser("roleName,userId,activityName,resourceName,resourceCriteria"); 091 092 /** Column renamer for the SECURITYAUDITS table */ 093 public final CamelCaser auditCamelCaser = new CamelCaser("userId,auditTime,auditDescription,resourceCriteria,authorised,authoriserId,authoriseTime"); 094 095 096 // we used to have staging tables for changes to the security model, which then 097 // had to be approved before they were transferred to the real security model. Remember that ? 098 // 'four-eyes' security anyone ? 099 100 /** Return the name of the USERS table that this security loader will retrieve data from */ 101 private String userTable() { 102 return "users"; 103 } 104 105 /** Return the name of the USERROLE table that this security loader will retrieve data from */ 106 private String userRoleTable() { 107 return "userRole"; 108 } 109 110 /** Return the name of the ROLETABLE table that this security loader will retrieve data from */ 111 private String roleTable() { 112 return "roleTable"; 113 } 114 115 /** Return the name of the SECURITYTABLE table that this security loader will retrieve data from */ 116 private String securityTable() { 117 return "securityTable"; 118 } 119 120 /* 121 private String roleTableSequence() { 122 return "SEQ_ROLETABLE"; 123 } 124 125 126 private boolean isAuditEnabled() { 127 Boolean enabled = (Boolean) properties.get(INIT_AUDIT_ENABLED); 128 if (enabled==null) { 129 return Boolean.TRUE; 130 } 131 return enabled; 132 } 133 134 / * * Return the username to be used to audit any security operations performed by this security loader * / 135 private String auditUsername() { 136 String auditUser = (String) properties.get(INIT_AUDIT_USERNAME); 137 if (auditUser==null) { 138 throw new IllegalStateException("Audit user required for all mutable security context operations"); 139 } 140 return auditUser; 141 } 142 */ 143 144 /** Retrieve the database vendor from the security loaders properties map. 145 * @return the database vendor */ 146 private String getDatabaseVendor() { 147 return (String) properties.get(INIT_DATABASE_VENDOR); 148 } 149 150 151 /** Returns true if this security context is case-insensitive, false otherwise 152 * 153 * @return true if this security context is case-insensitive, false otherwise 154 */ 155 private boolean getCaseInsensitive() { 156 // @TODO: cache this 157 return ((Boolean) properties.get(INIT_CASE_INSENSITIVE_OBJ)).booleanValue(); 158 } 159 160 /** Return the sql for a string comparison for a username field, taking 161 * case sensitivity into account. 162 * 163 * @param lhs expression to lowercase (if required) 164 * 165 * @return 166 */ 167 private String lowerSql(String lhs) { 168 if (getCaseInsensitive()) { 169 String vendor = getDatabaseVendor(); 170 if (vendor.equals(SqlGenerator.DATABASE_DB2)) { 171 return "LOWER(" + lhs + ")"; 172 } else if (vendor.equals(SqlGenerator.DATABASE_ORACLE)) { 173 return "LOWER(" + lhs + ")"; 174 } else if (vendor.equals(SqlGenerator.DATABASE_SQLSERVER)) { 175 return "LOWER(" + lhs + ")"; 176 } else if (vendor.equals(SqlGenerator.DATABASE_MYSQL)) { 177 return "LOWER(" + lhs + ")"; 178 } else { 179 throw new IllegalStateException("Case-insensitivity security contexts" + 180 " not supported for database type '" + vendor + "'"); 181 } 182 } else { 183 return lhs; 184 } 185 } 186 187 /** Converts a value to lowercase, but only if case insensitivity is required */ 188 private String lower(String value) { 189 if (getCaseInsensitive()) { 190 return value.toLowerCase(); 191 } else { 192 return value; 193 } 194 } 195 196 /** Converts a long into an object suitable to be passed to the database 197 * as a roleId or permissionId. 198 * 199 * @param var object to convert 200 * 201 * @return a Long representation of the object (or Integer for JET DBs) 202 */ 203 private Object toSequenceType(long var) { 204 String vendor = getDatabaseVendor(); 205 if (vendor.equals(SqlGenerator.DATABASE_JET)) { 206 return new Integer((int) var); 207 } else { 208 return new Long(var); 209 } 210 } 211 212 /** Initialise this loader. 213 * 214 * <p>The properties Map passed into this method must contain the following 215 * attributes. 216 * 217 * <attributes> 218 * jdbcTemplate - a JdbcTemplate object connected to a datasource 219 * databaseVendor - one of the SqlGenerator.DATABASE_* constants, defining what 220 * syntax of SQL to generate from this class. 221 * </attributes> 222 * 223 * @see com.randomnoun.common.security.SecurityLoader#initialise(java.util.Map) 224 */ 225 public void initialise(Map<String, Object> properties) 226 { 227 this.properties = properties; 228 //String tableSuffix = (String) properties.get(INIT_TABLE_SUFFIX); 229 //if (tableSuffix == null) { throw new NullPointerException("null INIT_TABLE_SUFFIX"); } 230 if (properties.get(INIT_JDBCTEMPLATE)==null) { throw new NullPointerException("null INIT_JDBCTEMPLATE"); } 231 if (properties.get(INIT_DATABASE_VENDOR)==null) { throw new NullPointerException("null INIT_DATABASE_VENDOR"); } 232 String vendor = (String) properties.get(INIT_DATABASE_VENDOR); 233 if (!(vendor.equals(SqlGenerator.DATABASE_DB2) || 234 vendor.equals(SqlGenerator.DATABASE_ORACLE) || 235 vendor.equals(SqlGenerator.DATABASE_SQLSERVER) || 236 vendor.equals(SqlGenerator.DATABASE_MYSQL) || 237 vendor.equals(SqlGenerator.DATABASE_JET))) { 238 throw new IllegalArgumentException("Invalid INIT_DATABASE_VENDOR property '" + vendor + "'"); 239 } 240 241 // '' should only be allowed when staging contexts are disabled 242 /* 243 if (!(tableSuffix.equals("_WORK") || tableSuffix.equals("_LIVE") || 244 tableSuffix.equals(""))) 245 { 246 throw new IllegalArgumentException("INIT_TABLE_SUFFIX must be set to '', '_WORK' or '_LIVE'"); 247 } 248 */ 249 250 String caseInsensitive = (String) properties.get(SecurityContext.INIT_CASE_INSENSITIVE); 251 if (Text.isBlank(caseInsensitive)) { 252 caseInsensitive = "false"; 253 } 254 properties.put(INIT_CASE_INSENSITIVE_OBJ, Boolean.valueOf(caseInsensitive)); 255 256 /* 257 it's still OK to call read-only methods on the staging security context without an audit user 258 259 if (tableSuffix.equals("_WORK") && properties.get(INIT_AUDIT_USERNAME)==null) { 260 throw new IllegalArgumentException( 261 "Must include audit username when operating on staging security context"); 262 }*/ 263 264 } 265 266 /** Load all role permissions. 267 * 268 * {@inheritDoc} 269 * 270 * @return A List of Permission objects for all roles in the current application. Does 271 * not return Permissions that are not explicitly associated with a role in the security table. 272 * 273 * @throws IOException if an error occured loading from the database. This IOException 274 * will always contain a spring DataAccessException which can be accessed in its .getCause() 275 * method. 276 * 277 * @see com.randomnoun.common.security.SecurityLoader#loadAllRolePermissions() 278 */ 279 public List<Permission> loadAllRolePermissions() 280 throws IOException 281 { 282 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 283 String loadAllRolePermissionsSql = 284 "SELECT roleName, activityName, resourceName, resourceCriteria " + 285 "FROM " + roleTable() + ", " + securityTable() + ", permission, resources " + 286 "WHERE " + 287 " (" + securityTable() + ".roleId = " + roleTable() + ".roleId) " + 288 " AND " + "(" + securityTable() + ".permissionId = permission.permissionId) " + 289 " AND " + "(permission.resourceId = resources.resourceId)"; 290 List<Object> sqlParams = new ArrayList<Object>(2); 291 List<Map<String, Object>> list = jt.query(loadAllRolePermissionsSql, 292 sqlParams.toArray(), 293 new ColumnMapRowMapper()); 294 if (logger.isDebugEnabled()) { 295 logger.debug(Struct.structuredListToString("loadAllRolePermissions", list)); 296 } 297 permissionCamelCaser.renameList(list); 298 return convertPermissionList(list, PERMISSION_ROLE); 299 } 300 301 /** Retrieve per-user permission objects. 302 * 303 * {@inheritDoc} 304 * 305 * @throws IOException if an error occured loading from the database. This IOException 306 * will always contain a spring DataAccessException which can be accessed in its .getCause() 307 * method. 308 * 309 * @see com.randomnoun.common.security.SecurityLoader#loadUserPermission() 310 */ 311 public List<Permission> loadUserPermissions(User user) 312 throws IOException 313 { 314 JdbcTemplate jt = (JdbcTemplate) properties.get("jdbcTemplate"); 315 316 String sqlPermissions = 317 "SELECT activityName, resourceName, resourceCriteria " + 318 "FROM " + securityTable() + ", permission, resources " + 319 "WHERE " + 320 " " + securityTable() + ".roleId IS NULL " + 321 " AND (" + lowerSql(securityTable() + ".userId") + " = ?) " + 322 " AND (" + securityTable() + ".permissionId = permission.permissionId) " + 323 " AND (permission.resourceId = resources.resourceId) ORDER BY resourceName, activityName"; 324 List<Object> sqlParams = new ArrayList<Object>(2); 325 sqlParams.add(lower(user.getUsername())); 326 List<Map<String, Object>> list = jt.query(sqlPermissions, sqlParams.toArray(), new ColumnMapRowMapper()); 327 328 if (logger.isDebugEnabled()) { 329 logger.debug(Struct.structuredListToString("loadAllUserPermissions [2]", list)); 330 } 331 permissionCamelCaser.renameList(list); 332 return convertPermissionList(list, PERMISSION_USER); 333 } 334 335 336 /** Retrieve a list of roles applied to a particular user 337 * for the current application context. 338 * 339 * @return List of roles, represented as Strings 340 * 341 * @see com.randomnoun.common.security.SecurityLoader#loadRolesForUser() 342 */ 343 public List<String> loadUserRoles(User user) 344 { 345 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 346 String sql = "SELECT roleName " + 347 " FROM " + roleTable() + "," + userRoleTable() + 348 " WHERE " + 349 roleTable() + ".roleId = " + userRoleTable() + ".roleId " + 350 " AND " + lowerSql(userRoleTable() + ".userId") + " = ?"; 351 logger.debug("loadRolesForUser: " + sql + "; " + user.getUsername()); 352 List<Object> sqlParams = new ArrayList<Object>(3); 353 sqlParams.add(lower(user.getUsername())); 354 List<String> list = jt.query(sql, sqlParams.toArray(), new StringRowMapper()); 355 return list; 356 } 357 358 359 /** 360 * Return List of Permission associated with a particular role 361 * 362 * @param role 363 * @return A List of Permission objects that apply to that role 364 */ 365 public List<Permission> loadRolePermissions(String role) 366 { 367 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 368 long roleId = findRoleIdByName(role); 369 String sql = 370 "SELECT roleName, activityName, resourceName, resourceCriteria " + 371 "FROM " + roleTable() + ", " + securityTable() + ", permission, resources " + 372 "WHERE " + 373 " (" + securityTable() + ".roleId = ?) " + 374 " AND (" + roleTable() + ".roleId = " + securityTable() + ".roleId) " + 375 " AND (" + securityTable() + ".permissionId = permission.permissionId) " + 376 " AND (permission.resourceId = resources.resourceId) " + 377 " ORDER BY resourceName, activityName"; 378 List<Object> sqlParams = new ArrayList<Object>(2); 379 sqlParams.add(toSequenceType(roleId)); 380 List<Map<String, Object>> list = jt.query(sql, sqlParams.toArray(), new ColumnMapRowMapper()); 381 permissionCamelCaser.renameList(list); 382 return convertPermissionList(list, PERMISSION_ROLE); 383 } 384 385 /** 386 * Return List of Permissions containing permissions contained for all roles 387 * for a particular user. 388 * 389 * <p>Note that if a user contains multiple roles that have permissions that apply to 390 * the same activity/resource combinations, then that will be reflected 391 * in the returned list. 392 * 393 * @param userid Name of user we are interested in. 394 * @return A List of Maps 395 */ 396 public List<Permission> loadUserRolePermissions(User user) 397 { 398 JdbcTemplate jt = (JdbcTemplate) properties.get("jdbcTemplate"); 399 String sql ="SELECT activityName, resourceName, resourceCriteria " + 400 "FROM " + securityTable() + ", " + roleTable() + ", permission, resources " + 401 "WHERE (" + securityTable() + ".roleId IN (" + 402 "SELECT " + userRoleTable() + ".roleId " + 403 "FROM " + userRoleTable() + ", " + roleTable() + 404 " WHERE " + userRoleTable() + ".roleId = " + roleTable() + ".roleId " + 405 " AND " + lowerSql("userId") + " = ?)) " + 406 " AND (" + securityTable() + ".permissionId = permission.permissionId) " + 407 " AND (permission.resourceId = resources.resourceId)"; 408 List<Object> sqlParams = new ArrayList<Object>(2); 409 sqlParams.add(user.getUsername()); 410 List<Map<String, Object>> list = jt.query(sql, sqlParams.toArray(), new ColumnMapRowMapper()); 411 412 // take out duplicates 413 // Can't use DISTINCT on queries that contain CLOBs. Goddamn oracle. 414 ArrayList<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>(); 415 for (int x = 0; x < list.size(); x++) { 416 Map<String, Object> row = list.get(x); 417 if (!list2.contains(row)) { 418 list2.add(row); 419 } 420 } 421 permissionCamelCaser.renameList(list2); 422 return convertPermissionList(list2, PERMISSION_NONE); // role perm here ? 423 424 } 425 426 427 /** 428 * Return a List of all Permissions available to this application 429 * 430 * @return a List of Permissions available to this application 431 */ 432 public List<Permission> loadAllPermissions() 433 { 434 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 435 String sql = 436 "SELECT activityName, resourceName" + 437 " FROM permission, resources " + 438 " WHERE " + 439 " permission.resourceId = resources.resourceId " + 440 "ORDER BY resourceName, activityName"; 441 List<Object> sqlParams = new ArrayList<Object>(2); 442 List<Map<String, Object>> list = jt.query(sql, sqlParams.toArray(), new ColumnMapRowMapper()); 443 permissionCamelCaser.renameList(list); 444 return convertPermissionList(list, PERMISSION_NONE); 445 } 446 447 448 449 /** Private method to convert a list of PERMISSION rows (as returned by Spring) 450 * into Permission Objects. 451 * 452 * <p>On reflection, probably should have used a Spring RowMapper for this. Oh well. It works. 453 * 454 * @param list The list to convert 455 * @return A List of Permission objects 456 */ 457 private List<Permission> convertPermissionList(List<Map<String, Object>> list, int permissionType) 458 { 459 String resourceType; 460 String expressionString; 461 Permission permission; 462 List<Permission> result = new ArrayList<Permission>(list.size()); 463 464 for (Iterator<Map<String, Object>> i = list.iterator(); i.hasNext(); ) { 465 Map<String, Object> map = i.next(); 466 resourceType = (String) map.get("resourceName"); 467 expressionString = (String) map.get("resourceCriteria"); 468 ResourceCriteriaImpl resourceCriteriaImpl = null; 469 if (expressionString != null && !expressionString.equals("")) { 470 try { 471 resourceCriteriaImpl = new ResourceCriteriaImpl(expressionString); 472 } catch (Exception ce) { 473 throw new DataIntegrityViolationException( 474 "Invalid criteria found in SECURITY.RESOURCECRITERIA: '" + 475 expressionString + "'", ce); 476 } 477 } 478 479 if (permissionType == PERMISSION_ROLE) { 480 permission = new Permission((String)map.get("roleName"), 481 (String)map.get("activityName"), resourceType, resourceCriteriaImpl); 482 } else if (permissionType == PERMISSION_USER) { 483 User user = new User(); 484 user.setUsername((String) map.get("userId")); 485 permission = new Permission( user, 486 (String)map.get("activityName"), resourceType, resourceCriteriaImpl); 487 } else if (permissionType == PERMISSION_NONE) { 488 permission = new Permission((String)map.get("activityName"), resourceType); 489 490 } else { 491 throw new IllegalArgumentException("Unknown permission type '" + permissionType + "'"); 492 } 493 result.add(permission); 494 } 495 return result; 496 } 497 498 // if you want to do this, subclass it 499 public User loadUser(long userId) throws IOException { 500 throw new IOException("loadUser() not implemented"); 501 502 /* 503 // tempted to go through all these methods and change userId to an actual number rather than a varchar. 504 // sounds fair to me. 505 506 JdbcTemplate jt = (JdbcTemplate) properties.get("jdbcTemplate"); 507 String sql = 508 "SELECT " + userTable() + ".userId " + // so userId's a string is it ? terrific. 509 " FROM " + userTable(); 510 List<String> list = jt.query(sql, new StringRowMapper()); 511 List<User> result = new ArrayList<User>(list.size()); 512 for (Iterator i = list.iterator(); i.hasNext(); ) { 513 String username = (String) i.next(); 514 User user = new User(); 515 user.setUsername(username); // this is horrible, but it's consistent with what's in here at the moment. 516 result.add(user); 517 } 518 return result; 519 */ 520 521 } 522 523 /** Retrieve a list of users in the current application context. 524 * 525 * {@inheritDoc} 526 * 527 * @throws IOException if an error occured loading from the database. This IOException 528 * will always contain a spring DataAccessException which can be accessed via 529 * {@link java.io.Throwable#getCause} method. 530 * 531 * @see com.randomnoun.common.security.SecurityLoader#loadAllUsers() 532 */ 533 public List<User> loadAllUsers() 534 throws IOException 535 { 536 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 537 String sql = 538 "SELECT " + userTable() + ".userId " + 539 " FROM " + userTable(); 540 List<String> list = jt.query(sql, new StringRowMapper()); 541 List<User> result = new ArrayList<User>(list.size()); 542 for (Iterator<String> i = list.iterator(); i.hasNext(); ) { 543 String username = (String) i.next(); 544 User user = new User(); 545 user.setUsername(username); 546 result.add(user); 547 } 548 return result; 549 } 550 551 /** Retrieve a list of all the resources under security for the current application context. 552 * 553 * @return List of maps, each map represents resource 554 * 555 * @see com.randomnoun.common.security.SecurityLoader#loadAllResources() 556 */ 557 public List<String> loadAllResources() { 558 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 559 String sql = 560 "SELECT resourceName " + 561 "FROM resources "; 562 List<Object> sqlParams = new ArrayList<Object>(2); 563 List<String> list = jt.query(sql, sqlParams.toArray(), new StringRowMapper()); 564 return list; 565 } 566 567 568 /** Retrieve a list of all the activities that can be applied to resource 569 * for the current application context. 570 * 571 * @return List of maps, each map represents an activity. 572 * 573 * @see com.randomnoun.common.security.SecurityLoader#loadAllActivities() 574 */ 575 public List<String> loadAllActivities(String resourceName) 576 { 577 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 578 String sql = 579 "SELECT activityName " + 580 "FROM permission, resources " + 581 "WHERE " + 582 " resourceName = ? " + 583 " AND permission.resourceId = resources.resourceId "; 584 List<Object> sqlParams = new ArrayList<Object>(3); 585 sqlParams.add(resourceName); 586 List<String> list = jt.query(sql, sqlParams.toArray(), new StringRowMapper()); 587 return list; 588 } 589 590 /** Retrieve a list of all the roles that can be applied to a user 591 * for the current application context. 592 * 593 * @return List of maps, each map represents a role. 594 * 595 * @see com.randomnoun.common.security.SecurityLoader#loadAllRoles() 596 */ 597 public List<String> loadAllRoles() 598 { 599 JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate"); 600 String sql = "SELECT roleName " + 601 " FROM " + roleTable(); 602 List<Object> sqlParams = new ArrayList<Object>(2); 603 List<String> list = jt.query(sql, sqlParams.toArray(), new StringRowMapper()); 604 return list; 605 } 606 607 608 /** 609 * Returns List of maps, where each map represents the details of a particular role. 610 */ 611 public List<Map<String, Object>> loadAllRoleDetails() 612 { 613 logger.debug("SpringSecurityLoaderImpl.loadAllRoleDetails(): 1. Entering"); 614 JdbcTemplate jt = (JdbcTemplate) properties.get("jdbcTemplate"); 615 String sql = 616 "SELECT roleId, roleName, description" + 617 " FROM " + roleTable(); 618 List<Object> sqlParams = new ArrayList<Object>(2); 619 List<Map<String,Object>> list = jt.queryForList(sql, sqlParams.toArray()); 620 roleCamelCaser.renameList(list); 621 return list; 622 } 623 624 /** 625 * Returns List of maps, where each map represents the details of a particular user. 626 */ 627 public List<Map<String, Object>> loadAllUserDetails() 628 { 629 JdbcTemplate jt = (JdbcTemplate) properties.get("jdbcTemplate"); 630 String sql = "SELECT userId, name " + 631 " FROM " + userTable(); 632 List<Object> sqlParams = new ArrayList<Object>(1); 633 List<Map<String,Object>> list = jt.queryForList(sql, sqlParams.toArray()); 634 userCamelCaser.renameList(list); 635 return list; 636 } 637 638 /** 639 * Returns the ROLEID of a role, given its name 640 * 641 * @param role Name of the role to find 642 * 643 */ 644 private long findRoleIdByName(String role) 645 { 646 try { 647 JdbcTemplate jt = (JdbcTemplate) properties.get("jdbcTemplate"); 648 logger.debug("findRoleIdByName('" + role + "') called"); 649 String tablename = roleTable(); 650 String sql = 651 "SELECT roleId " + 652 "FROM " + tablename + 653 " WHERE roleName = ? "; 654 List<Object> sqlParams = new ArrayList<Object>(3); 655 sqlParams.add(role); 656 long key = jt.queryForObject(sql, sqlParams.toArray(), Long.class); 657 logger.debug("findRoleIdByName('" + role + "') returning " + key); 658 return key; 659 } catch (org.springframework.dao.IncorrectResultSizeDataAccessException irsdae) { 660 throw (IllegalArgumentException) new IllegalArgumentException( 661 "Could not find role '" + role + "' in " + roleTable()).initCause(irsdae); 662 } 663 } 664 665 666 /** Resets the security context. 667 * 668 * <p>This security context holds no state, so this method does nothing. 669 */ 670 public void resetSecurityContext() { 671 // no action necessary 672 } 673 674 public void saveUserRolesAndPermissions(User user, List<String> roles, List<Permission> userPermissions) throws IOException 675 { 676 throw new UnsupportedOperationException("not implemented"); 677 } 678 679 public void saveRolePermissions(String role, List<Permission> rolePermissions) 680 throws IOException 681 { 682 throw new UnsupportedOperationException("not implemented"); 683 } 684 685 686 687} 688