From 83ff7b7f79437a6736b20b87632e0fb075b9b402 Mon Sep 17 00:00:00 2001 From: Sanjay Dalal Date: Mon, 19 Apr 2010 22:07:44 +0000 Subject: [PATCH] CSPACE-1303, CSPACE-1359 disassociate role(s) from account CSPACE-1313, CSPACE-1358 associate role(s) to account CSPACE-1347 account-role relationship schema test: account-role service tests, all service tests exception loanout created xxxFactory for Account, Role and Permission service tests so that these could be used from tests elsewhere --- .../main/resources/META-INF/persistence.xml | 2 +- services/account/client/pom.xml | 18 +- .../services/client/AccountFactory.java | 105 ++++ .../services/client/AccountRoleClient.java | 111 ++++ .../services/client/AccountRoleProxy.java | 66 +++ .../client/test/AccountRoleServiceTest.java | 489 ++++++++++++++++++ .../client/test/AccountServiceTest.java | 54 +- .../services/account/AccountResource.java | 139 +++++ .../account/AccountRoleSubResource.java | 180 +++++++ .../storage/AccountRoleDocumentHandler.java | 220 ++++++++ .../resources/config/jboss-login-config.xml | 2 +- .../main/resources/config/login-config.xml | 2 +- services/authorization-mgt/client/pom.xml | 4 +- .../services/client/PermissionFactory.java | 102 ++++ .../services/client/RoleFactory.java | 83 +++ .../test/PermissionRoleServiceTest.java | 37 +- .../client/test/PermissionServiceTest.java | 51 +- .../client/test/RoleServiceTest.java | 12 +- .../src/main/resources/accounts_roles.xsd | 38 +- .../src/main/resources/permissions_roles.xsd | 9 - .../main/resources/db/mysql/authorization.sql | 6 +- .../db/mysql/authorization_index.sql | 9 +- .../resources/db/mysql/test_authorization.sql | 11 +- .../test/resources/META-INF/persistence.xml | 2 +- .../main/config/services/tenant-bindings.xml | 33 ++ .../jpa/JpaRelationshipStorageClient.java | 290 +++++++++++ .../storage/jpa/JpaStorageClientImpl.java | 1 + services/pom.xml | 8 +- 28 files changed, 1913 insertions(+), 171 deletions(-) create mode 100644 services/account/client/src/main/java/org/collectionspace/services/client/AccountFactory.java create mode 100644 services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleClient.java create mode 100644 services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleProxy.java create mode 100644 services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountRoleServiceTest.java create mode 100644 services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java create mode 100644 services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java create mode 100644 services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionFactory.java create mode 100644 services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/RoleFactory.java create mode 100644 services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java diff --git a/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml b/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml index ce4dc6a7e..2ae9d411d 100644 --- a/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml +++ b/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml @@ -13,7 +13,7 @@ org.collectionspace.services.authorization.PermissionAction org.collectionspace.services.authorization.PermissionRoleRel org.collectionspace.services.authorization.Role - org.collectionspace.services.authorization.UserRole + org.collectionspace.services.authorization.AccountRoleRel diff --git a/services/account/client/pom.xml b/services/account/client/pom.xml index bb2a3e138..6a4cf67ef 100644 --- a/services/account/client/pom.xml +++ b/services/account/client/pom.xml @@ -12,29 +12,37 @@ org.collectionspace.services org.collectionspace.services.account.client services.account.client - + org.slf4j slf4j-api - test org.slf4j slf4j-log4j12 - test org.collectionspace.services org.collectionspace.services.account.jaxb ${project.version} + + org.collectionspace.services + org.collectionspace.services.authorization.jaxb + ${project.version} + org.collectionspace.services org.collectionspace.services.client ${project.version} + + org.collectionspace.services + org.collectionspace.services.authorization-mgt.client + ${project.version} + @@ -43,7 +51,7 @@ mysql mysql-connector-java test - + - username + account_id role_id @@ -85,11 +85,29 @@ - + - + + + + + + + + + + + + + + + + + + + @@ -103,20 +121,20 @@ - + - + - + - + diff --git a/services/authorization/jaxb/src/main/resources/permissions_roles.xsd b/services/authorization/jaxb/src/main/resources/permissions_roles.xsd index 7fdc2521c..0918afab0 100644 --- a/services/authorization/jaxb/src/main/resources/permissions_roles.xsd +++ b/services/authorization/jaxb/src/main/resources/permissions_roles.xsd @@ -134,15 +134,6 @@ - - - - - - - - - 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 3632e9f4f..0db2ab063 100644 --- a/services/authorization/pstore/src/main/resources/db/mysql/authorization.sql +++ b/services/authorization/pstore/src/main/resources/db/mysql/authorization.sql @@ -1,12 +1,12 @@ alter table permissions_actions drop foreign key FK85F82042E2DC84FD; +drop table if exists accounts_roles; drop table if exists permissions; drop table if exists permissions_actions; drop table if exists permissions_roles; drop table if exists roles; -drop table if exists users_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, 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, ACTIONS_PERMISSION_CSID varchar(128), primary key (HJID)); -create table permissions_roles (HJID bigint not null auto_increment, 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), updated_at datetime, primary key (HJID), unique (permission_id, role_id)); +create table permissions_roles (HJID bigint not null auto_increment, 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)); -create table users_roles (HJID bigint not null auto_increment, created_at datetime not null, role_id varchar(128) not null, updated_at datetime, username varchar(128) not null, primary key (HJID), unique (username, role_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/authorization_index.sql b/services/authorization/pstore/src/main/resources/db/mysql/authorization_index.sql index 6d9a19740..012e86abd 100644 --- a/services/authorization/pstore/src/main/resources/db/mysql/authorization_index.sql +++ b/services/authorization/pstore/src/main/resources/db/mysql/authorization_index.sql @@ -1,5 +1,5 @@ -- --- Copyright 20010 University of California at Berkeley +-- Copyright 2010 University of California at Berkeley -- Licensed under the Educational Community License (ECL), Version 2.0. -- You may not use this file except in compliance with this License. -- @@ -7,7 +7,10 @@ use cspace; CREATE INDEX index_rolename ON roles (rolename); CREATE INDEX index_rolegroup ON roles (rolegroup); CREATE INDEX index_tenant_id ON roles (tenant_id); -CREATE INDEX index_username ON users_roles (username); -CREATE INDEX index_role_id ON users_roles (role_id); + +CREATE INDEX index_user_id ON accounts_roles (user_id); +CREATE INDEX index_account_id ON accounts_roles (account_id); +CREATE INDEX index_role_id ON accounts_roles (role_id); + CREATE INDEX index_permission_id ON permissions_roles (permission_id); CREATE INDEX index_role_id ON permissions_roles (role_id); 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 b63777d0a..874ed3e98 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 @@ -10,9 +10,10 @@ insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) values ('3', 'ROLE_COLLECTIONS_MANAGER', 'collections', '2010-02-17 16:31:48', '1'); insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) values ('4', 'ROLE_COLLECTIONS_REGISTRAR', 'collections', '2010-02-17 16:31:48', '1'); -insert into `users_roles`(`username`, `role_id`, `created_at`) values ('test', '1', '2010-02-17 16:31:48'); -insert into `users_roles`(`username`, `role_id`, `created_at`) values ('test', '2', '2010-02-17 16:31:48'); -insert into `users_roles`(`username`, `role_id`, `created_at`) values ('test', '3', '2010-02-17 16:31:48'); +insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '1', 'ROLE_ADMINISTRATOR', '2010-02-17 16:31:48'); +insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '2', 'ROLE_USERS', '2010-02-17 16:31:48'); +insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '3', 'ROLE_COLLECTIONS_MANAGER', '2010-02-17 16:31:48'); -insert into `users_roles`(`username`, `role_id`, `created_at`) values ('barney', '2', '2010-02-17 16:31:48'); -insert into `users_roles`(`username`, `role_id`, `created_at`) values ('barney', '3', '2010-02-17 16:31:48'); +-- todo: barney is created in security test but accountrole is not yet created there, so add fake account id +insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('1', 'barney', '2', 'ROLE_USERS', '2010-02-17 16:31:48'); +insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('1', 'barney', '3', 'ROLE_COLLECTIONS_MANAGER', '2010-02-17 16:31:48'); diff --git a/services/authorization/pstore/src/test/resources/META-INF/persistence.xml b/services/authorization/pstore/src/test/resources/META-INF/persistence.xml index 18d7e06bf..ec517f79d 100644 --- a/services/authorization/pstore/src/test/resources/META-INF/persistence.xml +++ b/services/authorization/pstore/src/test/resources/META-INF/persistence.xml @@ -6,7 +6,7 @@ org.collectionspace.services.authorization.PermissionAction org.collectionspace.services.authorization.PermissionRoleRel org.collectionspace.services.authorization.Role - org.collectionspace.services.authorization.UserRole + org.collectionspace.services.authorization.AccountRoleRel diff --git a/services/common/src/main/config/services/tenant-bindings.xml b/services/common/src/main/config/services/tenant-bindings.xml index 7660a6a3a..a9cd3d2de 100644 --- a/services/common/src/main/config/services/tenant-bindings.xml +++ b/services/common/src/main/config/services/tenant-bindings.xml @@ -686,6 +686,39 @@ + + + + org.collectionspace.services.account.storage.AccountRoleDocumentHandler + + + + + + + + + + + + + + + + + + diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java new file mode 100644 index 000000000..91ae14073 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java @@ -0,0 +1,290 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2010 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.common.storage.jpa; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.NoResultException; +import javax.persistence.Query; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.BadRequestException; +import org.collectionspace.services.common.document.DocumentException; +import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentHandler; +import org.collectionspace.services.common.document.DocumentHandler.Action; +import org.collectionspace.services.common.document.DocumentNotFoundException; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.document.DocumentWrapperImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JpaRelationshipStorageClient deals with a relationship + * in persistent storage. This storage client deals with bulk operations, i.e. + * create/post inserts multiple tuples between the given object and subjects + * get retrieves all subjects for the given object in relationship + * delete deletes all subjects for the given object in relationship + * @author + */ +public class JpaRelationshipStorageClient extends JpaStorageClientImpl { + + private final Logger logger = LoggerFactory.getLogger(JpaRelationshipStorageClient.class); + + public JpaRelationshipStorageClient() { + } + + /** + * create of a relationship creates one or more relationships between + * permission and role + * the object and subjects of the relationship is chosen (by doc handler) from + * the payload + * @param ctx + * @param handler + * @return + * @throws BadRequestException + * @throws DocumentException + */ + @Override + public String create(ServiceContext ctx, + DocumentHandler handler) throws BadRequestException, + DocumentException { + + if (ctx == null) { + throw new IllegalArgumentException( + "JpaRelationshipStorageClient.create : ctx is missing"); + } + if (handler == null) { + throw new IllegalArgumentException( + "JpaRelationshipStorageClient.create: handler is missing"); + } + EntityManagerFactory emf = null; + EntityManager em = null; + try { + handler.prepare(Action.CREATE); + List rl = new ArrayList(); + DocumentWrapper> wrapDoc = + new DocumentWrapperImpl>(rl); + handler.handle(Action.CREATE, wrapDoc); + emf = getEntityManagerFactory(); + em = emf.createEntityManager(); + em.getTransaction().begin(); + for (T r : rl) { + setValue(r, "setCreatedAtItem", Date.class, new Date()); + em.persist(r); + } + em.getTransaction().commit(); + handler.complete(Action.CREATE, wrapDoc); + return UUID.randomUUID().toString(); //filler, not useful + } catch (BadRequestException bre) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + throw bre; + } catch (Exception e) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + throw new DocumentException(e); + } finally { + if (em != null) { + releaseEntityManagerFactory(emf); + } + } + } + + /** + * get retrieves all relationships for the object in the relationship + * identified by the id. the object could be a permission or a role + * @param ctx + * @param id of the object in the relationship + * @param handler + * @throws DocumentNotFoundException + * @throws DocumentException + */ + @Override + public void get(ServiceContext ctx, String id, DocumentHandler handler) + throws DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaRelationshipStorageClient.get: ctx is missing"); + } + if (handler == null) { + throw new IllegalArgumentException( + "JpaRelationshipStorageClient.get: handler is missing"); + } + DocumentFilter docFilter = handler.getDocumentFilter(); + if (docFilter == null) { + docFilter = handler.createDocumentFilter(); + } + EntityManagerFactory emf = null; + EntityManager em = null; + try { + handler.prepare(Action.GET); + StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM "); + queryStrBldr.append(getEntityName(ctx)); + queryStrBldr.append(" a"); + String objectId = getObjectId(ctx); + if (logger.isDebugEnabled()) { + logger.debug("get: using objectId=" + objectId); + } + queryStrBldr.append(" WHERE " + objectId + " = :objectId"); + String where = docFilter.getWhereClause(); + if ((null != where) && (where.length() > 0)) { + queryStrBldr.append(" AND " + where); + } + emf = getEntityManagerFactory(); + em = emf.createEntityManager(); + String queryStr = queryStrBldr.toString(); //for debugging + if (logger.isDebugEnabled()) { + logger.debug("get: jql=" + queryStr.toString()); + } + Query q = em.createQuery(queryStr); + q.setParameter("objectId", id); + + List rl = new ArrayList(); + try { + //require transaction for get? + em.getTransaction().begin(); + rl = q.getResultList(); + em.getTransaction().commit(); + } catch (NoResultException nre) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + String msg = "could not find entity with id=" + id; + logger.error(msg, nre); + throw new DocumentNotFoundException(msg, nre); + } + if (rl.size() == 0) { + String msg = "could not find entity with id=" + id; + logger.error(msg); + throw new DocumentNotFoundException(msg); + } + DocumentWrapper> wrapDoc = + new DocumentWrapperImpl>(rl); + handler.handle(Action.GET, wrapDoc); + handler.complete(Action.GET, wrapDoc); + } catch (DocumentException de) { + throw de; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + throw new DocumentException(e); + } finally { + if (emf != null) { + releaseEntityManagerFactory(emf); + } + } + } + + /** + * delete removes all the relationships for the object in the relationship + * identified by the id. the object could be a permission or a role + * @param ctx + * @param id of the object in the relationship + * @throws DocumentNotFoundException + * @throws DocumentException + */ + @Override + public void delete(ServiceContext ctx, String id) + throws DocumentNotFoundException, + DocumentException { + + if (logger.isDebugEnabled()) { + logger.debug("deleting entity with id=" + id); + } + if (ctx == null) { + throw new IllegalArgumentException( + "JpaRelationshipStorageClient.delete : ctx is missing"); + } + EntityManagerFactory emf = null; + EntityManager em = null; + try { + StringBuilder deleteStr = new StringBuilder("DELETE FROM "); + deleteStr.append(getEntityName(ctx)); + String objectId = getObjectId(ctx); + if (logger.isDebugEnabled()) { + logger.debug("delete: using objectId=" + objectId); + } + deleteStr.append(" WHERE " + objectId + " = :objectId"); + emf = getEntityManagerFactory(); + em = emf.createEntityManager(); + if (logger.isDebugEnabled()) { + logger.debug("delete: jql=" + deleteStr.toString()); + } + Query q = em.createQuery(deleteStr.toString()); + q.setParameter("objectId", id); + int rcount = 0; + em.getTransaction().begin(); + rcount = q.executeUpdate(); + if (rcount == 0) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + String msg = "could not find entity with id=" + id; + logger.error(msg); + throw new DocumentNotFoundException(msg); + } + em.getTransaction().commit(); + + } catch (DocumentException de) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + throw de; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + throw new DocumentException(e); + } finally { + if (emf != null) { + releaseEntityManagerFactory(emf); + } + } + } + + protected String getObjectId(ServiceContext ctx) { + String objectId = (String) ctx.getProperty("objectId"); + if (objectId == null) { + String msg = "objectId is missing in the context"; + logger.error(msg); + throw new IllegalArgumentException(msg); + } + + return objectId; + } +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java index dc29738e3..552b17e44 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java @@ -152,6 +152,7 @@ public class JpaStorageClientImpl implements StorageClient { /* (non-Javadoc) * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler) */ + @Override public void get(ServiceContext ctx, List csidList, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { throw new UnsupportedOperationException(); diff --git a/services/pom.xml b/services/pom.xml index 4556e2b2f..50e57ef22 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -18,8 +18,8 @@ client jaxb common - account - authorization-mgt + authorization-mgt + account relation acquisition @@ -69,7 +69,7 @@ - + org.jvnet.hyperjaxb3 maven-hyperjaxb3-plugin @@ -94,7 +94,7 @@ maven-jaxb2-plugin 0.7.2 - + org.jvnet.jaxb2.maven2 maven-jaxb2-plugin -- 2.47.3