From 5ca7973c64d0f6e41482609acc9269dc12002d7f Mon Sep 17 00:00:00 2001 From: Richard Millet Date: Tue, 9 Nov 2010 03:09:39 +0000 Subject: [PATCH] CSPACE-3158: All new accounts created by the services need to have the "ROLE_SPRING_ADMIN" role -this is a private internal service-level only role. This role will not be exposed to the end user or service consumer --- .../account/AccountRoleSubResource.java | 19 ++++++++++-- .../client/test/RoleServiceTest.java | 3 +- .../driver/AuthorizationSeedDriver.java | 6 ++-- .../importer/AuthorizationGen.java | 31 ++++++++++++------- .../applicationContext-authorization-test.xml | 6 ++-- .../src/main/resources/hibernate.cfg.xml | 2 +- .../storage/PermissionDocumentHandler.java | 1 + .../storage/RoleDocumentHandler.java | 12 ++++--- .../jaxb/src/main/resources/permissions.xsd | 9 ++++++ .../main/resources/db/mysql/authorization.sql | 2 +- .../resources/db/mysql/test_authorization.sql | 4 +++ .../authorization/PermissionActionUtil.java | 2 ++ .../spring/SpringPermissionEvaluator.java | 23 ++++++++++++++ .../applicationContext-authorization.xml | 6 ++-- 14 files changed, 96 insertions(+), 30 deletions(-) diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java b/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java index a824db8cd..bc776a1bd 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java @@ -33,6 +33,7 @@ import org.collectionspace.services.authorization.AccountValue; import org.collectionspace.services.authorization.AccountRoleRel; import org.collectionspace.services.authorization.Permission; import org.collectionspace.services.authorization.Role; +import org.collectionspace.services.authorization.RoleValue; import org.collectionspace.services.authorization.SubjectType; import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl; @@ -56,6 +57,10 @@ public class AccountRoleSubResource // extends AbstractCollectionSpaceResourceImpl { extends AbstractCollectionSpaceResourceImpl { + //FIXME: These belong in an Authorization class, not here + private static String ROLE_SPRING_ADMIN_ID = "-1"; + private static String ROLE_SPRING_ADMIN_NAME = "ROLE_SPRING_ADMIN"; + final public static String ACCOUNT_ACCOUNTROLE_SERVICE = "accounts/accountroles"; final public static String ROLE_ACCOUNTROLE_SERVICE = "authorization/roles/accountroles"; //this service is never exposed as standalone RESTful service...just use unique @@ -160,10 +165,20 @@ public class AccountRoleSubResource */ public String createAccountRole(AccountRole input, SubjectType subject) throws Exception { + + // + // We need to associate every new account with the Spring Security Admin role so we can make + // changes to the Spring Security ACL tables. The Spring Security Admin role has NO CollectionSpace + // specific permissions. It is an internal/private role that service consumers and end-users NEVER see. + // + RoleValue springAdminRole = new RoleValue(); + springAdminRole.setRoleId(ROLE_SPRING_ADMIN_ID); + springAdminRole.setRoleName(ROLE_SPRING_ADMIN_NAME); + List roleValues = input.getRoles(); + roleValues.add(springAdminRole); ServiceContext ctx = createServiceContext(input, subject); - DocumentHandler handler = createDocumentHandler(ctx); - + DocumentHandler handler = createDocumentHandler(ctx); String bogusCsid = getStorageClient(ctx).create(ctx, handler); return bogusCsid; diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java index 41dfe1800..2c620442e 100644 --- a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java @@ -351,7 +351,8 @@ public class RoleServiceTest extends AbstractServiceTestImpl { Role output = (Role) res.getEntity(); Assert.assertNotNull(output); - String roleNameToVerify = "ROLE_" + verifyRoleName.toUpperCase(); + //FIXME: Tenant ID of "1" should not be hard coded + String roleNameToVerify = "ROLE_" + "1_" + verifyRoleName.toUpperCase(); Assert.assertEquals(output.getRoleName(), roleNameToVerify, "RoleName fix did not work!"); } diff --git a/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/driver/AuthorizationSeedDriver.java b/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/driver/AuthorizationSeedDriver.java index 87369550c..9c6faab5a 100644 --- a/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/driver/AuthorizationSeedDriver.java +++ b/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/driver/AuthorizationSeedDriver.java @@ -165,9 +165,11 @@ public class AuthorizationSeedDriver { } private void login() { - GrantedAuthority gauth = new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"); + GrantedAuthority cspace_admin = new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"); + GrantedAuthority spring_security_admin = new GrantedAuthorityImpl("ROLE_SPRING_ADMIN"); HashSet gauths = new HashSet(); - gauths.add(gauth); + gauths.add(cspace_admin); + gauths.add(spring_security_admin); Authentication authRequest = new UsernamePasswordAuthenticationToken(user, password, gauths); SecurityContextHolder.getContext().setAuthentication(authRequest); if (logger.isDebugEnabled()) { diff --git a/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationGen.java b/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationGen.java index c10f290f3..b7105dfaa 100644 --- a/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationGen.java +++ b/services/authorization-mgt/import/src/main/java/org/collectionspace/services/authorization/importer/AuthorizationGen.java @@ -58,9 +58,10 @@ import org.collectionspace.services.common.security.SecurityUtils; */ public class AuthorizationGen { - final public static String ROLE_ADMINISTRATOR = "ROLE_ADMINISTRATOR"; - final public static String ROLE_TENANT_ADMINISTRATOR = "ROLE_TENANT_ADMINISTRATOR"; - final public static String ROLE_TENANT_READER = "ROLE_TENANT_READER"; + final public static String ROLE_PREFIX = "ROLE_"; + final public static String ROLE_ADMINISTRATOR = "ADMINISTRATOR"; + final public static String ROLE_TENANT_ADMINISTRATOR = "TENANT_ADMINISTRATOR"; + final public static String ROLE_TENANT_READER = "TENANT_READER"; final public static String ROLE_ADMINISTRATOR_ID = "0"; // // ActionGroup labels/constants @@ -262,7 +263,9 @@ public class AuthorizationGen { private Role buildTenantAdminRole(String tenantId) { Role role = new Role(); role.setCreatedAtItem(new Date()); - role.setRoleName(ROLE_TENANT_ADMINISTRATOR); + role.setRoleName(ROLE_PREFIX + + tenantId + "_" + + ROLE_TENANT_ADMINISTRATOR); String id = UUID.randomUUID().toString(); role.setCsid(id); role.setDescription("generated tenant admin role"); @@ -273,7 +276,9 @@ public class AuthorizationGen { private Role buildTenantReaderRole(String tenantId) { Role role = new Role(); role.setCreatedAtItem(new Date()); - role.setRoleName(ROLE_TENANT_READER); + role.setRoleName(ROLE_PREFIX + + tenantId + "_" + + ROLE_TENANT_READER); String id = UUID.randomUUID().toString(); role.setCsid(id); role.setDescription("generated tenant read only role"); @@ -289,21 +294,23 @@ public class AuthorizationGen { } public void associateDefaultPermissionsRoles() { - List roles = new ArrayList(); - roles.add(cspaceAdminRole); for (Permission p : adminPermList) { PermissionRole permAdmRole = associatePermissionRoles(p, adminRoles); adminPermRoleList.add(permAdmRole); - - //CSpace Administrator has all access - PermissionRole permCAdmRole = associatePermissionRoles(p, roles); - adminPermRoleList.add(permCAdmRole); } for (Permission p : readerPermList) { PermissionRole permRdrRole = associatePermissionRoles(p, readerRoles); readerPermRoleList.add(permRdrRole); } + + //CSpace Administrator has all access + List roles = new ArrayList(); + roles.add(cspaceAdminRole); + for (Permission p : adminPermList) { + PermissionRole permCAdmRole = associatePermissionRoles(p, roles); + adminPermRoleList.add(permCAdmRole); + } } public List associatePermissionsRoles(List perms, List roles) { @@ -358,7 +365,7 @@ public class AuthorizationGen { private Role buildCSpaceAdminRole() { Role role = new Role(); - role.setRoleName(ROLE_ADMINISTRATOR); + role.setRoleName(ROLE_PREFIX + ROLE_ADMINISTRATOR); role.setCsid(ROLE_ADMINISTRATOR_ID); return role; } diff --git a/services/authorization-mgt/import/src/main/resources/applicationContext-authorization-test.xml b/services/authorization-mgt/import/src/main/resources/applicationContext-authorization-test.xml index d313fbc05..42e5bf502 100644 --- a/services/authorization-mgt/import/src/main/resources/applicationContext-authorization-test.xml +++ b/services/authorization-mgt/import/src/main/resources/applicationContext-authorization-test.xml @@ -55,13 +55,13 @@ - + - + - + diff --git a/services/authorization-mgt/import/src/main/resources/hibernate.cfg.xml b/services/authorization-mgt/import/src/main/resources/hibernate.cfg.xml index 8296399cf..cb1f64509 100644 --- a/services/authorization-mgt/import/src/main/resources/hibernate.cfg.xml +++ b/services/authorization-mgt/import/src/main/resources/hibernate.cfg.xml @@ -19,6 +19,6 @@ @DB_DIALECT@ org.hibernate.transaction.JDBCTransactionFactory thread - true + false diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java index 9af981151..bf6977c14 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java @@ -98,6 +98,7 @@ public class PermissionDocumentHandler URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(), perm.getResourceName(), action); permAction.setObjectIdentity(uriRes.getHashedId().toString()); + permAction.setObjectIdentityResource(uriRes.getId()); //PermissionActionUtil.update(perm, permAction); } } catch (Exception x) { diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java index 5fd3bf257..837fbf513 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java @@ -54,16 +54,18 @@ public class RoleDocumentHandler public void handleCreate(DocumentWrapper wrapDoc) throws Exception { String id = UUID.randomUUID().toString(); Role role = wrapDoc.getWrappedObject(); - role.setRoleName(fixRoleName(role.getRoleName())); - role.setCsid(id); setTenant(role); + role.setRoleName(fixRoleName(role.getRoleName(), + role.getTenantId())); + role.setCsid(id); } @Override public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { Role roleFound = wrapDoc.getWrappedObject(); Role roleReceived = getCommonPart(); - roleReceived.setRoleName(fixRoleName(roleReceived.getRoleName())); + roleReceived.setRoleName(fixRoleName(roleReceived.getRoleName(), + roleFound.getTenantId())); merge(roleReceived, roleFound); } @@ -185,9 +187,9 @@ public class RoleDocumentHandler } } - private String fixRoleName(String role) { + private String fixRoleName(String role, String tenantId) { String roleName = role.toUpperCase(); - String rolePrefix = "ROLE_"; + String rolePrefix = "ROLE_" + tenantId + "_"; if (!roleName.startsWith(rolePrefix)) { roleName = rolePrefix + roleName; } diff --git a/services/authorization/jaxb/src/main/resources/permissions.xsd b/services/authorization/jaxb/src/main/resources/permissions.xsd index 097cea7c5..0b88a8c0f 100644 --- a/services/authorization/jaxb/src/main/resources/permissions.xsd +++ b/services/authorization/jaxb/src/main/resources/permissions.xsd @@ -179,6 +179,15 @@ + + + + + + + + + diff --git a/services/authorization/pstore/src/main/resources/db/mysql/authorization.sql b/services/authorization/pstore/src/main/resources/db/mysql/authorization.sql index e878814da..cf11aae9b 100644 --- a/services/authorization/pstore/src/main/resources/db/mysql/authorization.sql +++ b/services/authorization/pstore/src/main/resources/db/mysql/authorization.sql @@ -6,7 +6,7 @@ drop table if exists permissions_roles; drop table if exists roles; create table accounts_roles (HJID bigint not null auto_increment, account_id varchar(128) not null, created_at datetime not null, role_id varchar(128) not null, role_name varchar(255), screen_name varchar(255), user_id varchar(128) not null, primary key (HJID), unique (account_id, role_id)); create table permissions (csid varchar(128) not null, action_group varchar(128), attribute_name varchar(128), created_at datetime not null, description varchar(255), effect varchar(32) not null, resource_name varchar(128) not null, tenant_id varchar(128) not null, updated_at datetime, primary key (csid)); -create table permissions_actions (HJID bigint not null auto_increment, name varchar(128) not null, objectIdentity varchar(128) not null, ACTIONS_PERMISSION_CSID varchar(128), primary key (HJID)); +create table permissions_actions (HJID bigint not null auto_increment, name varchar(128) not null, objectIdentity varchar(128) not null, objectIdentityResource varchar(128) not null, ACTIONS_PERMISSION_CSID varchar(128), primary key (HJID)); create table permissions_roles (HJID bigint not null auto_increment, actionGroup varchar(255), created_at datetime not null, permission_id varchar(128) not null, permission_resource varchar(255), role_id varchar(128) not null, role_name varchar(255), primary key (HJID), unique (permission_id, role_id)); create table roles (csid varchar(128) not null, created_at datetime not null, description varchar(255), rolegroup varchar(255), rolename varchar(200) not null, tenant_id varchar(128) not null, updated_at datetime, primary key (csid), unique (rolename, tenant_id)); alter table permissions_actions add index FK85F82042E2DC84FD (ACTIONS_PERMISSION_CSID), add constraint FK85F82042E2DC84FD foreign key (ACTIONS_PERMISSION_CSID) references permissions (csid); diff --git a/services/authorization/pstore/src/main/resources/db/mysql/test_authorization.sql b/services/authorization/pstore/src/main/resources/db/mysql/test_authorization.sql index 2c961dfc3..f896a5207 100644 --- a/services/authorization/pstore/src/main/resources/db/mysql/test_authorization.sql +++ b/services/authorization/pstore/src/main/resources/db/mysql/test_authorization.sql @@ -5,15 +5,19 @@ -- use cspace; +insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) values ('-1', 'ROLE_SPRING_ADMIN', 'Spring Security Administrator', now(), '0'); insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) values ('0', 'ROLE_ADMINISTRATOR', 'CollectionSpace Administrator', now(), '0'); -- for default test account -- +insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '-1', 'ROLE_SPRING_ADMIN', now()); 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()); -- Additional account introduced during integration on release 0.6, and currently relied upon by the Application Layer. +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()); 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()); -- test account for pahma -- +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()); 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()); -- todo: barney is created in security test but accountrole is not yet created there, so add fake account id diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/PermissionActionUtil.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/PermissionActionUtil.java index 565a3754a..d6b800421 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/PermissionActionUtil.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/PermissionActionUtil.java @@ -15,6 +15,7 @@ public class PermissionActionUtil { perm.getResourceName(), action); pa.setName(actionType); pa.setObjectIdentity(uriRes.getHashedId().toString()); + pa.setObjectIdentityResource(uriRes.getId()); return pa; } @@ -26,6 +27,7 @@ public class PermissionActionUtil { URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(), perm.getResourceName(), action); pa.setObjectIdentity(uriRes.getHashedId().toString()); + pa.setObjectIdentityResource(uriRes.getId()); return pa; } diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java index c13baf681..5fdd1f3c3 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java @@ -23,6 +23,7 @@ */ package org.collectionspace.services.authorization.spring; +import java.util.List; import java.io.Serializable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -33,6 +34,7 @@ import org.collectionspace.services.authorization.CSpaceResource; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.acls.model.Permission; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; /** @@ -55,7 +57,28 @@ public class SpringPermissionEvaluator implements CSpacePermissionEvaluator { Serializable objectIdId = SpringAuthorizationProvider.getObjectIdentityIdentifier(res); String objectIdType = SpringAuthorizationProvider.getObjectIdentityType(res); PermissionEvaluator eval = provider.getProviderPermissionEvaluator(); + + debug(res, authToken, objectIdId, objectIdType, perm); return eval.hasPermission(authToken, objectIdId, objectIdType, perm); } + + private void debug(CSpaceResource res, + Authentication authToken, + Serializable objectIdId, + String objectIdType, + Permission perm) { + if (log.isDebugEnabled() == true) { + log.debug(this.getClass().getCanonicalName() + ":" + this); + String resourceTarget = "[" + res.getId() + "]" + " | " + + "[" + "objectIdId: " + objectIdType + "(" + objectIdId + ")]"; + System.out.println("PERMISSION CHECK FOR: " + resourceTarget); + System.out.println("\tPrincipal: " + authToken.getName() + + "\tTenant ID: " + res.getTenantId()); + System.out.println("\tRoles: " + authToken.getAuthorities()); + System.out.println("\tPermission Mask: " + perm.getMask() + + " - Permission Pattern: " + perm.getPattern()); + System.out.println(""); + } + } } diff --git a/services/authorization/service/src/main/resources/applicationContext-authorization.xml b/services/authorization/service/src/main/resources/applicationContext-authorization.xml index 75972364f..ad3c750c2 100644 --- a/services/authorization/service/src/main/resources/applicationContext-authorization.xml +++ b/services/authorization/service/src/main/resources/applicationContext-authorization.xml @@ -51,13 +51,13 @@ - + - + - + -- 2.47.3