]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-4964: A shuffling of methods from ServiceMain.java to AuthorizationCommon...
authorRichard Millet <remillet@berkeley.edu>
Wed, 28 Mar 2012 00:24:46 +0000 (17:24 -0700)
committerRichard Millet <remillet@berkeley.edu>
Wed, 28 Mar 2012 00:24:46 +0000 (17:24 -0700)
pom.xml
services/authorization-mgt/import/build.xml
services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/driver/AuthorizationSeedDriver.java
services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationGen.java
services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationSeed.java
services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationStore.java
services/common/pom.xml
services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java

diff --git a/pom.xml b/pom.xml
index 72531d35a776eb1a3f7a7388b26c4f025072f5ff..40f641d74d8f9064172521cd7b215ca3c9feefc0 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,8 @@
 -->\r
                <cspace.services.version>2.2-SNAPSHOT</cspace.services.version>\r
                <cspace.services.client.version>2.2-SNAPSHOT</cspace.services.client.version>\r
+               <spring.version>3.0.0.RELEASE</spring.version>\r
+        <spring.security.version>3.0.2.RELEASE</spring.security.version>\r
        </properties>\r
 \r
        <distributionManagement>\r
index b3a77ee738d8d82e450ca2e9433afebdc12d5ff9..bb32302d8b497be820f3f71a134de6b651b5a770 100644 (file)
     <target name="import-windows" if="osfamily-windows" depends="setup_hibernate.cfg">\r
         <exec executable="cmd" failonerror="true">\r
             <arg value="/c" />\r
-            <arg value="mvn.bat" /> <!-- To debug, change command here to be 'mvnDebug.bat' -->\r
+            <arg value="mvnDebug.bat" /> <!-- To debug, change command here to be 'mvnDebug.bat' -->\r
             <arg value="exec:java" />\r
             <arg value="-f" />\r
             <arg value="${basedir}/pom.xml" />\r
