1 package org.collectionspace.services.common.authorization_mgt;
\r
3 import java.sql.Connection;
\r
4 import java.sql.PreparedStatement;
\r
5 import java.sql.ResultSet;
\r
6 import java.sql.SQLException;
\r
7 import java.sql.Statement;
\r
8 import java.util.ArrayList;
\r
9 import java.util.Date;
\r
10 import java.util.Hashtable;
\r
11 import java.util.List;
\r
12 import java.util.UUID;
\r
14 import javax.naming.NamingException;
\r
16 import org.collectionspace.services.authorization.AuthZ;
\r
17 import org.collectionspace.services.authorization.CSpaceAction;
\r
18 import org.collectionspace.services.authorization.PermissionActionUtil;
\r
19 import org.collectionspace.services.authorization.PermissionException;
\r
20 import org.collectionspace.services.authorization.PermissionRole;
\r
21 import org.collectionspace.services.authorization.PermissionValue;
\r
22 import org.collectionspace.services.authorization.Role;
\r
23 import org.collectionspace.services.authorization.RoleValue;
\r
24 import org.collectionspace.services.authorization.SubjectType;
\r
25 import org.collectionspace.services.authorization.URIResourceImpl;
\r
26 import org.collectionspace.services.authorization.perms.ActionType;
\r
27 import org.collectionspace.services.authorization.perms.EffectType;
\r
28 import org.collectionspace.services.authorization.perms.Permission;
\r
29 import org.collectionspace.services.authorization.perms.PermissionAction;
\r
31 import org.collectionspace.services.client.RoleClient;
\r
32 import org.collectionspace.services.client.workflow.WorkflowClient;
\r
34 import org.collectionspace.services.common.authorization_mgt.AuthorizationStore;
\r
35 import org.collectionspace.services.common.config.ServiceConfigUtils;
\r
36 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
\r
37 import org.collectionspace.services.common.document.DocumentHandler;
\r
38 import org.collectionspace.services.common.security.SecurityUtils;
\r
39 import org.collectionspace.services.common.service.ServiceBindingType;
\r
40 import org.collectionspace.services.common.storage.DatabaseProductType;
\r
41 import org.collectionspace.services.common.storage.JDBCTools;
\r
42 import org.collectionspace.services.common.tenant.TenantBindingType;
\r
44 import org.collectionspace.services.lifecycle.Lifecycle;
\r
45 import org.collectionspace.services.lifecycle.TransitionDef;
\r
46 import org.collectionspace.services.lifecycle.TransitionDefList;
\r
48 //import org.mortbay.log.Log;
\r
49 import org.slf4j.Logger;
\r
50 import org.slf4j.LoggerFactory;
\r
52 import org.springframework.security.acls.model.AlreadyExistsException;
\r
55 public class AuthorizationCommon {
\r
58 // ActionGroup labels/constants
\r
62 final public static String ACTIONGROUP_CRUDL_NAME = "CRUDL";
\r
63 final public static ActionType[] ACTIONSET_CRUDL = {ActionType.CREATE, ActionType.READ, ActionType.UPDATE, ActionType.DELETE, ActionType.SEARCH};
\r
65 final public static String ACTIONGROUP_RL_NAME = "RL";
\r
66 final public static ActionType[] ACTIONSET_RL = {ActionType.READ, ActionType.SEARCH};
\r
69 * Inner class to deal with predefined ADMIN and READER action groupds
\r
71 public class ActionGroup {
\r
73 ActionType[] actions;
\r
76 static ActionGroup ACTIONGROUP_CRUDL;
\r
77 static ActionGroup ACTIONGROUP_RL;
\r
79 // A static block to initialize the predefined action groups
\r
81 AuthorizationCommon ac = new AuthorizationCommon();
\r
83 ACTIONGROUP_CRUDL = ac.new ActionGroup();
\r
84 ACTIONGROUP_CRUDL.name = ACTIONGROUP_CRUDL_NAME;
\r
85 ACTIONGROUP_CRUDL.actions = ACTIONSET_CRUDL;
\r
87 ACTIONGROUP_RL = ac.new ActionGroup();
\r
88 ACTIONGROUP_RL.name = ACTIONGROUP_RL_NAME;
\r
89 ACTIONGROUP_RL.actions = ACTIONSET_RL;
\r
93 final static Logger logger = LoggerFactory.getLogger(AuthorizationCommon.class);
\r
95 final public static String ROLE_ADMINISTRATOR = "ADMINISTRATOR";
\r
96 final public static String ROLE_TENANT_ADMINISTRATOR = "TENANT_ADMINISTRATOR";
\r
97 final public static String ROLE_TENANT_READER = "TENANT_READER";
\r
98 final public static String ROLE_ADMINISTRATOR_ID = "0";
\r
99 final public static String ADMINISTRATOR_TENANT_ID = "0";
\r
101 public static final String TENANT_ADMIN_ACCT_PREFIX = "admin@";
\r
102 public static final String TENANT_READER_ACCT_PREFIX = "reader@";
\r
103 public static final String ROLE_PREFIX = "ROLE_";
\r
104 public static final String SPRING_ADMIN_ROLE = "ROLE_SPRING_ADMIN";
\r
105 public static final String TENANT_ADMIN_ROLE_SUFFIX = "_TENANT_ADMINISTRATOR";
\r
106 public static final String TENANT_READER_ROLE_SUFFIX = "_TENANT_READER";
\r
107 public static final String DEFAULT_ADMIN_PASSWORD = "Administrator";
\r
108 public static final String DEFAULT_READER_PASSWORD = "reader";
\r
110 public static String ROLE_SPRING_ADMIN_ID = "-1";
\r
111 public static String ROLE_SPRING_ADMIN_NAME = "ROLE_SPRING_ADMIN";
\r
113 public static Role getRole(String tenantId, String displayName) {
\r
116 String roleName = AuthorizationCommon.getQualifiedRoleName(tenantId, displayName);
\r
117 role = AuthorizationStore.getRoleByName(roleName, tenantId);
\r
122 public static Role createRole(String tenantId, String name, String description) {
\r
123 return createRole(tenantId, name, description, false /* mutable by default */);
\r
126 public static Role createRole(String tenantId, String name, String description, boolean immutable) {
\r
127 Role role = new Role();
\r
129 role.setCreatedAtItem(new Date());
\r
130 role.setDisplayName(name);
\r
131 String roleName = AuthorizationCommon.getQualifiedRoleName(tenantId, name);
\r
132 role.setRoleName(roleName);
\r
133 String id = UUID.randomUUID().toString(); //FIXME: The qualified role name should be unique enough to use as an ID/key
\r
135 role.setDescription(description);
\r
136 role.setTenantId(tenantId);
\r
137 if (immutable == true) {
\r
138 role.setMetadataProtection(RoleClient.IMMUTABLE);
\r
139 role.setPermsProtection(RoleClient.IMMUTABLE);
\r
146 * Add permission to the Spring Security tables
\r
147 * with assumption that resource is of type URI
\r
148 * @param permission configuration
\r
150 public static void addPermissionsForUri(Permission perm,
\r
151 PermissionRole permRole) throws PermissionException {
\r
153 // First check the integrity of the incoming arguments.
\r
155 if (!perm.getCsid().equals(permRole.getPermission().get(0).getPermissionId())) {
\r
156 throw new IllegalArgumentException("permission ids do not"
\r
157 + " match for role=" + permRole.getRole().get(0).getRoleName()
\r
158 + " with permissionId=" + permRole.getPermission().get(0).getPermissionId()
\r
159 + " for permission with csid=" + perm.getCsid());
\r
162 List<String> principals = new ArrayList<String>();
\r
163 for (RoleValue roleValue : permRole.getRole()) {
\r
164 principals.add(roleValue.getRoleName());
\r
166 List<PermissionAction> permActions = perm.getAction();
\r
167 for (PermissionAction permAction : permActions) {
\r
169 CSpaceAction action = URIResourceImpl.getAction(permAction.getName());
\r
170 URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(),
\r
171 perm.getResourceName(), action);
\r
172 boolean grant = perm.getEffect().equals(EffectType.PERMIT) ? true : false;
\r
173 AuthZ.get().addPermissions(uriRes, principals.toArray(new String[0]), grant);//CSPACE-4967
\r
174 } catch (PermissionException e) {
\r
176 // Only throw the exception if it is *not* an already-exists exception
\r
178 if (e.getCause() instanceof AlreadyExistsException == false) {
\r
185 private static Connection getConnection() throws NamingException, SQLException {
\r
186 return JDBCTools.getConnection(JDBCTools.CSPACE_REPOSITORY_NAME);
\r
190 * Spring security seems to require that all of our role names start
\r
191 * with the ROLE_PREFIX string.
\r
193 public static String getQualifiedRoleName(String tenantId, String name) {
\r
194 String result = name;
\r
196 String qualifiedName = ROLE_PREFIX + tenantId.toUpperCase() + "_" + name.toUpperCase();
\r
197 if (name.equals(qualifiedName) == false) {
\r
198 result = qualifiedName;
\r
204 private static ActionGroup getActionGroup(String actionGroupStr) {
\r
205 ActionGroup result = null;
\r
207 if (actionGroupStr.equalsIgnoreCase(ACTIONGROUP_CRUDL_NAME)) {
\r
208 result = ACTIONGROUP_CRUDL;
\r
209 } else if (actionGroupStr.equalsIgnoreCase(ACTIONGROUP_RL_NAME)) {
\r
210 result = ACTIONGROUP_RL;
\r
216 public static Permission createPermission(String tenantId,
\r
217 String resourceName,
\r
218 String description,
\r
219 String actionGroupStr) {
\r
220 Permission result = null;
\r
222 ActionGroup actionGroup = getActionGroup(actionGroupStr);
\r
223 result = createPermission(tenantId, resourceName, description, actionGroup);
\r
228 private static Permission createPermission(String tenantId,
\r
229 String resourceName,
\r
230 String description,
\r
231 ActionGroup actionGroup) {
\r
232 String id = UUID.randomUUID().toString(); //FIXME: Could this be something like a refname instead of a UUID?
\r
233 Permission perm = new Permission();
\r
235 perm.setDescription(description);
\r
236 perm.setCreatedAtItem(new Date());
\r
237 perm.setResourceName(resourceName.toLowerCase().trim());
\r
238 perm.setEffect(EffectType.PERMIT);
\r
239 perm.setTenantId(tenantId);
\r
241 perm.setActionGroup(actionGroup.name);
\r
242 ArrayList<PermissionAction> pas = new ArrayList<PermissionAction>();
\r
243 perm.setAction(pas);
\r
244 for (ActionType actionType : actionGroup.actions) {
\r
245 PermissionAction permAction = createPermissionAction(perm, actionType);
\r
246 pas.add(permAction);
\r
252 private static Permission createWorkflowPermission(TenantBindingType tenantBinding,
\r
253 ServiceBindingType serviceBinding,
\r
254 TransitionDef transitionDef,
\r
255 ActionGroup actionGroup)
\r
257 Permission result = null;
\r
259 String tenantId = tenantBinding.getId();
\r
260 String resourceName = serviceBinding.getName().toLowerCase().trim()
\r
261 + WorkflowClient.SERVICE_AUTHZ_SUFFIX
\r
262 + transitionDef.getName();
\r
263 String description = "A generate workflow permission for actiongroup " + actionGroup.name;
\r
264 result = createPermission(tenantId, resourceName, description, actionGroup);
\r
269 private static PermissionRole createPermissionRole(Permission permission,
\r
271 boolean enforceTenancy) throws Exception
\r
273 PermissionRole permRole = new PermissionRole();
\r
275 if (enforceTenancy && role.getTenantId().equalsIgnoreCase(permission.getTenantId())) {
\r
276 permRole.setSubject(SubjectType.ROLE);
\r
278 // Set of the permission value list of the permrole
\r
280 List<PermissionValue> permValues = new ArrayList<PermissionValue>();
\r
281 PermissionValue permValue = new PermissionValue();
\r
282 permValue.setPermissionId(permission.getCsid());
\r
283 permValue.setResourceName(permission.getResourceName().toLowerCase());
\r
284 permValue.setActionGroup(permission.getActionGroup());
\r
285 permValues.add(permValue);
\r
286 permRole.setPermission(permValues);
\r
288 // Set of the role value list of the permrole
\r
290 List<RoleValue> roleValues = new ArrayList<RoleValue>();
\r
291 RoleValue rv = new RoleValue();
\r
292 // This needs to use the qualified name, not the display name
\r
293 rv.setRoleName(role.getRoleName());
\r
294 rv.setRoleId(role.getCsid());
\r
295 roleValues.add(rv);
\r
296 permRole.setRole(roleValues);
\r
298 String errMsg = "The tenant ID of the role: " + role.getTenantId()
\r
299 + " did not match the tenant ID of the permission: " + permission.getTenantId();
\r
300 throw new Exception(errMsg);
\r
306 public static void createDefaultPermissions(TenantBindingConfigReaderImpl tenantBindingConfigReader) throws Exception
\r
308 PermissionAction pa = new PermissionAction();
\r
311 Hashtable<String, TenantBindingType> tenantBindings =
\r
312 tenantBindingConfigReader.getTenantBindings();
\r
313 for (String tenantId : tenantBindings.keySet()) {
\r
314 TenantBindingType tenantBinding = tenantBindings.get(tenantId);
\r
315 for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
\r
317 DocumentHandler docHandler = ServiceConfigUtils.createDocumentHandlerInstance(
\r
318 tenantBinding, serviceBinding);
\r
319 Lifecycle lifecycle = docHandler.getLifecycle();
\r
320 TransitionDefList transitionDefList = lifecycle.getTransitionDefList();
\r
321 for (TransitionDef transitionDef : transitionDefList.getTransitionDef()) {
\r
323 // Create the permission for the admin role
\r
325 Permission adminPerm = createWorkflowPermission(tenantBinding, serviceBinding, transitionDef, AuthorizationCommon.ACTIONGROUP_CRUDL);
\r
326 Role adminRole = AuthorizationCommon.getRole(tenantBinding.getId(), AuthorizationCommon.ROLE_TENANT_ADMINISTRATOR);
\r
327 PermissionRole adminPermRole = createPermissionRole(adminPerm, adminRole, true);
\r
328 addPermissionsForUri(adminPerm, adminPermRole);
\r
330 // Create the permission for the read-only role
\r
331 Permission readonlyPerm = createWorkflowPermission(tenantBinding, serviceBinding, transitionDef, AuthorizationCommon.ACTIONGROUP_RL);
\r
332 Role readonlyRole = AuthorizationCommon.getRole(tenantBinding.getId(), AuthorizationCommon.ROLE_TENANT_READER);
\r
333 PermissionRole readonlyPermRole = createPermissionRole(readonlyPerm, readonlyRole, true);
\r
334 addPermissionsForUri(readonlyPerm, readonlyPermRole);
\r
336 // Create the permission for the super-admin role. Note we use the same "adminPerm" instance we used for the "adminPermRole" instance
\r
338 Role superRole = AuthorizationCommon.getRole(tenantBinding.getId(), AuthorizationCommon.ROLE_TENANT_READER);
\r
339 PermissionRole superPermRole = createPermissionRole(adminPerm, superRole, false);
\r
340 addPermissionsForUri(adminPerm, superPermRole);
\r
342 } catch (IllegalStateException e) {
\r
343 logger.debug(e.getLocalizedMessage(), e); //We end up here if there is no document handler for the service -this is ok for some of the services.
\r
350 * FIXME: REM - This method is way too big -over 300 lines! We need to break it up into
\r
351 * smaller, discrete, sub-methods.
\r
353 public static void createDefaultAccounts(TenantBindingConfigReaderImpl tenantBindingConfigReader) {
\r
354 if (logger.isDebugEnabled()) {
\r
355 logger.debug("ServiceMain.createDefaultAccounts starting...");
\r
358 Hashtable<String, TenantBindingType> tenantBindings =
\r
359 tenantBindingConfigReader.getTenantBindings();
\r
360 Hashtable<String, String> tenantInfo = new Hashtable<String, String>();
\r
361 for (TenantBindingType tenantBinding : tenantBindings.values()) {
\r
362 String tId = tenantBinding.getId();
\r
363 String tName = tenantBinding.getName();
\r
364 tenantInfo.put(tId, tName);
\r
365 if (logger.isDebugEnabled()) {
\r
366 logger.debug("createDefaultAccounts found configured tenant id: "+tId+" name: "+tName);
\r
369 Connection conn = null;
\r
370 PreparedStatement pstmt = null;
\r
371 Statement stmt = null;
\r
372 // TODO - need to put in tests for existence first.
\r
373 // We could just look for the accounts per tenant up front, and assume that
\r
374 // the rest is there if the accounts are.
\r
375 // Could add a sql script to remove these if need be - Spring only does roles,
\r
376 // and we're not touching that, so we could safely toss the
\r
377 // accounts, users, account-tenants, account-roles, and start over.
\r
379 conn = getConnection();
\r
380 // First find or create the tenants
\r
381 String queryTenantSQL =
\r
382 "SELECT id,name FROM tenants";
\r
383 stmt = conn.createStatement();
\r
384 ResultSet rs = stmt.executeQuery(queryTenantSQL);
\r
385 ArrayList<String> existingTenants = new ArrayList<String>();
\r
386 while (rs.next()) {
\r
387 String tId = rs.getString("id");
\r
388 String tName = rs.getString("name");
\r
389 if(tenantInfo.containsKey(tId)) {
\r
390 existingTenants.add(tId);
\r
391 if(!tenantInfo.get(tId).equalsIgnoreCase(tName)) {
\r
392 logger.warn("Configured name for tenant: "
\r
393 +tId+" in repository: "+tName
\r
394 +" does not match config'd name: "+ tenantInfo.get(tId));
\r
400 String insertTenantSQL =
\r
401 "INSERT INTO tenants (id,name,created_at) VALUES (?,?, now())";
\r
402 pstmt = conn.prepareStatement(insertTenantSQL); // create a statement
\r
403 for(String tId : tenantInfo.keySet()) {
\r
404 if(existingTenants.contains(tId)) {
\r
405 if (logger.isDebugEnabled()) {
\r
406 logger.debug("createDefaultAccounts: tenant exists (skipping): "
\r
407 +tenantInfo.get(tId));
\r
411 pstmt.setString(1, tId); // set id param
\r
412 pstmt.setString(2, tenantInfo.get(tId)); // set name param
\r
413 if (logger.isDebugEnabled()) {
\r
414 logger.debug("createDefaultAccounts adding entry for tenant: "+tId);
\r
416 pstmt.executeUpdate();
\r
419 // Second find or create the users
\r
420 String queryUserSQL =
\r
421 "SELECT username FROM users WHERE username LIKE '"
\r
422 +TENANT_ADMIN_ACCT_PREFIX+"%' OR username LIKE '"
\r
423 +TENANT_READER_ACCT_PREFIX+"%'";
\r
424 rs = stmt.executeQuery(queryUserSQL);
\r
425 ArrayList<String> usersInRepo = new ArrayList<String>();
\r
426 while (rs.next()) {
\r
427 String uName = rs.getString("username");
\r
428 usersInRepo.add(uName);
\r
431 String insertUserSQL =
\r
432 "INSERT INTO users (username,passwd, created_at)"
\r
433 +" VALUES (?,?, now())";
\r
434 pstmt = conn.prepareStatement(insertUserSQL); // create a statement
\r
435 for(String tName : tenantInfo.values()) {
\r
436 String adminAcctName = getDefaultAdminUserID(tName);
\r
437 if(!usersInRepo.contains(adminAcctName)) {
\r
438 String secEncPasswd = SecurityUtils.createPasswordHash(
\r
439 adminAcctName, DEFAULT_ADMIN_PASSWORD);
\r
440 pstmt.setString(1, adminAcctName); // set username param
\r
441 pstmt.setString(2, secEncPasswd); // set passwd param
\r
442 if (logger.isDebugEnabled()) {
\r
443 logger.debug("createDefaultAccounts adding user: "
\r
444 +adminAcctName+" for tenant: "+tName);
\r
446 pstmt.executeUpdate();
\r
447 } else if (logger.isDebugEnabled()) {
\r
448 logger.debug("createDefaultAccounts: user: "+adminAcctName
\r
449 +" already exists - skipping.");
\r
453 String readerAcctName = getDefaultReaderUserID(tName);
\r
454 if(!usersInRepo.contains(readerAcctName)) {
\r
455 String secEncPasswd = SecurityUtils.createPasswordHash(
\r
456 readerAcctName, DEFAULT_READER_PASSWORD);
\r
457 pstmt.setString(1, readerAcctName); // set username param
\r
458 pstmt.setString(2, secEncPasswd); // set passwd param
\r
459 if (logger.isDebugEnabled()) {
\r
460 logger.debug("createDefaultAccounts adding user: "
\r
461 +readerAcctName+" for tenant: "+tName);
\r
463 pstmt.executeUpdate();
\r
464 } else if (logger.isDebugEnabled()) {
\r
465 logger.debug("createDefaultAccounts: user: "+readerAcctName
\r
466 +" already exists - skipping.");
\r
470 // Third, create the accounts. Assume that if the users were already there,
\r
471 // then the accounts were as well
\r
472 String insertAccountSQL =
\r
473 "INSERT INTO accounts_common "
\r
474 + "(csid, email, userid, status, screen_name, metadata_protection, roles_protection, created_at) "
\r
475 + "VALUES (?,?,?,'ACTIVE',?, 'immutable', 'immutable', now())";
\r
476 Hashtable<String, String> tenantAdminAcctCSIDs = new Hashtable<String, String>();
\r
477 Hashtable<String, String> tenantReaderAcctCSIDs = new Hashtable<String, String>();
\r
478 pstmt = conn.prepareStatement(insertAccountSQL); // create a statement
\r
479 for(String tId : tenantInfo.keySet()) {
\r
480 String tName = tenantInfo.get(tId);
\r
481 String adminCSID = UUID.randomUUID().toString();
\r
482 tenantAdminAcctCSIDs.put(tId, adminCSID);
\r
483 String adminAcctName = getDefaultAdminUserID(tName);
\r
484 if(!usersInRepo.contains(adminAcctName)) {
\r
485 pstmt.setString(1, adminCSID); // set csid param
\r
486 pstmt.setString(2, adminAcctName); // set email param (bogus)
\r
487 pstmt.setString(3, adminAcctName); // set userid param
\r
488 pstmt.setString(4, "Administrator");// set screen name param
\r
489 if (logger.isDebugEnabled()) {
\r
490 logger.debug("createDefaultAccounts adding account: "
\r
491 +adminAcctName+" for tenant: "+tName);
\r
493 pstmt.executeUpdate();
\r
494 } else if (logger.isDebugEnabled()) {
\r
495 logger.debug("createDefaultAccounts: user: "+adminAcctName
\r
496 +" already exists - skipping account generation.");
\r
499 String readerCSID = UUID.randomUUID().toString();
\r
500 tenantReaderAcctCSIDs.put(tId, readerCSID);
\r
501 String readerAcctName = getDefaultReaderUserID(tName);
\r
502 if(!usersInRepo.contains(readerAcctName)) {
\r
503 pstmt.setString(1, readerCSID); // set csid param
\r
504 pstmt.setString(2, readerAcctName); // set email param (bogus)
\r
505 pstmt.setString(3, readerAcctName); // set userid param
\r
506 pstmt.setString(4, "Reader"); // set screen name param
\r
507 if (logger.isDebugEnabled()) {
\r
508 logger.debug("createDefaultAccounts adding account: "
\r
509 +readerAcctName+" for tenant: "+tName);
\r
511 pstmt.executeUpdate();
\r
512 } else if (logger.isDebugEnabled()) {
\r
513 logger.debug("createDefaultAccounts: user: "+readerAcctName
\r
514 +" already exists - skipping account creation.");
\r
518 // Fourth, bind accounts to tenants. Assume that if the users were already there,
\r
519 // then the accounts were bound to tenants correctly
\r
520 String insertAccountTenantSQL;
\r
521 DatabaseProductType databaseProductType = JDBCTools.getDatabaseProductType();
\r
522 if (databaseProductType == DatabaseProductType.MYSQL) {
\r
523 insertAccountTenantSQL =
\r
524 "INSERT INTO accounts_tenants (TENANTS_ACCOUNTSCOMMON_CSID,tenant_id) "
\r
526 } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {
\r
527 insertAccountTenantSQL =
\r
528 "INSERT INTO accounts_tenants (HJID, TENANTS_ACCOUNTSCOMMON_CSID,tenant_id) "
\r
529 + " VALUES(nextval('hibernate_sequence'), ?, ?)";
\r
531 throw new Exception("Unrecognized database system.");
\r
533 pstmt = conn.prepareStatement(insertAccountTenantSQL); // create a statement
\r
534 for(String tId : tenantInfo.keySet()) {
\r
535 String tName = tenantInfo.get(tId);
\r
536 if(!usersInRepo.contains(getDefaultAdminUserID(tName))) {
\r
537 String adminAcct = tenantAdminAcctCSIDs.get(tId);
\r
538 pstmt.setString(1, adminAcct); // set acct CSID param
\r
539 pstmt.setString(2, tId); // set tenant_id param
\r
540 if (logger.isDebugEnabled()) {
\r
541 logger.debug("createDefaultAccounts binding account id: "
\r
542 +adminAcct+" to tenant id: "+tId);
\r
544 pstmt.executeUpdate();
\r
546 if(!usersInRepo.contains(getDefaultReaderUserID(tName))) {
\r
547 String readerAcct = tenantReaderAcctCSIDs.get(tId);
\r
548 pstmt.setString(1, readerAcct); // set acct CSID param
\r
549 pstmt.setString(2, tId); // set tenant_id param
\r
550 if (logger.isDebugEnabled()) {
\r
551 logger.debug("createDefaultAccounts binding account id: "
\r
552 +readerAcct+" to tenant id: "+tId);
\r
554 pstmt.executeUpdate();
\r
558 // Fifth, fetch and save the default roles
\r
559 String springAdminRoleCSID = null;
\r
560 String querySpringRole =
\r
561 "SELECT csid from roles WHERE rolename='"+SPRING_ADMIN_ROLE+"'";
\r
562 rs = stmt.executeQuery(querySpringRole);
\r
564 springAdminRoleCSID = rs.getString(1);
\r
565 if (logger.isDebugEnabled()) {
\r
566 logger.debug("createDefaultAccounts found Spring Admin role: "
\r
567 +springAdminRoleCSID);
\r
570 String insertSpringAdminRoleSQL =
\r
571 "INSERT INTO roles (csid, rolename, displayName, rolegroup, created_at, tenant_id) "
\r
572 + "VALUES ('-1', 'ROLE_SPRING_ADMIN', 'SPRING_ADMIN', 'Spring Security Administrator', now(), '0')";
\r
573 stmt.executeUpdate(insertSpringAdminRoleSQL);
\r
574 springAdminRoleCSID = "-1";
\r
575 if (logger.isDebugEnabled()) {
\r
576 logger.debug("createDefaultAccounts CREATED Spring Admin role: "
\r
577 +springAdminRoleCSID);
\r
581 String getRoleCSIDSql =
\r
582 "SELECT csid from roles WHERE tenant_id=? and rolename=?";
\r
583 pstmt = conn.prepareStatement(getRoleCSIDSql); // create a statement
\r
585 Hashtable<String, String> tenantAdminRoleCSIDs = new Hashtable<String, String>();
\r
586 Hashtable<String, String> tenantReaderRoleCSIDs = new Hashtable<String, String>();
\r
587 for(String tId : tenantInfo.keySet()) {
\r
588 pstmt.setString(1, tId); // set tenant_id param
\r
589 pstmt.setString(2, getDefaultAdminRole(tId)); // set rolename param
\r
590 rs = pstmt.executeQuery();
\r
591 // extract data from the ResultSet
\r
593 throw new RuntimeException("Cannot find role: "+getDefaultAdminRole(tId)
\r
594 +" for tenant id: "+tId+" in roles!");
\r
596 String tenantAdminRoleCSID = rs.getString(1);
\r
597 if (logger.isDebugEnabled()) {
\r
598 logger.debug("createDefaultAccounts found role: "
\r
599 +getDefaultAdminRole(tId)+"("+tenantAdminRoleCSID
\r
600 +") for tenant id: "+tId);
\r
602 tenantAdminRoleCSIDs.put(tId, tenantAdminRoleCSID);
\r
603 pstmt.setString(1, tId); // set tenant_id param
\r
604 pstmt.setString(2, getDefaultReaderRole(tId)); // set rolename param
\r
606 rs = pstmt.executeQuery();
\r
607 // extract data from the ResultSet
\r
609 throw new RuntimeException("Cannot find role: "+getDefaultReaderRole(tId)
\r
610 +" for tenant id: "+tId+" in roles!");
\r
612 String tenantReaderRoleCSID = rs.getString(1);
\r
613 if (logger.isDebugEnabled()) {
\r
614 logger.debug("createDefaultAccounts found role: "
\r
615 +getDefaultReaderRole(tId)+"("+tenantReaderRoleCSID
\r
616 +") for tenant id: "+tId);
\r
618 tenantReaderRoleCSIDs.put(tId, tenantReaderRoleCSID);
\r
622 // Sixth, bind the accounts to roles. If the users already existed,
\r
623 // we'll assume they were set up correctly.
\r
624 String insertAccountRoleSQL;
\r
625 if (databaseProductType == DatabaseProductType.MYSQL) {
\r
626 insertAccountRoleSQL =
\r
627 "INSERT INTO accounts_roles(account_id, user_id, role_id, role_name, created_at)"
\r
628 +" VALUES(?, ?, ?, ?, now())";
\r
629 } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {
\r
630 insertAccountRoleSQL =
\r
631 "INSERT INTO accounts_roles(HJID, account_id, user_id, role_id, role_name, created_at)"
\r
632 +" VALUES(nextval('hibernate_sequence'), ?, ?, ?, ?, now())";
\r
634 throw new Exception("Unrecognized database system.");
\r
636 if (logger.isDebugEnabled()) {
\r
637 logger.debug("createDefaultAccounts binding accounts to roles with SQL:\n"
\r
638 +insertAccountRoleSQL);
\r
640 pstmt = conn.prepareStatement(insertAccountRoleSQL); // create a statement
\r
641 for(String tId : tenantInfo.keySet()) {
\r
642 String adminUserId = getDefaultAdminUserID(tenantInfo.get(tId));
\r
643 if(!usersInRepo.contains(adminUserId)) {
\r
644 String adminAcct = tenantAdminAcctCSIDs.get(tId);
\r
645 String adminRoleId = tenantAdminRoleCSIDs.get(tId);
\r
646 pstmt.setString(1, adminAcct); // set acct CSID param
\r
647 pstmt.setString(2, adminUserId); // set user_id param
\r
648 pstmt.setString(3, adminRoleId); // set role_id param
\r
649 pstmt.setString(4, getDefaultAdminRole(tId)); // set rolename param
\r
650 if (logger.isDebugEnabled()) {
\r
651 logger.debug("createDefaultAccounts binding account: "
\r
652 +adminUserId+" to Admin role("+adminRoleId
\r
653 +") for tenant id: "+tId);
\r
655 pstmt.executeUpdate();
\r
656 // Now add the Spring Admin Role to the admin accounts
\r
657 pstmt.setString(3, springAdminRoleCSID); // set role_id param
\r
658 pstmt.setString(4, SPRING_ADMIN_ROLE); // set rolename param
\r
659 if (logger.isDebugEnabled()) {
\r
660 logger.debug("createDefaultAccounts binding account: "
\r
661 +adminUserId+" to Spring Admin role: "+springAdminRoleCSID);
\r
663 pstmt.executeUpdate();
\r
665 String readerUserId = getDefaultReaderUserID(tenantInfo.get(tId));
\r
666 if(!usersInRepo.contains(readerUserId)) {
\r
667 String readerAcct = tenantReaderAcctCSIDs.get(tId);
\r
668 String readerRoleId = tenantReaderRoleCSIDs.get(tId);
\r
669 pstmt.setString(1, readerAcct); // set acct CSID param
\r
670 pstmt.setString(2, readerUserId); // set user_id param
\r
671 pstmt.setString(3, readerRoleId); // set role_id param
\r
672 pstmt.setString(4, getDefaultReaderRole(tId)); // set rolename param
\r
673 if (logger.isDebugEnabled()) {
\r
674 logger.debug("createDefaultAccounts binding account: "
\r
675 +readerUserId+" to Reader role("+readerRoleId
\r
676 +") for tenant id: "+tId);
\r
678 pstmt.executeUpdate();
\r
683 } catch (RuntimeException rte) {
\r
684 if (logger.isDebugEnabled()) {
\r
685 logger.debug("Exception in createDefaultAccounts: "+
\r
686 rte.getLocalizedMessage());
\r
687 logger.debug(rte.getStackTrace().toString());
\r
690 } catch (SQLException sqle) {
\r
691 // SQLExceptions can be chained. We have at least one exception, so
\r
692 // set up a loop to make sure we let the user know about all of them
\r
693 // if there happens to be more than one.
\r
694 if (logger.isDebugEnabled()) {
\r
695 SQLException tempException = sqle;
\r
696 while (null != tempException) {
\r
697 logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
\r
698 tempException = tempException.getNextException();
\r
700 logger.debug(sqle.getStackTrace().toString());
\r
702 throw new RuntimeException("SQL problem in createDefaultAccounts: ", sqle);
\r
703 } catch (Exception e) {
\r
704 if (logger.isDebugEnabled()) {
\r
705 logger.debug("Exception in createDefaultAccounts: "+
\r
706 e.getLocalizedMessage());
\r
716 } catch (SQLException sqle) {
\r
717 if (logger.isDebugEnabled()) {
\r
718 logger.debug("SQL Exception closing statement/connection: "
\r
719 + sqle.getLocalizedMessage());
\r
725 private static String getDefaultAdminRole(String tenantId) {
\r
726 return ROLE_PREFIX+tenantId+TENANT_ADMIN_ROLE_SUFFIX;
\r
729 private static String getDefaultReaderRole(String tenantId) {
\r
730 return ROLE_PREFIX+tenantId+TENANT_READER_ROLE_SUFFIX;
\r
733 private static String getDefaultAdminUserID(String tenantName) {
\r
734 return TENANT_ADMIN_ACCT_PREFIX+tenantName;
\r
737 private static String getDefaultReaderUserID(String tenantName) {
\r
738 return TENANT_READER_ACCT_PREFIX+tenantName;
\r
741 static public PermissionAction createPermissionAction(Permission perm,
\r
742 ActionType actionType) {
\r
743 PermissionAction pa = new PermissionAction();
\r
745 CSpaceAction action = URIResourceImpl.getAction(actionType);
\r
746 URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(),
\r
747 perm.getResourceName(), action);
\r
748 pa.setName(actionType);
\r
749 pa.setObjectIdentity(uriRes.getHashedId().toString());
\r
750 pa.setObjectIdentityResource(uriRes.getId());
\r
755 static public PermissionAction update(Permission perm, PermissionAction permAction) {
\r
756 PermissionAction pa = new PermissionAction();
\r
758 CSpaceAction action = URIResourceImpl.getAction(permAction.getName());
\r
759 URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(),
\r
760 perm.getResourceName(), action);
\r
761 pa.setObjectIdentity(uriRes.getHashedId().toString());
\r
762 pa.setObjectIdentityResource(uriRes.getId());
\r