-- movingimages --
INSERT INTO `cspace`.`tenants` (`id`, `name`, `created_at`) VALUES ('1','movingimages.us', now());
-- pahma --
-INSERT INTO `cspace`.`tenants` (`id`, `name`, `created_at`) VALUES ('2','hearstmuseum.berkeley.edu', now());
+--INSERT INTO `cspace`.`tenants` (`id`, `name`, `created_at`) VALUES ('2','hearstmuseum.berkeley.edu', now());
-- Accounts
-- default test account --
INSERT INTO `cspace`.`accounts_common` (`csid`, `email`, `phone`, `mobile`, `userid`, `status`, `screen_name`, `created_at`) VALUES ('eeca40d7-dc77-4cc5-b489-16a53c75525a','test.test@berkeley.edu',NULL,NULL,'test','ACTIVE','test', now());
-- Additional account introduced during integration on release 0.6, and currently relied upon by the Application Layer.
-INSERT INTO `cspace`.`accounts_common` (`csid`, `email`, `phone`, `mobile`, `userid`, `status`, `screen_name`, `created_at`) VALUES ('251f98f3-0292-4f3e-aa95-455314050e1b','test@collectionspace.org',NULL,NULL,'test@collectionspace.org','ACTIVE','test@collectionspace.org', now());
+--INSERT INTO `cspace`.`accounts_common` (`csid`, `email`, `phone`, `mobile`, `userid`, `status`, `screen_name`, `created_at`) VALUES ('251f98f3-0292-4f3e-aa95-455314050e1b','test@collectionspace.org',NULL,NULL,'test@collectionspace.org','ACTIVE','test@collectionspace.org', now());
-- PAHMA test account --
-INSERT INTO `cspace`.`accounts_common` (`csid`, `email`, `phone`, `mobile`, `userid`, `status`, `screen_name`, `created_at`) VALUES ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7','test@hearstmuseum.berkeley.edu',NULL,NULL,'test-pahma','ACTIVE','test-pahma', now());
+--INSERT INTO `cspace`.`accounts_common` (`csid`, `email`, `phone`, `mobile`, `userid`, `status`, `screen_name`, `created_at`) VALUES ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7','test@hearstmuseum.berkeley.edu',NULL,NULL,'test-pahma','ACTIVE','test-pahma', now());
-- Association of accounts with tenants
INSERT INTO `cspace`.`accounts_tenants` (`TENANTS_ACCOUNTSCOMMON_CSID`, `tenant_id`) VALUES ('eeca40d7-dc77-4cc5-b489-16a53c75525a', '1');
-INSERT INTO `cspace`.`accounts_tenants` (`TENANTS_ACCOUNTSCOMMON_CSID`, `tenant_id`) VALUES ('251f98f3-0292-4f3e-aa95-455314050e1b', '1');
-INSERT INTO `cspace`.`accounts_tenants` (`TENANTS_ACCOUNTSCOMMON_CSID`, `tenant_id`) VALUES ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7', '2');
+--INSERT INTO `cspace`.`accounts_tenants` (`TENANTS_ACCOUNTSCOMMON_CSID`, `tenant_id`) VALUES ('251f98f3-0292-4f3e-aa95-455314050e1b', '1');
+--INSERT INTO `cspace`.`accounts_tenants` (`TENANTS_ACCOUNTSCOMMON_CSID`, `tenant_id`) VALUES ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7', '2');
-- default test user --\r
insert into `users` (`username`,`passwd`, `created_at`) VALUES ('test','n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=', now());\r
-- Additional account introduced during integration on release 0.6, and currently relied upon by the Application Layer.\r
-insert into `users` (`username`,`passwd`, `created_at`) VALUES ('test@collectionspace.org','NyaDNd1pMQRb3N+SYj/4GaZCRLU9DnRtQ4eXNJ1NpXg=', now());\r
+--insert into `users` (`username`,`passwd`, `created_at`) VALUES ('test@collectionspace.org','NyaDNd1pMQRb3N+SYj/4GaZCRLU9DnRtQ4eXNJ1NpXg=', now());\r
-- user for testing pahma deployment --\r
-insert into `users` (`username`,`passwd`, `created_at`) VALUES ('test-pahma','n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=', now());\r
+--insert into `users` (`username`,`passwd`, `created_at`) VALUES ('test-pahma','n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=', now());\r
public void seedPermissions(PermissionsList permList, PermissionsRolesList permRoleList)
throws Exception {
for (Permission p : permList.getPermissions()) {
- if (logger.isDebugEnabled()) {
- logger.debug("adding permission for res=" + p.getResourceName() +
+ if (logger.isTraceEnabled()) {
+ logger.trace("adding permission for res=" + p.getResourceName() +
" for tenant=" + p.getTenantId());
}
for (PermissionRole pr : permRoleList.getPermissionRoles()) {
<property name="providerAclService" ref="aclService"/>
<property name="providerPermissionEvaluator" ref="permissionEvaluator"/>
<property name="txManager" ref="transactionManager"/>
- </bean>
+ <property name="providerAclCache" ref="aclCache"/>
+ </bean>
</beans>
insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '0', 'ROLE_ADMINISTRATOR', now());\r
\r
-- Additional account introduced during integration on release 0.6, and currently relied upon by the Application Layer.\r
-insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('251f98f3-0292-4f3e-aa95-455314050e1b', 'test@collectionspace.org', '-1', 'ROLE_SPRING_ADMIN', now());\r
-insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('251f98f3-0292-4f3e-aa95-455314050e1b', 'test@collectionspace.org', '0', 'ROLE_ADMINISTRATOR', now());\r
+--insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('251f98f3-0292-4f3e-aa95-455314050e1b', 'test@collectionspace.org', '0', 'ROLE_ADMINISTRATOR', now());\r
\r
-- test account for pahma --\r
-insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7', 'test-pahma', '-1', 'ROLE_SPRING_ADMIN', now());\r
-insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7', 'test-pahma', '0', 'ROLE_ADMINISTRATOR', now());\r
+--insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('ff2b4440-ed0d-4892-adb4-b6999eba3ae7', 'test-pahma', '0', 'ROLE_ADMINISTRATOR', now());\r
\r
-- todo: barney is created in security test but accountrole is not yet created there, so add fake account id\r
-insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('1', 'barney', '2', 'ROLE_USERS', now());\r
+--insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('1', 'barney', '2', 'ROLE_USERS', now());\r
\r
\r
*/
public class SpringAuthorizationProvider implements CSpaceAuthorizationProvider {
- final Log log = LogFactory.getLog(SpringPermissionEvaluator.class);
+ final Log log = LogFactory.getLog(SpringAuthorizationProvider.class);
@Autowired
private MutableAclService providerAclService;
@Autowired
cspace.ssl=false\r
cspace.auth=true\r
# default user\r
-cspace.user=test\r
+cspace.user=admin@collectionspace.org\r
#cspace.user=test-pahma\r
-cspace.password=test\r
+cspace.password=Administrator\r
# default tenant\r
-cspace.tenant=1
\ No newline at end of file
+cspace.tenant=1\r
<!-- begin movingimages.us tenant meta-data -->
<tenant:tenantBinding
- id="1" name="movingimage.us" displayName="Museum of Moving Images" version="0.1">
+ id="1" name="collectionspace.org" displayName="CollectionSpace Demo" version="0.1">
<tenant:repositoryDomain name="default-domain" repositoryClient="nuxeo-java"/>
</tenant:serviceBindings>
</tenant:tenantBinding>
- <!-- end movingimages.us tenant meta-data -->
+ <!-- end collectionspace.org tenant meta-data -->
<!-- ##################################################################### -->
*/\r
package org.collectionspace.services.common;\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.InitialContext;\r
+import javax.naming.NamingException;\r
+import javax.security.auth.login.LoginException;\r
+import javax.sql.DataSource;\r
+import javax.ws.rs.WebApplicationException;\r
+import javax.ws.rs.core.Response;\r
\r
import org.collectionspace.services.common.config.ServicesConfigReaderImpl;\r
import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
+import org.collectionspace.services.common.security.SecurityUtils;\r
import org.collectionspace.services.common.tenant.TenantBindingType;\r
import org.collectionspace.services.common.types.PropertyItemType;\r
import org.collectionspace.services.common.types.PropertyType;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
+\r
/**\r
* Main class for Services layer. It reads configuration and performs service\r
* level initialization. It is a singleton.\r
private String serverRootDir = null;\r
private ServicesConfigReaderImpl servicesConfigReader;\r
private TenantBindingConfigReaderImpl tenantBindingConfigReader;\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
+ \r
+ private static String repositoryName = "CspaceDS";\r
\r
private ServiceMain() {\r
}\r
setServerRootDir();\r
readConfig();\r
propagateConfiguredProperties();\r
+ try {\r
+ createDefaultAccounts();\r
+ } catch(Exception e) {\r
+ logger.error("Default Account setup failed on exception: "+e.getLocalizedMessage());\r
+ }\r
if (getClientType().equals(ClientType.JAVA)) {\r
nuxeoConnector = NuxeoConnector.getInstance();\r
nuxeoConnector.initialize(\r
getServicesConfigReader().read();\r
\r
tenantBindingConfigReader = new TenantBindingConfigReaderImpl(getServerRootDir());\r
- getTenantBindingConfigReader().read();\r
+ tenantBindingConfigReader.read();\r
}\r
\r
private void propagateConfiguredProperties() {\r
}\r
}\r
}\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`, `created_at`) "\r
+ + "VALUES (?,?,?,'ACTIVE',?, 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
+ "INSERT INTO `accounts_tenants` (`TENANTS_ACCOUNTSCOMMON_CSID`,`tenant_id`) "\r
+ + "VALUES (?, ?)";\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 querySpringRole = \r
+ "SELECT `csid` from `Roles` WHERE `rolename`='"+SPRING_ADMIN_ROLE+"'";\r
+ rs = stmt.executeQuery(querySpringRole);\r
+ if(!rs.next()) {\r
+ throw new RuntimeException("Cannot find SPRING ADMIN role!");\r
+ }\r
+ String springAdminRoleCSID = rs.getString(1);\r
+ if (logger.isDebugEnabled()) {\r
+ logger.debug("createDefaultAccounts found Spring Admin role: "\r
+ +springAdminRoleCSID);\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
+ "INSERT INTO `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`)"\r
+ + " VALUES(?, ?, ?, ?, now())";\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
+ private Connection getConnection() throws LoginException, SQLException {\r
+ InitialContext ctx = null;\r
+ Connection conn = null;\r
+ try {\r
+ ctx = new InitialContext();\r
+ DataSource ds = (DataSource) ctx.lookup(repositoryName);\r
+ if (ds == null) {\r
+ throw new IllegalArgumentException("datasource not found: " + repositoryName);\r
+ }\r
+ conn = ds.getConnection();\r
+ return conn;\r
+ } catch (NamingException ex) {\r
+ LoginException le = new LoginException("Error looking up DataSource from: " + repositoryName);\r
+ le.initCause(ex);\r
+ throw le;\r
+ } finally {\r
+ if (ctx != null) {\r
+ try {\r
+ ctx.close();\r
+ } catch (Exception e) {\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
\r
void retrieveAllWorkspaceIds() throws Exception {\r
//all configs are read, connector is initialized, retrieve workspaceids\r
Hashtable<String, TenantBindingType> tenantBindings =\r
- getTenantBindingConfigReader().getTenantBindings();\r
+ tenantBindingConfigReader.getTenantBindings();\r
TenantRepository.get().setup(tenantBindings);\r
}\r
\r
<artifactId>org.collectionspace.services.dimension.client</artifactId>\r
<version>${project.version}</version>\r
</dependency>\r
+ <dependency>\r
+ <groupId>org.collectionspace.services</groupId>\r
+ <artifactId>org.collectionspace.services.intake.client</artifactId>\r
+ <version>${project.version}</version>\r
+ </dependency>\r
<!-- External dependencies -->\r
<dependency>\r
<groupId>org.testng</groupId>\r
import org.collectionspace.services.client.CollectionSpaceClient;
import org.collectionspace.services.client.DimensionClient;
import org.collectionspace.services.client.DimensionFactory;
+import org.collectionspace.services.client.IntakeClient;
import org.collectionspace.services.client.PermissionClient;
import org.collectionspace.services.client.PermissionFactory;
import org.collectionspace.services.client.PermissionRoleClient;
import org.collectionspace.services.client.RoleFactory;
import org.collectionspace.services.client.test.AbstractServiceTestImpl;
import org.collectionspace.services.dimension.DimensionsCommon;
+import org.collectionspace.services.intake.IntakesCommon;
import org.collectionspace.services.jaxb.AbstractCommonList;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
private String bigbirdPermId;
private String elmoPermId;
private final static String TEST_SERVICE_NAME = "dimensions";
+ private boolean accountRolesFlipped = false;
/*
* This method is called only by the parent class, AbstractServiceTestImpl
*/
}
private void seedAccounts() {
- String userId = "bigbird2010";
- String accId = createAccount(userId, "bigbird@cspace.org");
- AccountValue ava = new AccountValue();
- ava.setScreenName(userId);
- ava.setUserId(userId);
- ava.setAccountId(accId);
- accValues.put(ava.getUserId(), ava);
+ String userId1 = "bigbird2010";
+ String accId1 = createAccount(userId1, "bigbird@cspace.org");
+ AccountValue av1 = new AccountValue();
+ av1.setScreenName(userId1);
+ av1.setUserId(userId1);
+ av1.setAccountId(accId1);
+ accValues.put(av1.getUserId(), av1);
String userId2 = "elmo2010";
- String coAccId = createAccount(userId2, "elmo@cspace.org");
- AccountValue avc = new AccountValue();
- avc.setScreenName(userId2);
- avc.setUserId(userId2);
- avc.setAccountId(coAccId);
- accValues.put(avc.getUserId(), avc);
+ String accId2 = createAccount(userId2, "elmo@cspace.org");
+ AccountValue av2 = new AccountValue();
+ av2.setScreenName(userId2);
+ av2.setUserId(userId2);
+ av2.setAccountId(accId2);
+ accValues.put(av2.getUserId(), av2);
+
+ String userId3 = "lockedOut";
+ String accId3 = createAccount(userId3, "lockedOut@cspace.org");
+ AccountValue av3 = new AccountValue();
+ av3.setScreenName(userId3);
+ av3.setUserId(userId3);
+ av3.setAccountId(accId3);
+ accValues.put(av3.getUserId(), av3);
}
private void seedAccountRoles() {
if (logger.isDebugEnabled()) {
logger.debug(testName + ": knownResourceId=" + knownResourceId);
}
+
+ // Now verify that elmo cannot create
+ client = new DimensionClient();
+ client.setAuth(true, "elmo2010", true, "elmo2010", true);
+ res = client.create(multipart);
+
+ statusCode = res.getStatus();
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + " (verify not allowed): status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, Response.Status.FORBIDDEN.getStatusCode());
+
+ //Finally, verify that elmo has no access to Intakes
+ // Submit the request to the service and store the response.
+ IntakeClient iclient = new IntakeClient();
+ iclient.setAuth(true, "elmo2010", true, "elmo2010", true);
+ multipart = createIntakeInstance(
+ "entryNumber-" + identifier,
+ "entryDate-" + identifier,
+ "depositor-" + identifier);
+ res = iclient.create(multipart);
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + " (verify create intake not allowed): status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, Response.Status.FORBIDDEN.getStatusCode());
+
+ }
+
+ /**
+ * Creates the intake instance.
+ *
+ * @param entryNumber the entry number
+ * @param entryDate the entry date
+ * @param depositor the depositor
+ * @return the multipart output
+ */
+ private MultipartOutput createIntakeInstance(String entryNumber,
+ String entryDate,
+ String depositor) {
+ IntakesCommon intake = new IntakesCommon();
+ intake.setEntryNumber(entryNumber);
+ intake.setEntryDate(entryDate);
+ intake.setDepositor(depositor);
+
+ MultipartOutput multipart = new MultipartOutput();
+ OutputPart commonPart =
+ multipart.addPart(intake, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", new IntakeClient().getCommonPartName());
+
+ if(logger.isDebugEnabled()){
+ logger.debug("to be created, intake common");
+ logger.debug(objectAsXmlString(intake, IntakesCommon.class));
+ }
+
+ return multipart;
+ }
+
+
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+ dependsOnMethods = {"delete"})
+ public void verifyCreateWithFlippedRoles(String testName) throws Exception {
+ if (logger.isDebugEnabled()) {
+ logger.debug(testBanner(testName, CLASS_NAME));
+ }
+ setupCreate();
+
+ // Submit the request to the service and store the response.
+ DimensionClient client = new DimensionClient();
+ flipInitialAccountRoles();
+
+ // Now verify that elmo can create
+ client.setAuth(true, "elmo2010", true, "elmo2010", true);
+ client = new DimensionClient();
+
+ String identifier = createIdentifier();
+ DimensionsCommon dimension = new DimensionsCommon();
+ dimension.setDimension("dimensionType");
+ dimension.setValue("value-" + identifier);
+ dimension.setValueDate(new Date().toString());
+ MultipartOutput multipart = DimensionFactory.createDimensionInstance(client.getCommonPartName(),
+ dimension);
+ ClientResponse<Response> res = client.create(multipart);
+
+ int statusCode = res.getStatus();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, Response.Status.CREATED.getStatusCode());
+ knownResourceId = extractId(res);
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": knownResourceId=" + knownResourceId);
+ }
+
+ //bigbird no longer allowed to create
+ client.setAuth(true, "bigbird2010", true, "bigbird2010", true);
+ res = client.create(multipart);
+
+ statusCode = res.getStatus();
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + " (verify not allowed): status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, Response.Status.FORBIDDEN.getStatusCode());
+ restoreInitialAccountRoles();
}
//to not cause uniqueness violation for permRole, createList is removed
DimensionsCommon dimension = (DimensionsCommon) extractPart(input,
client.getCommonPartName(), DimensionsCommon.class);
Assert.assertNotNull(dimension);
+ }
+
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+ dependsOnMethods = {"read"})
+ public void readLockedOut(String testName) throws Exception {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(testBanner(testName, CLASS_NAME));
+ }
+ // Perform setup.
+ setupRead();
+
+ // Submit the request to the service and store the response.
+ DimensionClient client = new DimensionClient();
+ //lockedOut allowed to read
+ client.setAuth(true, "lockedOut", true, "lockedOut", true);
+ ClientResponse<MultipartInput> res = client.read(knownResourceId);
+ int statusCode = res.getStatus();
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + " (test lockedOut): status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, Response.Status.FORBIDDEN.getStatusCode());
}
// Failure outcomes
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, Response.Status.FORBIDDEN.getStatusCode());
+
+ client = new DimensionClient();
+
+ //lockedOut not allowed to update
+ client.setAuth(true, "lockedOut", true, "lockedOut", true);
+ res = client.update(knownResourceId, output);
+ statusCode = res.getStatus();
+ // Check the status code of the response: does it match the expected response(s)?
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": (lockedOut) status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, Response.Status.FORBIDDEN.getStatusCode());
+
}
// Failure outcomes
//FIXME delete on permission deletes all associations with roles
//this would delete association with ROLE_ADMINISTRATOR too
//deletePermissions();
- deleteRoles();
+ deleteRoles();
deleteAccounts();
}
private void deleteAccountRoles() {
List<RoleValue> bigbirdRoleValues = new ArrayList<RoleValue>();
bigbirdRoleValues.add(roleValues.get("ROLE_TEST_CM"));
- deleteAccountRole(accValues.get("bigbird2010"), bigbirdRoleValues);
List<RoleValue> elmoRoleValues = new ArrayList<RoleValue>();
elmoRoleValues.add(roleValues.get("ROLE_TEST_INTERN"));
- deleteAccountRole(accValues.get("elmo2010"), elmoRoleValues);
+ if(!accountRolesFlipped) {
+ deleteAccountRole(accValues.get("bigbird2010"), bigbirdRoleValues);
+ deleteAccountRole(accValues.get("elmo2010"), elmoRoleValues);
+ } else {
+ deleteAccountRole(accValues.get("bigbird2010"), elmoRoleValues);
+ deleteAccountRole(accValues.get("elmo2010"),bigbirdRoleValues );
+ }
}
+
+ private void flipInitialAccountRoles() {
+ if(!accountRolesFlipped) {
+ List<RoleValue> cmRoleValues = new ArrayList<RoleValue>();
+ List<RoleValue> internRoleValues = new ArrayList<RoleValue>();
+ cmRoleValues.add(roleValues.get("ROLE_TEST_CM"));
+ internRoleValues.add(roleValues.get("ROLE_TEST_INTERN"));
+
+ deleteAccountRole(accValues.get("bigbird2010"), cmRoleValues);
+ deleteAccountRole(accValues.get("elmo2010"), internRoleValues);
+
+ createAccountRole(accValues.get("bigbird2010"), internRoleValues);
+ createAccountRole(accValues.get("elmo2010"), cmRoleValues);
+
+ accountRolesFlipped = true;
+ }
+ }
+
+ private void restoreInitialAccountRoles() {
+ if(accountRolesFlipped) {
+ List<RoleValue> cmRoleValues = new ArrayList<RoleValue>();
+ List<RoleValue> internRoleValues = new ArrayList<RoleValue>();
+ cmRoleValues.add(roleValues.get("ROLE_TEST_CM"));
+ internRoleValues.add(roleValues.get("ROLE_TEST_INTERN"));
+
+ deleteAccountRole(accValues.get("bigbird2010"), internRoleValues);
+ deleteAccountRole(accValues.get("elmo2010"), cmRoleValues);
+
+ createAccountRole(accValues.get("bigbird2010"), internRoleValues);
+ createAccountRole(accValues.get("elmo2010"), cmRoleValues);
+ accountRolesFlipped = false;
+ }
+ }
+
+
private void deletePermissions() {
//delete entities
private final String CLASS_NAME = MultiTenancyTest.class.getName();
private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
- private final static String TENANT_1_ADMIN_USER = "test";
- private final static String TENANT_2_ADMIN_USER = "test-pahma";
+ private final static String TENANT_1_ADMIN_USER = "admin@collectionspace.org";
+ private final static String TENANT_2_ADMIN_USER = "admin@hearstmuseum.berkeley.edu";
+ private final static String TENANT_ADMIN_PASS = "Administrator";
private final static String TENANT_1_USER = "user1@museum1.org";
private final static String TENANT_2_USER = "user2@museum2.org";
private final static String TENANT_1 = "1";
//tenant admin users are used to create accounts, roles and permissions and relationships
//assumption : two tenant admin users exist before running this test
- tenantAdminUsers.put(TENANT_1, new UserInfo(TENANT_1_ADMIN_USER, "test"));
- tenantAdminUsers.put(TENANT_2, new UserInfo(TENANT_2_ADMIN_USER, "test"));
+ tenantAdminUsers.put(TENANT_1, new UserInfo(TENANT_1_ADMIN_USER, TENANT_ADMIN_PASS));
+ tenantAdminUsers.put(TENANT_2, new UserInfo(TENANT_2_ADMIN_USER, TENANT_ADMIN_PASS));
seedAccounts();
seedPermissions();