index 737bbcec6ca6ab642147b4163c9e9d84502e9364..5002a6e4fd4279bff953e06f0166c1cdc51bf81d 100644 (file)
@@ -123,7 +123,7 @@ public class AuthorizationSeedDriver {
     public void seed() {
         TransactionStatus status = null;
         try {
-               // Push all the authz info into the cspace DB tables.
+               // Push all the authz info into the cspace DB tables -this include default roles, permissions, and permroles
             store();
 
             setupSpring();
@@ -167,7 +167,7 @@ public class AuthorizationSeedDriver {
 
     private void login() {
         //GrantedAuthority cspace_admin = new GrantedAuthorityImpl("ROLE_ADMINISTRATOR");
-        GrantedAuthority spring_security_admin = new GrantedAuthorityImpl("ROLE_SPRING_ADMIN");
+        GrantedAuthority spring_security_admin = new GrantedAuthorityImpl("ROLE_SPRING_ADMIN"); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
         HashSet<GrantedAuthority> gauths = new HashSet<GrantedAuthority>();
         //gauths.add(cspace_admin);
         gauths.add(spring_security_admin);
@@ -203,7 +203,7 @@ public class AuthorizationSeedDriver {
                }
         }
 
-        for (Permission perm : authzGen.getDefaultPermissions()) {
+        for (Permission perm : authzGen.getDefaultPermissions()) { //FIXME: REM - 3/27/2012 - If we change the CSID of permissions to something like a refname, then we need to check for existing perms just like we did above for roles
             authzStore.store(perm);
         }
 
index cd9b16612841b1589065b3f418caa399645fad91..3ebd9d7bb85bff521a4b441e8bd17f38d5312b1e 100644 (file)
@@ -155,7 +155,7 @@ public class AuthorizationGen {
     }
 
     private Permission buildAdminPermission(String tenantId, String resourceName) {
-        String id = UUID.randomUUID().toString();
+        String id = UUID.randomUUID().toString(); //FIXME: Could this be something like a refname instead of a UUID?
         Permission perm = new Permission();
         perm.setCsid(id);
         perm.setDescription("generated admin permission");
@@ -310,7 +310,7 @@ public class AuthorizationGen {
                allRoleList.addAll(adminRoles);
                allRoleList.addAll(readerRoles);
        }
-        return allRoleList;
+        return allRoleList;  //FIXME: REM - 3/27/2012, The super role "cspaceAdminRole" is not on this list.  Intentional?
     }
 
     public void associateDefaultPermissionsRoles() {
index 1fa6a01b3bd6d2121bc3539747b2186f1bddf327..5a766a8baf1b38226cafb0d1151950d646b56b33 100644 (file)
@@ -35,7 +35,6 @@ import javax.xml.bind.Unmarshaller;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.springframework.security.acls.model.AlreadyExistsException;
 import org.collectionspace.services.authorization.AuthZ;
 import org.collectionspace.services.authorization.CSpaceAction;
 import org.collectionspace.services.authorization.perms.EffectType;
@@ -47,6 +46,7 @@ import org.collectionspace.services.authorization.perms.PermissionsList;
 import org.collectionspace.services.authorization.PermissionsRolesList;
 import org.collectionspace.services.authorization.RoleValue;
 import org.collectionspace.services.authorization.URIResourceImpl;
+import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
 
 /**
  * AuthorizationSeed seeds authorizations (permission, role) into authz provider database
@@ -107,48 +107,13 @@ public class AuthorizationSeed {
             }
             for (PermissionRole pr : permRoleList) {
                 if (pr.getPermission().get(0).getPermissionId().equals(p.getCsid())) {
-                    addPermissionsForUri(p, pr);
+                       AuthorizationCommon.addPermissionsForUri(p, pr);
                 }
             }
         }
     }
     
-    /**
-     * addPermissionsForUri add permissions from given permission configuration
-     * with assumption that resource is of type URI
-     * @param permission configuration
-     */
-    private void addPermissionsForUri(Permission perm,
-            PermissionRole permRole) throws PermissionException {
-        List<String> principals = new ArrayList<String>();
-        if (!perm.getCsid().equals(permRole.getPermission().get(0).getPermissionId())) {
-            throw new IllegalArgumentException("permission ids do not"
-                    + " match for role=" + permRole.getRole().get(0).getRoleName()
-                    + " with permissionId=" + permRole.getPermission().get(0).getPermissionId()
-                    + " for permission with csid=" + perm.getCsid());
-        }
-        for (RoleValue roleValue : permRole.getRole()) {
-            principals.add(roleValue.getRoleName());
-        }
-        List<PermissionAction> permActions = perm.getAction();
-        for (PermissionAction permAction : permActions) {
-               try {
-                   CSpaceAction action = URIResourceImpl.getAction(permAction.getName());
-                   URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(),
-                           perm.getResourceName(), action);
-                   boolean grant = perm.getEffect().equals(EffectType.PERMIT) ? true : false;
-                   AuthZ.get().addPermissions(uriRes, principals.toArray(new String[0]), grant);
-               } catch (PermissionException e) {
-                       //
-                       // Only throw the exception if it is *not* an already-exists exception
-                       //
-                       if (e.getCause() instanceof AlreadyExistsException == false) {
-                               throw e;
-                       }
-               }
-        }
-    }
-
+    
     /**
      * getAction is a convenience method to get corresponding action for
      * given ActionType
index 593101fda8ad5d2999989cef8a17c653a3b8c3d0..a9b3dc2b3807549d97815339592088fbd6fd5c48 100644 (file)
@@ -96,7 +96,7 @@ public class AuthorizationStore {
             em.getTransaction().commit();
             String id = null;
             try{
-                id = (String) JaxbUtils.getValue(entity, "getCsid");
+                id = (String) JaxbUtils.getValue(entity, "getCsid"); //NOTE: Not all entities have a CSID attribute
             } catch(NoSuchMethodException nsme) {
                 //do nothing ok, relationship does not have csid
             }
index cb15ea4fef72e5156729b92005d182a58d81944f..65dccb52da1df3ee18ccaf0c0f6fb65d086264f7 100644 (file)
@@ -7,7 +7,6 @@
     </parent>\r
 \r
     <modelVersion>4.0.0</modelVersion>\r
-    <groupId>org.collectionspace.services</groupId>\r
     <artifactId>org.collectionspace.services.common</artifactId>\r
     <name>services.common</name>\r
     <packaging>jar</packaging>\r
             <groupId>commons-io</groupId>\r
             <artifactId>commons-io</artifactId>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.security</groupId>\r
+            <artifactId>spring-security-acl</artifactId>\r
+            <version>${spring.security.version}</version>\r
+            <scope>provided</scope>\r
+        </dependency>        \r
     </dependencies>\r
 \r
     <repositories>\r
index 2151c31ca703df565ed705bba628f84c692f9e4f..c8c1b4118bf3f9d7ed6d7a96f19f29dcba5c63af 100644 (file)
@@ -18,6 +18,7 @@ import javax.servlet.ServletContext;
 import javax.sql.DataSource;\r
 \r
 import org.collectionspace.authentication.AuthN;\r
+import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;\r
 import org.collectionspace.services.common.config.ServicesConfigReaderImpl;\r
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
 import org.collectionspace.services.common.init.IInitHandler;\r
@@ -53,14 +54,6 @@ public class ServiceMain {
     private ServicesConfigReaderImpl servicesConfigReader;\r
     private TenantBindingConfigReaderImpl tenantBindingConfigReader;\r
     \r
-    private static final String TENANT_ADMIN_ACCT_PREFIX = "admin@"; \r
-    private static final String TENANT_READER_ACCT_PREFIX = "reader@"; \r
-    private static final String ROLE_PREFIX = "ROLE_"; \r
-    private static final String SPRING_ADMIN_ROLE = "ROLE_SPRING_ADMIN"; \r
-    private static final String TENANT_ADMIN_ROLE_SUFFIX = "_TENANT_ADMINISTRATOR"; \r
-    private static final String TENANT_READER_ROLE_SUFFIX = "_TENANT_READER"; \r
-    private static final String DEFAULT_ADMIN_PASSWORD = "Administrator";\r
-    private static final String DEFAULT_READER_PASSWORD = "reader";\r
     private static final String SERVER_HOME_PROPERTY = "catalina.home";\r
     \r
     private ServiceMain() {\r
@@ -151,7 +144,7 @@ public class ServiceMain {
         // Create all the default user accounts\r
         //\r
         try {\r
-               createDefaultAccounts();\r
+               AuthorizationCommon.createDefaultAccounts(tenantBindingConfigReader);\r
         } catch(Exception e) {\r
                logger.error("Default accounts setup failed with exception(s): " + e.getLocalizedMessage());\r
         }\r
@@ -209,396 +202,6 @@ public class ServiceMain {
         }\r
     }\r
     \r
-    /*\r
-     * FIXME: REM - This method is way too big -over 300 lines!  We need to break it up into\r
-     * smaller, discrete, sub-methods.\r
-     */\r
-    private void createDefaultAccounts() {\r
-       if (logger.isDebugEnabled()) {\r
-               logger.debug("ServiceMain.createDefaultAccounts starting...");\r
-       }\r
-        Hashtable<String, TenantBindingType> tenantBindings =\r
-               tenantBindingConfigReader.getTenantBindings();\r
-        Hashtable<String, String> tenantInfo = new Hashtable<String, String>();\r
-        for (TenantBindingType tenantBinding : tenantBindings.values()) {\r
-               String tId = tenantBinding.getId();\r
-               String tName = tenantBinding.getName();\r
-               tenantInfo.put(tId, tName);\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts found configured tenant id: "+tId+" name: "+tName);\r
-               }\r
-        }\r
-        Connection conn = null;\r
-        PreparedStatement pstmt = null;\r
-       Statement stmt = null;\r
-        // TODO - need to put in tests for existence first.\r
-        // We could just look for the accounts per tenant up front, and assume that\r
-        // the rest is there if the accounts are.\r
-        // Could add a sql script to remove these if need be - Spring only does roles, \r
-        // and we're not touching that, so we could safely toss the \r
-        // accounts, users, account-tenants, account-roles, and start over.\r
-        try {\r
-               conn = getConnection();\r
-               // First find or create the tenants\r
-               String queryTenantSQL = \r
-                       "SELECT id,name FROM tenants";\r
-               stmt = conn.createStatement();\r
-                       ResultSet rs = stmt.executeQuery(queryTenantSQL);\r
-               ArrayList<String> existingTenants = new ArrayList<String>();\r
-                       while (rs.next()) {\r
-                               String tId = rs.getString("id");\r
-                               String tName = rs.getString("name");\r
-                               if(tenantInfo.containsKey(tId)) {\r
-                                       existingTenants.add(tId);\r
-                                       if(!tenantInfo.get(tId).equalsIgnoreCase(tName)) {\r
-                                               logger.warn("Configured name for tenant: "\r
-                                                               +tId+" in repository: "+tName\r
-                                                               +" does not match config'd name: "+ tenantInfo.get(tId));\r
-                                       }\r
-                               }\r
-                       }\r
-                       rs.close();\r
-\r
-               String insertTenantSQL = \r
-                       "INSERT INTO tenants (id,name,created_at) VALUES (?,?, now())";\r
-               pstmt = conn.prepareStatement(insertTenantSQL); // create a statement\r
-               for(String tId : tenantInfo.keySet()) {\r
-                       if(existingTenants.contains(tId)) {\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts: tenant exists (skipping): "\r
-                                               +tenantInfo.get(tId));\r
-                       }\r
-                               continue;\r
-                       }\r
-                       pstmt.setString(1, tId);                                        // set id param\r
-                       pstmt.setString(2, tenantInfo.get(tId));        // set name param\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts adding entry for tenant: "+tId);\r
-               }\r
-                       pstmt.executeUpdate();\r
-               }\r
-               pstmt.close();\r
-               // Second find or create the users\r
-               String queryUserSQL = \r
-                       "SELECT username FROM users WHERE username LIKE '"\r
-                               +TENANT_ADMIN_ACCT_PREFIX+"%' OR username LIKE '"\r
-                               +TENANT_READER_ACCT_PREFIX+"%'";\r
-                       rs = stmt.executeQuery(queryUserSQL);\r
-               ArrayList<String> usersInRepo = new ArrayList<String>();\r
-                       while (rs.next()) {\r
-                               String uName = rs.getString("username");\r
-                               usersInRepo.add(uName);\r
-                       }\r
-                       rs.close();\r
-               String insertUserSQL = \r
-                       "INSERT INTO users (username,passwd, created_at)"\r
-                       +" VALUES (?,?, now())";\r
-               pstmt = conn.prepareStatement(insertUserSQL); // create a statement\r
-               for(String tName : tenantInfo.values()) {\r
-                       String adminAcctName = getDefaultAdminUserID(tName);\r
-                       if(!usersInRepo.contains(adminAcctName)) {\r
-                               String secEncPasswd = SecurityUtils.createPasswordHash(\r
-                                               adminAcctName, DEFAULT_ADMIN_PASSWORD);\r
-                               pstmt.setString(1, adminAcctName);      // set username param\r
-                               pstmt.setString(2, secEncPasswd);       // set passwd param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts adding user: "\r
-                                               +adminAcctName+" for tenant: "+tName);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       } else if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts: user: "+adminAcctName\r
-                                                       +" already exists - skipping.");\r
-               }\r
-\r
-\r
-                       String readerAcctName =  getDefaultReaderUserID(tName);\r
-                       if(!usersInRepo.contains(readerAcctName)) {\r
-                               String secEncPasswd = SecurityUtils.createPasswordHash(\r
-                                               readerAcctName, DEFAULT_READER_PASSWORD);\r
-                               pstmt.setString(1, readerAcctName);     // set username param\r
-                               pstmt.setString(2, secEncPasswd);       // set passwd param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts adding user: "\r
-                                               +readerAcctName+" for tenant: "+tName);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       } else if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts: user: "+readerAcctName\r
-                                                       +" already exists - skipping.");\r
-                       }\r
-               }\r
-               pstmt.close();\r
-               // Third, create the accounts. Assume that if the users were already there,\r
-               // then the accounts were as well\r
-            String insertAccountSQL = \r
-               "INSERT INTO accounts_common "\r
-               + "(csid, email, userid, status, screen_name, metadata_protection, roles_protection, created_at) "\r
-               + "VALUES (?,?,?,'ACTIVE',?, 'immutable', 'immutable', now())";\r
-            Hashtable<String, String> tenantAdminAcctCSIDs = new Hashtable<String, String>();\r
-            Hashtable<String, String> tenantReaderAcctCSIDs = new Hashtable<String, String>();\r
-               pstmt = conn.prepareStatement(insertAccountSQL); // create a statement\r
-               for(String tId : tenantInfo.keySet()) {\r
-                       String tName = tenantInfo.get(tId);\r
-               String adminCSID = UUID.randomUUID().toString();\r
-               tenantAdminAcctCSIDs.put(tId, adminCSID);\r
-                       String adminAcctName =  getDefaultAdminUserID(tName);\r
-                       if(!usersInRepo.contains(adminAcctName)) {\r
-                               pstmt.setString(1, adminCSID);                  // set csid param\r
-                               pstmt.setString(2, adminAcctName);      // set email param (bogus)\r
-                               pstmt.setString(3, adminAcctName);      // set userid param\r
-                               pstmt.setString(4, "Administrator");// set screen name param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts adding account: "\r
-                                               +adminAcctName+" for tenant: "+tName);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       } else if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts: user: "+adminAcctName\r
-                                                       +" already exists - skipping account generation.");\r
-                       }\r
-\r
-                       String readerCSID = UUID.randomUUID().toString();       \r
-               tenantReaderAcctCSIDs.put(tId, readerCSID);\r
-                       String readerAcctName =  getDefaultReaderUserID(tName);\r
-                       if(!usersInRepo.contains(readerAcctName)) {\r
-                               pstmt.setString(1, readerCSID);         // set csid param\r
-                               pstmt.setString(2, readerAcctName);     // set email param (bogus)\r
-                               pstmt.setString(3, readerAcctName);     // set userid param\r
-                               pstmt.setString(4, "Reader");           // set screen name param\r
-                               if (logger.isDebugEnabled()) {\r
-                                       logger.debug("createDefaultAccounts adding account: "\r
-                                                       +readerAcctName+" for tenant: "+tName);\r
-                               }\r
-                               pstmt.executeUpdate();\r
-                       } else if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts: user: "+readerAcctName\r
-                                                       +" already exists - skipping account creation.");\r
-                       }\r
-               }\r
-               pstmt.close();\r
-               // Fourth, bind accounts to tenants. Assume that if the users were already there,\r
-               // then the accounts were bound to tenants correctly\r
-               String insertAccountTenantSQL;\r
-               DatabaseProductType databaseProductType = JDBCTools.getDatabaseProductType();\r
-               if (databaseProductType == DatabaseProductType.MYSQL) {\r
-                       insertAccountTenantSQL =\r
-                               "INSERT INTO accounts_tenants (TENANTS_ACCOUNTSCOMMON_CSID,tenant_id) "\r
-                               + " VALUES(?, ?)";\r
-               } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
-                       insertAccountTenantSQL =\r
-                               "INSERT INTO accounts_tenants (HJID, TENANTS_ACCOUNTSCOMMON_CSID,tenant_id) "\r
-                               + " VALUES(nextval('hibernate_sequence'), ?, ?)";\r
-               } else {\r
-                       throw new Exception("Unrecognized database system.");\r
-               }\r
-               pstmt = conn.prepareStatement(insertAccountTenantSQL); // create a statement\r
-               for(String tId : tenantInfo.keySet()) {\r
-                       String tName = tenantInfo.get(tId);\r
-                       if(!usersInRepo.contains(getDefaultAdminUserID(tName))) {\r
-                               String adminAcct = tenantAdminAcctCSIDs.get(tId);\r
-                               pstmt.setString(1, adminAcct);          // set acct CSID param\r
-                               pstmt.setString(2, tId);                        // set tenant_id param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts binding account id: "\r
-                                               +adminAcct+" to tenant id: "+tId);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       }\r
-                       if(!usersInRepo.contains(getDefaultReaderUserID(tName))) {\r
-                               String readerAcct = tenantReaderAcctCSIDs.get(tId);\r
-                               pstmt.setString(1, readerAcct);         // set acct CSID param\r
-                               pstmt.setString(2, tId);                        // set tenant_id param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts binding account id: "\r
-                                               +readerAcct+" to tenant id: "+tId);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       }\r
-               }\r
-               pstmt.close();\r
-               // Fifth, fetch and save the default roles\r
-                       String springAdminRoleCSID = null;\r
-               String querySpringRole = \r
-                       "SELECT csid from roles WHERE rolename='"+SPRING_ADMIN_ROLE+"'";\r
-                       rs = stmt.executeQuery(querySpringRole);\r
-               if(rs.next()) {\r
-                       springAdminRoleCSID = rs.getString(1);\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts found Spring Admin role: "\r
-                                       +springAdminRoleCSID);\r
-               }\r
-               } else {\r
-                String insertSpringAdminRoleSQL =\r
-                       "INSERT INTO roles (csid, rolename, displayName, rolegroup, created_at, tenant_id) "\r
-                       + "VALUES ('-1', 'ROLE_SPRING_ADMIN', 'SPRING_ADMIN', 'Spring Security Administrator', now(), '0')";\r
-                       stmt.executeUpdate(insertSpringAdminRoleSQL);\r
-                       springAdminRoleCSID = "-1";\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts CREATED Spring Admin role: "\r
-                                       +springAdminRoleCSID);\r
-               }\r
-               }\r
-               rs.close();\r
-               String getRoleCSIDSql =\r
-                       "SELECT csid from roles WHERE tenant_id=? and rolename=?";\r
-               pstmt = conn.prepareStatement(getRoleCSIDSql); // create a statement\r
-               rs = null;\r
-            Hashtable<String, String> tenantAdminRoleCSIDs = new Hashtable<String, String>();\r
-            Hashtable<String, String> tenantReaderRoleCSIDs = new Hashtable<String, String>();\r
-               for(String tId : tenantInfo.keySet()) {\r
-                       pstmt.setString(1, tId);                                                // set tenant_id param\r
-                       pstmt.setString(2, getDefaultAdminRole(tId));   // set rolename param\r
-                       rs = pstmt.executeQuery();\r
-                       // extract data from the ResultSet\r
-                       if(!rs.next()) {\r
-                               throw new RuntimeException("Cannot find role: "+getDefaultAdminRole(tId)\r
-                                               +" for tenant id: "+tId+" in roles!");\r
-                       }\r
-                       String tenantAdminRoleCSID = rs.getString(1);\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts found role: "\r
-                                       +getDefaultAdminRole(tId)+"("+tenantAdminRoleCSID\r
-                                       +") for tenant id: "+tId);\r
-               }\r
-                       tenantAdminRoleCSIDs.put(tId, tenantAdminRoleCSID);\r
-                       pstmt.setString(1, tId);                                                // set tenant_id param\r
-                       pstmt.setString(2, getDefaultReaderRole(tId));  // set rolename param\r
-                       rs.close();\r
-                       rs = pstmt.executeQuery();\r
-                       // extract data from the ResultSet\r
-                       if(!rs.next()) {\r
-                               throw new RuntimeException("Cannot find role: "+getDefaultReaderRole(tId)\r
-                                               +" for tenant id: "+tId+" in roles!");\r
-                       }\r
-                       String tenantReaderRoleCSID = rs.getString(1);\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts found role: "\r
-                                       +getDefaultReaderRole(tId)+"("+tenantReaderRoleCSID\r
-                                       +") for tenant id: "+tId);\r
-               }\r
-                       tenantReaderRoleCSIDs.put(tId, tenantReaderRoleCSID);\r
-                       rs.close();\r
-               }\r
-               pstmt.close();\r
-               // Sixth, bind the accounts to roles. If the users already existed,\r
-               // we'll assume they were set up correctly.\r
-                                       String insertAccountRoleSQL;\r
-                                       if (databaseProductType == DatabaseProductType.MYSQL) {\r
-                                               insertAccountRoleSQL =\r
-                                               "INSERT INTO accounts_roles(account_id, user_id, role_id, role_name, created_at)"\r
-                                                       +" VALUES(?, ?, ?, ?, now())";\r
-                                       } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
-                                               insertAccountRoleSQL =\r
-                                               "INSERT INTO accounts_roles(HJID, account_id, user_id, role_id, role_name, created_at)"\r
-                                                       +" VALUES(nextval('hibernate_sequence'), ?, ?, ?, ?, now())";\r
-                                       } else {\r
-                                                       throw new Exception("Unrecognized database system.");\r
-                                       }\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("createDefaultAccounts binding accounts to roles with SQL:\n"\r
-                                       +insertAccountRoleSQL);\r
-               }\r
-               pstmt = conn.prepareStatement(insertAccountRoleSQL); // create a statement\r
-               for(String tId : tenantInfo.keySet()) {\r
-                       String adminUserId =  getDefaultAdminUserID(tenantInfo.get(tId));\r
-                       if(!usersInRepo.contains(adminUserId)) {\r
-                       String adminAcct = tenantAdminAcctCSIDs.get(tId);\r
-                               String adminRoleId = tenantAdminRoleCSIDs.get(tId);\r
-                               pstmt.setString(1, adminAcct);          // set acct CSID param\r
-                               pstmt.setString(2, adminUserId);        // set user_id param\r
-                               pstmt.setString(3, adminRoleId);        // set role_id param\r
-                               pstmt.setString(4, getDefaultAdminRole(tId));   // set rolename param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts binding account: "\r
-                                               +adminUserId+" to Admin role("+adminRoleId\r
-                                               +") for tenant id: "+tId);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                               // Now add the Spring Admin Role to the admin accounts\r
-                               pstmt.setString(3, springAdminRoleCSID);        // set role_id param\r
-                               pstmt.setString(4, SPRING_ADMIN_ROLE);          // set rolename param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts binding account: "\r
-                                               +adminUserId+" to Spring Admin role: "+springAdminRoleCSID);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       }\r
-                       String readerUserId = getDefaultReaderUserID(tenantInfo.get(tId));\r
-                       if(!usersInRepo.contains(readerUserId)) {\r
-                               String readerAcct = tenantReaderAcctCSIDs.get(tId);\r
-                               String readerRoleId = tenantReaderRoleCSIDs.get(tId);\r
-                               pstmt.setString(1, readerAcct);         // set acct CSID param\r
-                               pstmt.setString(2, readerUserId);       // set user_id param\r
-                               pstmt.setString(3, readerRoleId);       // set role_id param\r
-                               pstmt.setString(4, getDefaultReaderRole(tId));  // set rolename param\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("createDefaultAccounts binding account: "\r
-                                               +readerUserId+" to Reader role("+readerRoleId\r
-                                               +") for tenant id: "+tId);\r
-                       }\r
-                               pstmt.executeUpdate();\r
-                       }\r
-               }\r
-               pstmt.close();\r
-                       stmt.close();\r
-        } catch (RuntimeException rte) {\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("Exception in createDefaultAccounts: "+\r
-                                               rte.getLocalizedMessage());\r
-                       logger.debug(rte.getStackTrace().toString());\r
-               }\r
-            throw rte;\r
-        } catch (SQLException sqle) {\r
-            // SQLExceptions can be chained. We have at least one exception, so\r
-            // set up a loop to make sure we let the user know about all of them\r
-            // if there happens to be more than one.\r
-               if (logger.isDebugEnabled()) {\r
-                       SQLException tempException = sqle;\r
-                       while (null != tempException) {\r
-                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());\r
-                               tempException = tempException.getNextException();\r
-                       }\r
-                       logger.debug(sqle.getStackTrace().toString());\r
-               }\r
-            throw new RuntimeException("SQL problem in createDefaultAccounts: ", sqle);\r
-        } catch (Exception e) {\r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("Exception in createDefaultAccounts: "+\r
-                                               e.getLocalizedMessage());\r
-               }\r
-        } finally {\r
-               try {\r
-               if(conn!=null)\r
-                    conn.close();\r
-               if(pstmt!=null)\r
-                    pstmt.close();\r
-               if(stmt!=null)\r
-                    stmt.close();\r
-            } catch (SQLException sqle) {\r
-               if (logger.isDebugEnabled()) {\r
-                               logger.debug("SQL Exception closing statement/connection: "\r
-                                               + sqle.getLocalizedMessage());\r
-               }\r
-               }\r
-        }      \r
-    }\r
-    \r
-    private String getDefaultAdminRole(String tenantId) {\r
-       return ROLE_PREFIX+tenantId+TENANT_ADMIN_ROLE_SUFFIX;\r
-    }\r
-    \r
-    private String getDefaultReaderRole(String tenantId) {\r
-       return ROLE_PREFIX+tenantId+TENANT_READER_ROLE_SUFFIX;\r
-    }\r
-    \r
-    private String getDefaultAdminUserID(String tenantName) {\r
-       return TENANT_ADMIN_ACCT_PREFIX+tenantName;\r
-    }\r
-    \r
-    private String getDefaultReaderUserID(String tenantName) {\r
-       return TENANT_READER_ACCT_PREFIX+tenantName;\r
-    }\r
 \r
     public void firePostInitHandlers() throws Exception {\r
        DataSource dataSource = JDBCTools.getDataSource(JDBCTools.NUXEO_REPOSITORY_NAME);\r
@@ -649,10 +252,6 @@ public class ServiceMain {
         return null;\r
     }\r
 \r
-    private Connection getConnection() throws NamingException, SQLException {\r
-        return JDBCTools.getConnection(JDBCTools.CSPACE_REPOSITORY_NAME);\r
-    }\r
-\r
     void retrieveAllWorkspaceIds() throws Exception {\r
         //all configs are read, connector is initialized, retrieve workspaceids\r
         Hashtable<String, TenantBindingType> tenantBindings =\r
index 62ac660e8ff48c72ee816092ef2591e0211f2f05..68ceaffa976d6385071dfeb821348fc6ba6bd7e0 100644 (file)
@@ -1,8 +1,495 @@
 package org.collectionspace.services.common.authorization_mgt;\r
 \r
+import java.sql.Connection;\r
+import java.sql.PreparedStatement;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.util.ArrayList;\r
+import java.util.Hashtable;\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+import javax.naming.NamingException;\r
+\r
+import org.collectionspace.services.authorization.AuthZ;\r
+import org.collectionspace.services.authorization.CSpaceAction;\r
+import org.collectionspace.services.authorization.PermissionException;\r
+import org.collectionspace.services.authorization.PermissionRole;\r
+import org.collectionspace.services.authorization.RoleValue;\r
+import org.collectionspace.services.authorization.URIResourceImpl;\r
+import org.collectionspace.services.authorization.perms.EffectType;\r
+import org.collectionspace.services.authorization.perms.Permission;\r
+import org.collectionspace.services.authorization.perms.PermissionAction;\r
+import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
+import org.collectionspace.services.common.security.SecurityUtils;\r
+import org.collectionspace.services.common.storage.DatabaseProductType;\r
+import org.collectionspace.services.common.storage.JDBCTools;\r
+import org.collectionspace.services.common.tenant.TenantBindingType;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.security.acls.model.AlreadyExistsException;\r
+\r
+\r
 public class AuthorizationCommon {\r
+    final static Logger logger = LoggerFactory.getLogger(AuthorizationCommon.class);\r
+\r
+    public static final String TENANT_ADMIN_ACCT_PREFIX = "admin@"; \r
+    public static final String TENANT_READER_ACCT_PREFIX = "reader@"; \r
+    public static final String ROLE_PREFIX = "ROLE_"; \r
+    public static final String SPRING_ADMIN_ROLE = "ROLE_SPRING_ADMIN"; \r
+    public static final String TENANT_ADMIN_ROLE_SUFFIX = "_TENANT_ADMINISTRATOR"; \r
+    public static final String TENANT_READER_ROLE_SUFFIX = "_TENANT_READER"; \r
+    public static final String DEFAULT_ADMIN_PASSWORD = "Administrator";\r
+    public static final String DEFAULT_READER_PASSWORD = "reader";\r
 \r
     public static String ROLE_SPRING_ADMIN_ID = "-1";\r
-    public static String ROLE_SPRING_ADMIN_NAME = "ROLE_SPRING_ADMIN";    \r
+    public static String ROLE_SPRING_ADMIN_NAME = "ROLE_SPRING_ADMIN";\r
+\r
+    /**\r
+     * addPermissionsForUri add permissions from given permission configuration\r
+     * with assumption that resource is of type URI\r
+     * @param permission configuration\r
+     */\r
+    public static void addPermissionsForUri(Permission perm,\r
+            PermissionRole permRole) throws PermissionException {\r
+        List<String> principals = new ArrayList<String>();\r
+        if (!perm.getCsid().equals(permRole.getPermission().get(0).getPermissionId())) {\r
+            throw new IllegalArgumentException("permission ids do not"\r
+                    + " match for role=" + permRole.getRole().get(0).getRoleName()\r
+                    + " with permissionId=" + permRole.getPermission().get(0).getPermissionId()\r
+                    + " for permission with csid=" + perm.getCsid());\r
+        }\r
+        for (RoleValue roleValue : permRole.getRole()) {\r
+            principals.add(roleValue.getRoleName());\r
+        }\r
+        List<PermissionAction> permActions = perm.getAction();\r
+        for (PermissionAction permAction : permActions) {\r
+               try {\r
+                   CSpaceAction action = URIResourceImpl.getAction(permAction.getName()); \r
+                   URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(),\r
+                           perm.getResourceName(), action);\r
+                   boolean grant = perm.getEffect().equals(EffectType.PERMIT) ? true : false;\r
+                   AuthZ.get().addPermissions(uriRes, principals.toArray(new String[0]), grant);//CSPACE-4967\r
+               } catch (PermissionException e) {\r
+                       //\r
+                       // Only throw the exception if it is *not* an already-exists exception\r
+                       //\r
+                       if (e.getCause() instanceof AlreadyExistsException == false) {\r
+                               throw e;\r
+                       }\r
+               }\r
+        }\r
+    }\r
+    \r
+    private static Connection getConnection() throws NamingException, SQLException {\r
+        return JDBCTools.getConnection(JDBCTools.CSPACE_REPOSITORY_NAME);\r
+    }\r
+    \r
+    public static void createDefaultPermissions(TenantBindingConfigReaderImpl tenantBindingConfigReader)\r
+    {\r
+       // For each service binding in each tenancy, get the Nuxeo document type and retrieve it's life cycle type.  For\r
+       // that life cycle type, ask Nuxeo for all the configured transitions.  For each of those transitions,\r
+       // create:\r
+       //              * a URI of the form - /<service>/*/workflow/<transition>\r
+       //              * a CRUDL Permission for the URI\r
+       //              * a RL Permission for the URI\r
+       //              * a PermissionRole for admin role\r
+       //              * a PermissionRole for the reader role\r
+       //              \r
+       //              * add a new Permission/PermissionRole tuple to the Spring AuthZ tables\r
+       //              * persist the new Permission, and PermissionRole to the cspace database\r
+    }\r
+    \r
+    /*\r
+     * FIXME: REM - This method is way too big -over 300 lines!  We need to break it up into\r
+     * smaller, discrete, sub-methods.\r
+     */\r
+    public static void createDefaultAccounts(TenantBindingConfigReaderImpl tenantBindingConfigReader) {\r
+       if (logger.isDebugEnabled()) {\r
+               logger.debug("ServiceMain.createDefaultAccounts starting...");\r
+       }\r
+       \r
+        Hashtable<String, TenantBindingType> tenantBindings =\r
+               tenantBindingConfigReader.getTenantBindings();\r
+        Hashtable<String, String> tenantInfo = new Hashtable<String, String>();\r
+        for (TenantBindingType tenantBinding : tenantBindings.values()) {\r
+               String tId = tenantBinding.getId();\r
+               String tName = tenantBinding.getName();\r
+               tenantInfo.put(tId, tName);\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts found configured tenant id: "+tId+" name: "+tName);\r
+               }\r
+        }\r
+        Connection conn = null;\r
+        PreparedStatement pstmt = null;\r
+       Statement stmt = null;\r
+        // TODO - need to put in tests for existence first.\r
+        // We could just look for the accounts per tenant up front, and assume that\r
+        // the rest is there if the accounts are.\r
+        // Could add a sql script to remove these if need be - Spring only does roles, \r
+        // and we're not touching that, so we could safely toss the \r
+        // accounts, users, account-tenants, account-roles, and start over.\r
+        try {\r
+               conn = getConnection();\r
+               // First find or create the tenants\r
+               String queryTenantSQL = \r
+                       "SELECT id,name FROM tenants";\r
+               stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery(queryTenantSQL);\r
+               ArrayList<String> existingTenants = new ArrayList<String>();\r
+                       while (rs.next()) {\r
+                               String tId = rs.getString("id");\r
+                               String tName = rs.getString("name");\r
+                               if(tenantInfo.containsKey(tId)) {\r
+                                       existingTenants.add(tId);\r
+                                       if(!tenantInfo.get(tId).equalsIgnoreCase(tName)) {\r
+                                               logger.warn("Configured name for tenant: "\r
+                                                               +tId+" in repository: "+tName\r
+                                                               +" does not match config'd name: "+ tenantInfo.get(tId));\r
+                                       }\r
+                               }\r
+                       }\r
+                       rs.close();\r
+\r
+               String insertTenantSQL = \r
+                       "INSERT INTO tenants (id,name,created_at) VALUES (?,?, now())";\r
+               pstmt = conn.prepareStatement(insertTenantSQL); // create a statement\r
+               for(String tId : tenantInfo.keySet()) {\r
+                       if(existingTenants.contains(tId)) {\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts: tenant exists (skipping): "\r
+                                               +tenantInfo.get(tId));\r
+                       }\r
+                               continue;\r
+                       }\r
+                       pstmt.setString(1, tId);                                        // set id param\r
+                       pstmt.setString(2, tenantInfo.get(tId));        // set name param\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts adding entry for tenant: "+tId);\r
+               }\r
+                       pstmt.executeUpdate();\r
+               }\r
+               pstmt.close();\r
+               // Second find or create the users\r
+               String queryUserSQL = \r
+                       "SELECT username FROM users WHERE username LIKE '"\r
+                               +TENANT_ADMIN_ACCT_PREFIX+"%' OR username LIKE '"\r
+                               +TENANT_READER_ACCT_PREFIX+"%'";\r
+                       rs = stmt.executeQuery(queryUserSQL);\r
+               ArrayList<String> usersInRepo = new ArrayList<String>();\r
+                       while (rs.next()) {\r
+                               String uName = rs.getString("username");\r
+                               usersInRepo.add(uName);\r
+                       }\r
+                       rs.close();\r
+               String insertUserSQL = \r
+                       "INSERT INTO users (username,passwd, created_at)"\r
+                       +" VALUES (?,?, now())";\r
+               pstmt = conn.prepareStatement(insertUserSQL); // create a statement\r
+               for(String tName : tenantInfo.values()) {\r
+                       String adminAcctName = getDefaultAdminUserID(tName);\r
+                       if(!usersInRepo.contains(adminAcctName)) {\r
+                               String secEncPasswd = SecurityUtils.createPasswordHash(\r
+                                               adminAcctName, DEFAULT_ADMIN_PASSWORD);\r
+                               pstmt.setString(1, adminAcctName);      // set username param\r
+                               pstmt.setString(2, secEncPasswd);       // set passwd param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts adding user: "\r
+                                               +adminAcctName+" for tenant: "+tName);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       } else if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts: user: "+adminAcctName\r
+                                                       +" already exists - skipping.");\r
+               }\r
+\r
+\r
+                       String readerAcctName =  getDefaultReaderUserID(tName);\r
+                       if(!usersInRepo.contains(readerAcctName)) {\r
+                               String secEncPasswd = SecurityUtils.createPasswordHash(\r
+                                               readerAcctName, DEFAULT_READER_PASSWORD);\r
+                               pstmt.setString(1, readerAcctName);     // set username param\r
+                               pstmt.setString(2, secEncPasswd);       // set passwd param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts adding user: "\r
+                                               +readerAcctName+" for tenant: "+tName);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       } else if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts: user: "+readerAcctName\r
+                                                       +" already exists - skipping.");\r
+                       }\r
+               }\r
+               pstmt.close();\r
+               // Third, create the accounts. Assume that if the users were already there,\r
+               // then the accounts were as well\r
+            String insertAccountSQL = \r
+               "INSERT INTO accounts_common "\r
+               + "(csid, email, userid, status, screen_name, metadata_protection, roles_protection, created_at) "\r
+               + "VALUES (?,?,?,'ACTIVE',?, 'immutable', 'immutable', now())";\r
+            Hashtable<String, String> tenantAdminAcctCSIDs = new Hashtable<String, String>();\r
+            Hashtable<String, String> tenantReaderAcctCSIDs = new Hashtable<String, String>();\r
+               pstmt = conn.prepareStatement(insertAccountSQL); // create a statement\r
+               for(String tId : tenantInfo.keySet()) {\r
+                       String tName = tenantInfo.get(tId);\r
+               String adminCSID = UUID.randomUUID().toString();\r
+               tenantAdminAcctCSIDs.put(tId, adminCSID);\r
+                       String adminAcctName =  getDefaultAdminUserID(tName);\r
+                       if(!usersInRepo.contains(adminAcctName)) {\r
+                               pstmt.setString(1, adminCSID);                  // set csid param\r
+                               pstmt.setString(2, adminAcctName);      // set email param (bogus)\r
+                               pstmt.setString(3, adminAcctName);      // set userid param\r
+                               pstmt.setString(4, "Administrator");// set screen name param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts adding account: "\r
+                                               +adminAcctName+" for tenant: "+tName);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       } else if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts: user: "+adminAcctName\r
+                                                       +" already exists - skipping account generation.");\r
+                       }\r
 \r
+                       String readerCSID = UUID.randomUUID().toString();       \r
+               tenantReaderAcctCSIDs.put(tId, readerCSID);\r
+                       String readerAcctName =  getDefaultReaderUserID(tName);\r
+                       if(!usersInRepo.contains(readerAcctName)) {\r
+                               pstmt.setString(1, readerCSID);         // set csid param\r
+                               pstmt.setString(2, readerAcctName);     // set email param (bogus)\r
+                               pstmt.setString(3, readerAcctName);     // set userid param\r
+                               pstmt.setString(4, "Reader");           // set screen name param\r
+                               if (logger.isDebugEnabled()) {\r
+                                       logger.debug("createDefaultAccounts adding account: "\r
+                                                       +readerAcctName+" for tenant: "+tName);\r
+                               }\r
+                               pstmt.executeUpdate();\r
+                       } else if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts: user: "+readerAcctName\r
+                                                       +" already exists - skipping account creation.");\r
+                       }\r
+               }\r
+               pstmt.close();\r
+               // Fourth, bind accounts to tenants. Assume that if the users were already there,\r
+               // then the accounts were bound to tenants correctly\r
+               String insertAccountTenantSQL;\r
+               DatabaseProductType databaseProductType = JDBCTools.getDatabaseProductType();\r
+               if (databaseProductType == DatabaseProductType.MYSQL) {\r
+                       insertAccountTenantSQL =\r
+                               "INSERT INTO accounts_tenants (TENANTS_ACCOUNTSCOMMON_CSID,tenant_id) "\r
+                               + " VALUES(?, ?)";\r
+               } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
+                       insertAccountTenantSQL =\r
+                               "INSERT INTO accounts_tenants (HJID, TENANTS_ACCOUNTSCOMMON_CSID,tenant_id) "\r
+                               + " VALUES(nextval('hibernate_sequence'), ?, ?)";\r
+               } else {\r
+                       throw new Exception("Unrecognized database system.");\r
+               }\r
+               pstmt = conn.prepareStatement(insertAccountTenantSQL); // create a statement\r
+               for(String tId : tenantInfo.keySet()) {\r
+                       String tName = tenantInfo.get(tId);\r
+                       if(!usersInRepo.contains(getDefaultAdminUserID(tName))) {\r
+                               String adminAcct = tenantAdminAcctCSIDs.get(tId);\r
+                               pstmt.setString(1, adminAcct);          // set acct CSID param\r
+                               pstmt.setString(2, tId);                        // set tenant_id param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts binding account id: "\r
+                                               +adminAcct+" to tenant id: "+tId);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       }\r
+                       if(!usersInRepo.contains(getDefaultReaderUserID(tName))) {\r
+                               String readerAcct = tenantReaderAcctCSIDs.get(tId);\r
+                               pstmt.setString(1, readerAcct);         // set acct CSID param\r
+                               pstmt.setString(2, tId);                        // set tenant_id param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts binding account id: "\r
+                                               +readerAcct+" to tenant id: "+tId);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       }\r
+               }\r
+               pstmt.close();\r
+               // Fifth, fetch and save the default roles\r
+                       String springAdminRoleCSID = null;\r
+               String querySpringRole = \r
+                       "SELECT csid from roles WHERE rolename='"+SPRING_ADMIN_ROLE+"'";\r
+                       rs = stmt.executeQuery(querySpringRole);\r
+               if(rs.next()) {\r
+                       springAdminRoleCSID = rs.getString(1);\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts found Spring Admin role: "\r
+                                       +springAdminRoleCSID);\r
+               }\r
+               } else {\r
+                String insertSpringAdminRoleSQL =\r
+                       "INSERT INTO roles (csid, rolename, displayName, rolegroup, created_at, tenant_id) "\r
+                       + "VALUES ('-1', 'ROLE_SPRING_ADMIN', 'SPRING_ADMIN', 'Spring Security Administrator', now(), '0')";\r
+                       stmt.executeUpdate(insertSpringAdminRoleSQL);\r
+                       springAdminRoleCSID = "-1";\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts CREATED Spring Admin role: "\r
+                                       +springAdminRoleCSID);\r
+               }\r
+               }\r
+               rs.close();\r
+               String getRoleCSIDSql =\r
+                       "SELECT csid from roles WHERE tenant_id=? and rolename=?";\r
+               pstmt = conn.prepareStatement(getRoleCSIDSql); // create a statement\r
+               rs = null;\r
+            Hashtable<String, String> tenantAdminRoleCSIDs = new Hashtable<String, String>();\r
+            Hashtable<String, String> tenantReaderRoleCSIDs = new Hashtable<String, String>();\r
+               for(String tId : tenantInfo.keySet()) {\r
+                       pstmt.setString(1, tId);                                                // set tenant_id param\r
+                       pstmt.setString(2, getDefaultAdminRole(tId));   // set rolename param\r
+                       rs = pstmt.executeQuery();\r
+                       // extract data from the ResultSet\r
+                       if(!rs.next()) {\r
+                               throw new RuntimeException("Cannot find role: "+getDefaultAdminRole(tId)\r
+                                               +" for tenant id: "+tId+" in roles!");\r
+                       }\r
+                       String tenantAdminRoleCSID = rs.getString(1);\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts found role: "\r
+                                       +getDefaultAdminRole(tId)+"("+tenantAdminRoleCSID\r
+                                       +") for tenant id: "+tId);\r
+               }\r
+                       tenantAdminRoleCSIDs.put(tId, tenantAdminRoleCSID);\r
+                       pstmt.setString(1, tId);                                                // set tenant_id param\r
+                       pstmt.setString(2, getDefaultReaderRole(tId));  // set rolename param\r
+                       rs.close();\r
+                       rs = pstmt.executeQuery();\r
+                       // extract data from the ResultSet\r
+                       if(!rs.next()) {\r
+                               throw new RuntimeException("Cannot find role: "+getDefaultReaderRole(tId)\r
+                                               +" for tenant id: "+tId+" in roles!");\r
+                       }\r
+                       String tenantReaderRoleCSID = rs.getString(1);\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts found role: "\r
+                                       +getDefaultReaderRole(tId)+"("+tenantReaderRoleCSID\r
+                                       +") for tenant id: "+tId);\r
+               }\r
+                       tenantReaderRoleCSIDs.put(tId, tenantReaderRoleCSID);\r
+                       rs.close();\r
+               }\r
+               pstmt.close();\r
+               // Sixth, bind the accounts to roles. If the users already existed,\r
+               // we'll assume they were set up correctly.\r
+                                       String insertAccountRoleSQL;\r
+                                       if (databaseProductType == DatabaseProductType.MYSQL) {\r
+                                               insertAccountRoleSQL =\r
+                                               "INSERT INTO accounts_roles(account_id, user_id, role_id, role_name, created_at)"\r
+                                                       +" VALUES(?, ?, ?, ?, now())";\r
+                                       } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
+                                               insertAccountRoleSQL =\r
+                                               "INSERT INTO accounts_roles(HJID, account_id, user_id, role_id, role_name, created_at)"\r
+                                                       +" VALUES(nextval('hibernate_sequence'), ?, ?, ?, ?, now())";\r
+                                       } else {\r
+                                                       throw new Exception("Unrecognized database system.");\r
+                                       }\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("createDefaultAccounts binding accounts to roles with SQL:\n"\r
+                                       +insertAccountRoleSQL);\r
+               }\r
+               pstmt = conn.prepareStatement(insertAccountRoleSQL); // create a statement\r
+               for(String tId : tenantInfo.keySet()) {\r
+                       String adminUserId =  getDefaultAdminUserID(tenantInfo.get(tId));\r
+                       if(!usersInRepo.contains(adminUserId)) {\r
+                       String adminAcct = tenantAdminAcctCSIDs.get(tId);\r
+                               String adminRoleId = tenantAdminRoleCSIDs.get(tId);\r
+                               pstmt.setString(1, adminAcct);          // set acct CSID param\r
+                               pstmt.setString(2, adminUserId);        // set user_id param\r
+                               pstmt.setString(3, adminRoleId);        // set role_id param\r
+                               pstmt.setString(4, getDefaultAdminRole(tId));   // set rolename param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts binding account: "\r
+                                               +adminUserId+" to Admin role("+adminRoleId\r
+                                               +") for tenant id: "+tId);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                               // Now add the Spring Admin Role to the admin accounts\r
+                               pstmt.setString(3, springAdminRoleCSID);        // set role_id param\r
+                               pstmt.setString(4, SPRING_ADMIN_ROLE);          // set rolename param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts binding account: "\r
+                                               +adminUserId+" to Spring Admin role: "+springAdminRoleCSID);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       }\r
+                       String readerUserId = getDefaultReaderUserID(tenantInfo.get(tId));\r
+                       if(!usersInRepo.contains(readerUserId)) {\r
+                               String readerAcct = tenantReaderAcctCSIDs.get(tId);\r
+                               String readerRoleId = tenantReaderRoleCSIDs.get(tId);\r
+                               pstmt.setString(1, readerAcct);         // set acct CSID param\r
+                               pstmt.setString(2, readerUserId);       // set user_id param\r
+                               pstmt.setString(3, readerRoleId);       // set role_id param\r
+                               pstmt.setString(4, getDefaultReaderRole(tId));  // set rolename param\r
+                       if (logger.isDebugEnabled()) {\r
+                               logger.debug("createDefaultAccounts binding account: "\r
+                                               +readerUserId+" to Reader role("+readerRoleId\r
+                                               +") for tenant id: "+tId);\r
+                       }\r
+                               pstmt.executeUpdate();\r
+                       }\r
+               }\r
+               pstmt.close();\r
+                       stmt.close();\r
+        } catch (RuntimeException rte) {\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("Exception in createDefaultAccounts: "+\r
+                                               rte.getLocalizedMessage());\r
+                       logger.debug(rte.getStackTrace().toString());\r
+               }\r
+            throw rte;\r
+        } catch (SQLException sqle) {\r
+            // SQLExceptions can be chained. We have at least one exception, so\r
+            // set up a loop to make sure we let the user know about all of them\r
+            // if there happens to be more than one.\r
+               if (logger.isDebugEnabled()) {\r
+                       SQLException tempException = sqle;\r
+                       while (null != tempException) {\r
+                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());\r
+                               tempException = tempException.getNextException();\r
+                       }\r
+                       logger.debug(sqle.getStackTrace().toString());\r
+               }\r
+            throw new RuntimeException("SQL problem in createDefaultAccounts: ", sqle);\r
+        } catch (Exception e) {\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("Exception in createDefaultAccounts: "+\r
+                                               e.getLocalizedMessage());\r
+               }\r
+        } finally {\r
+               try {\r
+               if(conn!=null)\r
+                    conn.close();\r
+               if(pstmt!=null)\r
+                    pstmt.close();\r
+               if(stmt!=null)\r
+                    stmt.close();\r
+            } catch (SQLException sqle) {\r
+               if (logger.isDebugEnabled()) {\r
+                               logger.debug("SQL Exception closing statement/connection: "\r
+                                               + sqle.getLocalizedMessage());\r
+               }\r
+               }\r
+        }      \r
+    }\r
+    \r
+    private static String getDefaultAdminRole(String tenantId) {\r
+       return ROLE_PREFIX+tenantId+TENANT_ADMIN_ROLE_SUFFIX;\r
+    }\r
+    \r
+    private static String getDefaultReaderRole(String tenantId) {\r
+       return ROLE_PREFIX+tenantId+TENANT_READER_ROLE_SUFFIX;\r
+    }\r
+    \r
+    private static String getDefaultAdminUserID(String tenantName) {\r
+       return TENANT_ADMIN_ACCT_PREFIX+tenantName;\r
+    }\r
+    \r
+    private static String getDefaultReaderUserID(String tenantName) {\r
+       return TENANT_READER_ACCT_PREFIX+tenantName;\r
+    }\r
 }\r