From c0e5a9d105f2ff8111edcb7ed615808919582139 Mon Sep 17 00:00:00 2001 From: Sanjay Dalal Date: Wed, 14 Apr 2010 20:27:24 +0000 Subject: [PATCH] CSPACE-1301 associate role(s) to permi CSPACE-1302 dis-associate role(s) from perm CSPACE-1347 role-perm schema added permission-role relationship. service is available as a subresource of permissions service (/permissions/{csid}/permroles). supports post, get and delete only. this version of delete deletes all associations for a permission. test: authz-mgt, all services requires: ant create_db at the service level M services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleStorageClient.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java _M services/authorization-mgt/client M services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java M services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java A services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionRoleServiceTest.java A services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleClient.java A services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleProxy.java M services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java M services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AbstractAuthorizationTestImpl.java D services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGenTest.java A + services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGen.java M services/authorization/service/src/test/resources/test-data/test-permissions-roles.xml M services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java M services/authorization/jaxb/src/main/resources/users_roles.xsd M services/authorization/jaxb/src/main/resources/permissions.xsd M services/authorization/jaxb/src/main/resources/permissions_roles.xsd M services/authorization/pstore/src/test/resources/META-INF/persistence.xml _M services/jaxb M services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java M services/common/src/main/config/services/tenant-bindings.xml M services/common/pom.xml M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java M services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java M services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java --- .../main/resources/META-INF/persistence.xml | 4 +- .../client/test/AccountServiceTest.java | 4 +- .../account/storage/AccountStorageClient.java | 24 +- .../services/client/PermissionRoleClient.java | 111 ++++ .../services/client/PermissionRoleProxy.java | 66 ++ .../test/PermissionRoleServiceTest.java | 463 ++++++++++++++ .../client/test/PermissionServiceTest.java | 16 +- .../client/test/RoleServiceTest.java | 4 +- .../authorization/PermissionResource.java | 136 ++++ .../PermissionRoleSubResource.java | 149 +++++ .../PermissionRoleDocumentHandler.java | 180 ++++++ .../storage/PermissionRoleStorageClient.java | 277 ++++++++ .../storage/PermissionRoleUtil.java | 43 ++ .../jaxb/src/main/resources/permissions.xsd | 10 +- .../src/main/resources/permissions_roles.xsd | 59 +- .../jaxb/src/main/resources/users_roles.xsd | 48 +- .../test/resources/META-INF/persistence.xml | 6 +- .../services/authorization/AuthZ.java | 9 +- .../test/AbstractAuthorizationTestImpl.java | 40 +- ...tionGenTest.java => AuthorizationGen.java} | 47 +- .../test/AuthorizationSeedTest.java | 20 +- .../test-data/test-permissions-roles.xml | 8 +- .../services/client/test/BaseServiceTest.java | 596 +++++++++--------- services/common/pom.xml | 10 +- .../main/config/services/tenant-bindings.xml | 35 +- .../storage/jpa/JpaStorageClientImpl.java | 27 +- 26 files changed, 1970 insertions(+), 422 deletions(-) create mode 100644 services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleClient.java create mode 100644 services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleProxy.java create mode 100644 services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionRoleServiceTest.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleStorageClient.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java rename services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/{AuthorizationGenTest.java => AuthorizationGen.java} (76%) diff --git a/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml b/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml index 120511413..ce4dc6a7e 100644 --- a/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml +++ b/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml @@ -11,11 +11,9 @@ org.collectionspace.services.authentication.User org.collectionspace.services.authorization.Permission org.collectionspace.services.authorization.PermissionAction - org.collectionspace.services.authorization.PermissionsList + org.collectionspace.services.authorization.PermissionRoleRel org.collectionspace.services.authorization.Role - org.collectionspace.services.authorization.RolesList org.collectionspace.services.authorization.UserRole - org.collectionspace.services.authorization.UsersRolesList diff --git a/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java b/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java index 3c5f92d97..beb92420a 100644 --- a/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java +++ b/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java @@ -590,7 +590,7 @@ public class AccountServiceTest extends AbstractServiceTestImpl { Assert.assertNotNull(toUpdateAccount); //change password - toUpdateAccount.setPassword(Base64.encodeBase64("imagination".getBytes())); + toUpdateAccount.setPassword("imagination".getBytes()); if (logger.isDebugEnabled()) { logger.debug(testName + ": updated object"); logger.debug(objectAsXmlString(toUpdateAccount, @@ -640,7 +640,7 @@ public class AccountServiceTest extends AbstractServiceTestImpl { toUpdateAccount.setUserId(null); //change password - toUpdateAccount.setPassword(Base64.encodeBase64("imagination".getBytes())); + toUpdateAccount.setPassword("imagination".getBytes()); if (logger.isDebugEnabled()) { logger.debug(testName + " : updated object"); logger.debug(objectAsXmlString(toUpdateAccount, diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java index be4c7482d..81e0909e0 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java @@ -61,10 +61,9 @@ public class AccountStorageClient extends JpaStorageClientImpl { DocumentHandler handler) throws BadRequestException, DocumentException { - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); + if (ctx == null) { + throw new IllegalArgumentException( + "AccountStorageClient.create : ctx is missing"); } if (handler == null) { throw new IllegalArgumentException( @@ -119,10 +118,9 @@ public class AccountStorageClient extends JpaStorageClientImpl { public void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException { - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); + if (ctx == null) { + throw new IllegalArgumentException( + "AccountStorageClient.update : ctx is missing"); } if (handler == null) { throw new IllegalArgumentException( @@ -184,10 +182,9 @@ public class AccountStorageClient extends JpaStorageClientImpl { if (logger.isDebugEnabled()) { logger.debug("deleting entity with id=" + id); } - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); + if (ctx == null) { + throw new IllegalArgumentException( + "AccountStorageClient.delete : ctx is missing"); } EntityManagerFactory emf = null; EntityManager em = null; @@ -265,7 +262,8 @@ public class AccountStorageClient extends JpaStorageClientImpl { private boolean checkAllowedUpdates(AccountsCommon toAccount, AccountsCommon fromAccount) throws BadRequestException { if (!fromAccount.getUserId().equals(toAccount.getUserId())) { - String msg = "User id " + toAccount.getUserId() + " not found!"; + String msg = "User id " + toAccount.getUserId() + " does not match " + + "for given account with csid=" + fromAccount.getCsid(); logger.error(msg); logger.debug(msg + " found userid=" + fromAccount.getUserId()); throw new BadRequestException(msg); diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleClient.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleClient.java new file mode 100644 index 000000000..d19605487 --- /dev/null +++ b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleClient.java @@ -0,0 +1,111 @@ +/** + * PermissionRoleClient.java + * + * {Purpose of This Class} + * + * {Other Notes Relating to This Class (Optional)} + * + * $LastChangedBy: $ + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + * 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 (C) 2009 {Contributing Institution} + * + * 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 + */ +package org.collectionspace.services.client; + +import javax.ws.rs.core.Response; + + +import org.collectionspace.services.authorization.PermissionRole; +import org.jboss.resteasy.client.ProxyFactory; +import org.jboss.resteasy.plugins.providers.RegisterBuiltin; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.spi.ResteasyProviderFactory; + +/** + * A PermissionRoleClient. + + * @version $Revision:$ + */ +public class PermissionRoleClient extends AbstractServiceClientImpl { + + /** + * + */ + private PermissionRoleProxy permissionRoleProxy; + + /* (non-Javadoc) + * @see + */ + public String getServicePathComponent() { + return "authorization/permissions"; + } + + /** + * + * Default constructor for PermissionRoleClient class. + * + */ + public PermissionRoleClient() { + ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance(); + RegisterBuiltin.register(factory); + setProxy(); + } + + /** + * allow to reset proxy as per security needs + */ + public void setProxy() { + if (useAuth()) { + permissionRoleProxy = ProxyFactory.create(PermissionRoleProxy.class, + getBaseURL(), getHttpClient()); + } else { + permissionRoleProxy = ProxyFactory.create(PermissionRoleProxy.class, + getBaseURL()); + } + } + + + /** + * @param csid + * @param prcsid relationship does not have an id, junk is fine + * @return + * @see + */ + public ClientResponse read(String csid, String prcsid) { + return permissionRoleProxy.read(csid, prcsid); + } + + /** + * @param permRole + * @return + * @see + */ + public ClientResponse create(String csid, PermissionRole permRole) { + return permissionRoleProxy.create(csid, permRole); + } + + + /** + * @param csid + * @param prcsid relationship does not have an id, junk is fine + * @return + * @see + */ + public ClientResponse delete(String csid, String prcsid) { + return permissionRoleProxy.delete(csid, prcsid); + } +} diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleProxy.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleProxy.java new file mode 100644 index 000000000..9f9ee1d74 --- /dev/null +++ b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionRoleProxy.java @@ -0,0 +1,66 @@ +/** + * PermissionRoleProxy.java + * + * {Purpose of This Class} + * + * {Other Notes Relating to This Class (Optional)} + * + * $LastChangedBy: $ + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + * 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 (C) 2009 {Contributing Institution} + * + * 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 + */ +package org.collectionspace.services.client; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + + +import org.collectionspace.services.authorization.PermissionRole; +import org.jboss.resteasy.client.ClientResponse; + +/** + * @version $Revision:$ + */ +@Path("/authorization/permissions") +@Produces({"application/xml"}) +@Consumes({"application/xml"}) +public interface PermissionRoleProxy { + + //(C)reate + @POST + @Path("/{csid}/permroles") + ClientResponse create(@PathParam("csid") String csid, PermissionRole permRole); + + //(R)ead + @GET + @Path("/{csid}/permroles/{prcsid}") + ClientResponse read(@PathParam("csid") String csid, + @PathParam("prcsid") String prcsid); + + //(D)elete + @DELETE + @Path("/{csid}/permroles/{prcsid}") + ClientResponse delete(@PathParam("csid") String csid, + @PathParam("prcsid") String prcsid); +} diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionRoleServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionRoleServiceTest.java new file mode 100644 index 000000000..5db336dc7 --- /dev/null +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionRoleServiceTest.java @@ -0,0 +1,463 @@ +/** + * 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 © 2009 Regents of the University of California + * + * 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 permRoles and + * limitations under the License. + */ +package org.collectionspace.services.authorization.client.test; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import javax.ws.rs.core.Response; +import org.collectionspace.services.authorization.EffectType; + +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionAction; +import org.collectionspace.services.authorization.PermissionRole; +import org.collectionspace.services.authorization.Role; +import org.collectionspace.services.client.PermissionClient; +import org.collectionspace.services.client.PermissionRoleClient; +import org.collectionspace.services.client.RoleClient; +import org.collectionspace.services.client.test.AbstractServiceTestImpl; +import org.collectionspace.services.client.test.ServiceRequestType; +import org.jboss.resteasy.client.ClientResponse; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +/** + * PermissionServiceTest, carries out tests against a + * deployed and running Permission, Role and PermissionRole Services. + * + * $LastChangedRevision: 917 $ + * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $ + */ +public class PermissionRoleServiceTest extends AbstractServiceTestImpl { + + private final Logger logger = + LoggerFactory.getLogger(PermissionRoleServiceTest.class); + // Instance variables specific to this test. + private PermissionRoleClient client = new PermissionRoleClient(); + private String knownResourceId = null; + private List allResourceIdsCreated = new ArrayList(); + private Hashtable permIds = new Hashtable(); + private Hashtable roleIds = new Hashtable(); + /* + * This method is called only by the parent class, AbstractServiceTestImpl + */ + + @Override + protected String getServicePathComponent() { + return client.getServicePathComponent(); + } + + @BeforeClass(alwaysRun = true) + public void seedData() { + String accPermId = createPermission("accounts", EffectType.PERMIT); + permIds.put("accounts", accPermId); + + String coPermId = createPermission("collectionobjects", EffectType.DENY); + permIds.put("collectionobjects", coPermId); + + String iPermId = createPermission("intakes", EffectType.DENY); + permIds.put("intakes", iPermId); + + String r1RoleId = createRole("ROLE_CO1"); + roleIds.put("ROLE_1", r1RoleId); + + String r2RoleId = createRole("ROLE_CO2"); + roleIds.put("ROLE_2", r2RoleId); + } + + // --------------------------------------------------------------- + // CRUD tests : CREATE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void create(String testName) throws Exception { + + // Perform setup, such as initializing the type of service request + // (e.g. CREATE, DELETE), its valid and expected status codes, and + // its associated HTTP method name (e.g. POST, DELETE). + setupCreate(testName); + + // Submit the request to the service and store the response. + PermissionRole permRole = createPermissionRoleInstance(permIds.get("accounts"), + roleIds.values().toArray(new String[0]), true, true); + ClientResponse res = client.create(permIds.get("accounts"), permRole); + 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, EXPECTED_STATUS_CODE); + + // Store the ID returned from this create operation + // for additional tests below. + //this is is not important in case of this relationship + knownResourceId = extractId(res); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": knownResourceId=" + knownResourceId); + } + } + + //to not cause uniqueness violation for permRole, createList is removed + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void createList(String testName) throws Exception { + + setupCreate(testName); + // Submit the request to the service and store the response. + PermissionRole permRole = createPermissionRoleInstance(permIds.get("collectionobjects"), + roleIds.values().toArray(new String[0]), true, true); + ClientResponse res = client.create(permIds.get("collectionobjects"), permRole); + int statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + //id of relationship is not important + allResourceIdsCreated.add(permIds.get("collectionobjects")); + + PermissionRole permRole2 = createPermissionRoleInstance(permIds.get("intakes"), + roleIds.values().toArray(new String[0]), true, true); + res = client.create(permIds.get("intakes"), permRole2); + statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + //id of relationship is not important + allResourceIdsCreated.add(permIds.get("intakes")); + + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + @Override + public void createWithEmptyEntityBody(String testName) throws Exception { + } + + @Override + public void createWithMalformedXml(String testName) throws Exception { + } + + @Override + public void createWithWrongXmlSchema(String testName) throws Exception { + } + + // --------------------------------------------------------------- + // CRUD tests : READ tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void read(String testName) throws Exception { + + // Perform setup. + setupRead(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.read(permIds.get("accounts"), "123"); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + PermissionRole output = (PermissionRole) res.getEntity(); + Assert.assertNotNull(output); + } + + // Failure outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void readNonExistent(String testName) throws Exception { + + // Perform setup. + setupReadNonExistent(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.read(NON_EXISTENT_ID, "123"); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + // --------------------------------------------------------------- + // CRUD tests : READ_LIST tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"createList", "read"}) + public void readList(String testName) throws Exception { + } + + // Failure outcomes + // None at present. + // --------------------------------------------------------------- + // CRUD tests : UPDATE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read", "readList", "readNonExistent"}) + public void update(String testName) throws Exception { + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + @Override + public void updateWithEmptyEntityBody(String testName) throws Exception { + } + + @Override + public void updateWithMalformedXml(String testName) throws Exception { + } + + @Override + public void updateWithWrongXmlSchema(String testName) throws Exception { + } + + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"readNonExistent", "testSubmitRequest"}) + public void updateNonExistent(String testName) throws Exception { + } + + // --------------------------------------------------------------- + // CRUD tests : DELETE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read"}) + public void delete(String testName) throws Exception { + + // Perform setup. + setupDelete(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.delete(permIds.get("accounts"), "123"); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + } + + // Failure outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void deleteNonExistent(String testName) throws Exception { + + // Perform setup. + setupDeleteNonExistent(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.delete(NON_EXISTENT_ID, "123"); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + // --------------------------------------------------------------- + // Utility tests : tests of code used in tests above + // --------------------------------------------------------------- + /** + * Tests the code for manually submitting data that is used by several + * of the methods above. + */ + @Test(dependsOnMethods = {"create"}) + public void testSubmitRequest() throws Exception { + + // Expected status code: 200 OK + final int EXPECTED_STATUS = Response.Status.OK.getStatusCode(); + + // Submit the request to the service and store the response. + String method = ServiceRequestType.READ.httpMethodName(); + String url = getResourceURL(permIds.get("accounts")); + int statusCode = submitRequest(method, url); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug("testSubmitRequest: url=" + url + + " status=" + statusCode); + } + Assert.assertEquals(statusCode, EXPECTED_STATUS); + + } + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + /** + * create permRolerole instance + * @param permId + * @param roleIds array of role ids + * @param userPermId + * @param useRoleId + * @return + */ + private PermissionRole createPermissionRoleInstance(String permId, + String[] roleIds, + boolean usePermId, + boolean useRoleId) { + + PermissionRole permRole = new PermissionRole(); + //service consume is not required to provide subject as it is determined + //from URI used +// permRole.setSubject(SubjectType.ROLE); + if (usePermId) { + ArrayList pl = new ArrayList(); + pl.add(permId); + permRole.setPermissionIds(pl); + } + if (useRoleId) { + ArrayList rl = new ArrayList(); + for (String roleId : roleIds) { + rl.add(roleId); + } + permRole.setRoleIds(rl); + } + + if (logger.isDebugEnabled()) { + logger.debug("to be created, permRole common"); + logger.debug(objectAsXmlString(permRole, PermissionRole.class)); + } + return permRole; + } + + @AfterClass(alwaysRun = true) + public void cleanUp() { + setupDelete("delete"); + if (logger.isDebugEnabled()) { + logger.debug("Cleaning up temporary resources created for testing ..."); + } + for (String resourceId : allResourceIdsCreated) { + // Note: Any non-success responses are ignored and not reported. + ClientResponse res = client.delete(resourceId, "123"); + int statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + for (String permId : permIds.values()) { + deletePermission(permId); + } + + for (String roleId : roleIds.values()) { + deleteRole(roleId); + } + } + + private String createPermission(String resName, EffectType effect) { + setupCreate(); + PermissionClient permClient = new PermissionClient(); + List actions = PermissionServiceTest.getDefaultActions(); + Permission permission = PermissionServiceTest.createPermissionInstance(resName, + "default permissions for " + resName, + actions, EffectType.PERMIT, true, true, true); + ClientResponse res = permClient.create(permission); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("createPermission" + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + return extractId(res); + } + + private void deletePermission(String permId) { + setupDelete(); + PermissionClient permClient = new PermissionClient(); + ClientResponse res = permClient.delete(permId); + int statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + private String createRole(String roleName) { + setupCreate(); + RoleClient roleClient = new RoleClient(); + + Role role = RoleServiceTest.createRoleInstance(roleName, + "role for " + roleName, true); + ClientResponse res = roleClient.create(role); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("createRole" + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + return extractId(res); + } + + private void deleteRole(String roleId) { + setupDelete(); + RoleClient roleClient = new RoleClient(); + ClientResponse res = roleClient.delete(roleId); + int statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } +} diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java index 3a15e30f4..486e4f381 100644 --- a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java @@ -52,7 +52,7 @@ import org.testng.annotations.AfterClass; */ public class PermissionServiceTest extends AbstractServiceTestImpl { - private final Logger logger = + static private final Logger logger = LoggerFactory.getLogger(PermissionServiceTest.class); // Instance variables specific to this test. private PermissionClient client = new PermissionClient(); @@ -163,8 +163,8 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); allResourceIdsCreated.add(extractId(res)); - Permission permission2 = createPermissionInstance("intakes", - "default permissions for intakes", + Permission permission2 = createPermissionInstance("acquisitions", + "default permissions for acquisitions", actions, EffectType.PERMIT, true, @@ -300,7 +300,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { setupReadList(testName); // Submit the request to the service and store the response. - ClientResponse res = client.readSearchList("intake"); + ClientResponse res = client.readSearchList("acquisition"); PermissionsList list = res.getEntity(); int statusCode = res.getStatus(); // Check the status code of the response: does it match @@ -409,8 +409,8 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { // Note: The ID used in this 'create' call may be arbitrary. // The only relevant ID may be the one used in updatePermission(), below. List actions = getDefaultActions(); - Permission permission = createPermissionInstance("intakes", - "default permissions for intakes", + Permission permission = createPermissionInstance("acquisitions", + "default permissions for acquisitions", actions, EffectType.PERMIT, true, @@ -521,7 +521,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { * @param useEffect * @return */ - private Permission createPermissionInstance(String resourceName, + static Permission createPermissionInstance(String resourceName, String description, List actionList, EffectType effect, @@ -548,7 +548,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { return permission; } - private List getDefaultActions() { + static List getDefaultActions() { List actions = new ArrayList(); PermissionAction create = new PermissionAction(); create.setName(ActionType.CREATE); 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 59e085de7..6616b18b6 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 @@ -49,7 +49,7 @@ import org.testng.annotations.AfterClass; */ public class RoleServiceTest extends AbstractServiceTestImpl { - private final Logger logger = + static private final Logger logger = LoggerFactory.getLogger(RoleServiceTest.class); // Instance variables specific to this test. private RoleClient client = new RoleClient(); @@ -509,7 +509,7 @@ public class RoleServiceTest extends AbstractServiceTestImpl { * @param useRoleName * @return */ - private Role createRoleInstance(String roleName, + static Role createRoleInstance(String roleName, String description, boolean useRoleName) { diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java index 37a0f0a33..88ccc3970 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java @@ -299,4 +299,140 @@ public class PermissionResource } } + + @POST + @Path("{csid}/permroles") + public Response createPermissionRole(@PathParam("csid") String permCsid, + PermissionRole input) { + if (logger.isDebugEnabled()) { + logger.debug("createPermissionRole with permCsid=" + permCsid); + } + if (permCsid == null || "".equals(permCsid)) { + logger.error("createPermissionRole: missing permCsid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "create failed on PermissionRole permCsid=" + permCsid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + try { + PermissionRoleSubResource subResource = new PermissionRoleSubResource(); + String permrolecsid = subResource.createPermissionRole(input, SubjectType.ROLE); + UriBuilder path = UriBuilder.fromResource(PermissionResource.class); + path.path(permCsid + "/permroles/" + permrolecsid); + Response response = Response.created(path.build()).build(); + return response; + } catch (BadRequestException bre) { + Response response = Response.status( + Response.Status.BAD_REQUEST).entity("Create failed reason " + + bre.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Create failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in createPermissionRole", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Create failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + } + + @GET + @Path("{csid}/permroles/{permrolecsid}") + public PermissionRole getPermissionRole( + @PathParam("csid") String permCsid, + @PathParam("permrolecsid") String permrolecsid) { + if (logger.isDebugEnabled()) { + logger.debug("getPermissionRole with permCsid=" + permCsid); + } + if (permCsid == null || "".equals(permCsid)) { + logger.error("getPermissionRole: missing permCsid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "get failed on PermissionRole permCsid=" + permCsid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + PermissionRole result = null; + try { + PermissionRoleSubResource subResource = new PermissionRoleSubResource(); + //get relationships for a permission + result = subResource.getPermissionRole(permCsid, SubjectType.ROLE); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Get failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("getPermissionRole", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed on PermissionRole permrolecsid=" + permrolecsid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("getPermissionRole", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Get failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + if (result == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed, the requested PermissionRole permrolecsid:" + permrolecsid + + ": was not found.").type( + "text/plain").build(); + throw new WebApplicationException(response); + } + return result; + } + + @DELETE + @Path("{csid}/permroles/{permrolecsid}") + public Response deletePermissionRole( + @PathParam("csid") String permCsid, + @PathParam("permrolecsid") String permrolecsid) { + if (logger.isDebugEnabled()) { + logger.debug("deletePermissionRole with permCsid=" + permCsid); + } + if (permCsid == null || "".equals(permCsid)) { + logger.error("deletePermissionRole: missing permCsid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "delete failed on PermissionRole permCsid=" + permCsid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + try { + PermissionRoleSubResource subResource = new PermissionRoleSubResource(); + //delete all relationships for a permission + subResource.deletePermissionRole(permCsid, SubjectType.ROLE); + return Response.status(HttpResponseCodes.SC_OK).build(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Delete failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("caught exception in deletePermissionRole", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Delete failed on PermissionRole permrolecsid=" + permrolecsid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Delete failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + + } } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java new file mode 100644 index 000000000..2b59ec293 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java @@ -0,0 +1,149 @@ +/** + * 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 2009 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.authorization; + +import javax.ws.rs.PathParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; +import org.collectionspace.services.authorization.storage.PermissionRoleStorageClient; + +import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl; +import org.collectionspace.services.common.context.RemoteServiceContextImpl; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentHandler; +import org.collectionspace.services.common.storage.StorageClient; +import org.jboss.resteasy.util.HttpResponseCodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * PermissionRoleSubResource is used to manage permission-role relationship + * @author + */ +public class PermissionRoleSubResource + extends AbstractCollectionSpaceResourceImpl { + + //this service is never exposed as standalone RESTful service...just use unique + //service name to identify binding + final private String serviceName = "authorization/permroles"; + final Logger logger = LoggerFactory.getLogger(PermissionRoleSubResource.class); + final StorageClient storageClient = new PermissionRoleStorageClient(); + + @Override + protected String getVersionString() { + /** The last change revision. */ + final String lastChangeRevision = "$LastChangedRevision: 1165 $"; + return lastChangeRevision; + } + + @Override + public String getServiceName() { + return serviceName; + } + + private ServiceContext createServiceContext(T obj, SubjectType subject) throws Exception { + ServiceContext ctx = new RemoteServiceContextImpl(getServiceName()); + ctx.setInput(obj); + ctx.setDocumentType(PermissionRole.class.getPackage().getName()); //persistence unit + ctx.setProperty("entity-name", PermissionRoleRel.class.getName()); + //subject name is necessary to indicate if role or permission is a subject + ctx.setProperty("subject", subject); + return ctx; + } + + @Override + public StorageClient getStorageClient(ServiceContext ctx) { + //FIXME use ctx to identify storage client + return storageClient; + } + + @Override + public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception { + DocumentHandler docHandler = ctx.getDocumentHandler(); + docHandler.setCommonPart(ctx.getInput()); + return docHandler; + } + + /** + * createPermissionRole creates one or more permission-role relationships + * between object (permission/role) and subject (role/permission) + * @param input + * @param subject + * @return + * @throws Exception + */ + public String createPermissionRole(PermissionRole input, SubjectType subject) + throws Exception { + + ServiceContext ctx = createServiceContext(input, subject); + DocumentHandler handler = createDocumentHandler(ctx); + return getStorageClient(ctx).create(ctx, handler); + } + + /** + * getPermissionRole retrieves permission-role relationships using given + * csid of object (permission/role) and subject (role/permission) + * @param csid + * @param subject + * @return + * @throws Exception + */ + public PermissionRole getPermissionRole( + String csid, SubjectType subject) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug("getPermissionRole with csid=" + csid); + } + PermissionRole result = null; + ServiceContext ctx = createServiceContext((PermissionRole) null, subject); + DocumentHandler handler = createDocumentHandler(ctx); + getStorageClient(ctx).get(ctx, csid, handler); + result = (PermissionRole) ctx.getOutput(); + + return result; + } + + /** + * deletePermissionRole deletes permission-role relationships using given + * csid of object (permission/role) and subject (role/permission) + * @param csid + * @param subject + * @return + * @throws Exception + */ + public void deletePermissionRole(String csid, + SubjectType subject) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug("deletePermissionRole with csid=" + csid); + } + ServiceContext ctx = createServiceContext((PermissionRole) null, subject); + getStorageClient(ctx).delete(ctx, csid); + } +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java new file mode 100644 index 000000000..8bd86ea50 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java @@ -0,0 +1,180 @@ +/** + * 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 2009 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 permissionRoles and + * limitations under the License. + */ +package org.collectionspace.services.authorization.storage; + +import java.util.ArrayList; +import java.util.List; + +import org.collectionspace.services.authorization.PermissionRole; +import org.collectionspace.services.authorization.PermissionRoleRel; +import org.collectionspace.services.authorization.PermissionsRolesList; +import org.collectionspace.services.authorization.SubjectType; +import org.collectionspace.services.common.context.ServiceContext; + +import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; +import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Document handler for PermissionRole association + * @author + */ +public class PermissionRoleDocumentHandler + extends AbstractDocumentHandlerImpl, List> { + + private final Logger logger = LoggerFactory.getLogger(PermissionRoleDocumentHandler.class); + private PermissionRole permissionRole; + private PermissionsRolesList permissionRolesList; + + @Override + public void handleCreate(DocumentWrapper> wrapDoc) throws Exception { + fillCommonPart(getCommonPart(), wrapDoc); + } + + @Override + public void handleUpdate(DocumentWrapper> wrapDoc) throws Exception { + throw new UnsupportedOperationException("operation not relevant for PermissionRoleDocumentHandler"); + } + + @Override + public void completeUpdate(DocumentWrapper> wrapDoc) throws Exception { + throw new UnsupportedOperationException("operation not relevant for PermissionRoleDocumentHandler"); + } + + @Override + public void handleGet(DocumentWrapper> wrapDoc) throws Exception { + setCommonPart(extractCommonPart(wrapDoc)); + getServiceContext().setOutput(permissionRole); + } + + @Override + public void handleGetAll(DocumentWrapper> wrapDoc) throws Exception { + throw new UnsupportedOperationException("operation not relevant for PermissionRoleDocumentHandler"); + } + + @Override + public PermissionRole extractCommonPart( + DocumentWrapper> wrapDoc) + throws Exception { + List prrl = wrapDoc.getWrappedObject(); + PermissionRole pr = new PermissionRole(); + SubjectType subject = PermissionRoleUtil.getSubject(getServiceContext()); + pr.setSubject(subject); + if (SubjectType.ROLE.equals(subject)) { + List permIds = new ArrayList(); + permIds.add(prrl.get(0).getPermissionId()); + pr.setPermissionIds(permIds); + List roleIds = new ArrayList(); + for (PermissionRoleRel prr : prrl) { + roleIds.add(prr.getRoleId()); + pr.setCreatedAt(prr.getCreatedAt()); + pr.setUpdatedAt(prr.getUpdatedAt()); + } + pr.setRoleIds(roleIds); + } else { + List roleIds = new ArrayList(); + roleIds.add(prrl.get(0).getRoleId()); + pr.setRoleIds(roleIds); + List permIds = new ArrayList(); + for (PermissionRoleRel prr : prrl) { + permIds.add(prr.getPermissionId()); + pr.setCreatedAt(prr.getCreatedAt()); + pr.setUpdatedAt(prr.getUpdatedAt()); + } + pr.setPermissionIds(permIds); + } + return pr; + } + + @Override + public void fillCommonPart(PermissionRole pr, DocumentWrapper> wrapDoc) + throws Exception { + List prrl = wrapDoc.getWrappedObject(); + SubjectType subject = pr.getSubject(); + if (subject == null) { + //it is not required to give subject as URI determines the subject + subject = PermissionRoleUtil.getSubject(getServiceContext()); + } else { + //subject mismatch should have been checked during validation + } + if (subject.equals(SubjectType.ROLE)) { + String permId = pr.getPermissionIds().get(0); + for (String roleId : pr.getRoleIds()) { + PermissionRoleRel prr = new PermissionRoleRel(); + prr.setPermissionId(permId); + prr.setRoleId(roleId); + prrl.add(prr); + } + } else { + String roleId = pr.getRoleIds().get(0); + for (String permId : pr.getPermissionIds()) { + PermissionRoleRel prr = new PermissionRoleRel(); + prr.setPermissionId(permId); + prr.setRoleId(roleId); + prrl.add(prr); + } + } + } + + @Override + public PermissionsRolesList extractCommonPartList( + DocumentWrapper> wrapDoc) + throws Exception { + + throw new UnsupportedOperationException("operation not relevant for PermissionRoleDocumentHandler"); + } + + @Override + public PermissionRole getCommonPart() { + return permissionRole; + } + + @Override + public void setCommonPart(PermissionRole permissionRole) { + this.permissionRole = permissionRole; + } + + @Override + public PermissionsRolesList getCommonPartList() { + return permissionRolesList; + } + + @Override + public void setCommonPartList(PermissionsRolesList permissionRolesList) { + this.permissionRolesList = permissionRolesList; + } + + @Override + public String getQProperty( + String prop) { + return null; + } + + @Override + public DocumentFilter createDocumentFilter(ServiceContext ctx) { + return new DocumentFilter(); + } +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleStorageClient.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleStorageClient.java new file mode 100644 index 000000000..20c1b820f --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleStorageClient.java @@ -0,0 +1,277 @@ +/** + * 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 2009 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.authorization.storage; + +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.authorization.PermissionRoleRel; +import org.collectionspace.services.authorization.SubjectType; +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.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * PermissionRoleStorageClient deals with PermissionRole 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 PermissionRoleStorageClient extends JpaStorageClientImpl { + + private final Logger logger = LoggerFactory.getLogger(PermissionRoleStorageClient.class); + + public PermissionRoleStorageClient() { + } + + /** + * create of PermissionRole 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( + "PermissionRoleStorageClient.create : ctx is missing"); + } + if (handler == null) { + throw new IllegalArgumentException( + "PermissionRoleStorageClient.create: handler is missing"); + } + EntityManagerFactory emf = null; + EntityManager em = null; + try { + handler.prepare(Action.CREATE); + List prrl = new ArrayList(); + DocumentWrapper> wrapDoc = + new DocumentWrapperImpl>(prrl); + handler.handle(Action.CREATE, wrapDoc); + emf = getEntityManagerFactory(); + em = emf.createEntityManager(); + em.getTransaction().begin(); + for (PermissionRoleRel prr : prrl) { + prr.setCreatedAtItem(new Date()); + em.persist(prr); + } + 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 + */ + public void get(ServiceContext ctx, String id, DocumentHandler handler) + throws DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.get: ctx is missing"); + } + if (handler == null) { + throw new IllegalArgumentException( + "JpaStorageClient.get: handler is missing"); + } + DocumentFilter docFilter = handler.getDocumentFilter(); + if (docFilter == null) { + docFilter = handler.createDocumentFilter(ctx); + } + 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"); + SubjectType subject = PermissionRoleUtil.getSubject(ctx); + String objectId = "permission_id"; + if (SubjectType.PERMISSION.equals(subject)) { + objectId = "role_id"; + } + 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 + Query q = em.createQuery(queryStr); + q.setParameter("objectId", id); + + List prrl = new ArrayList(); + try { + //require transaction for get? + em.getTransaction().begin(); + prrl = 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 (prrl.size() == 0) { + String msg = "could not find entity with id=" + id; + logger.error(msg); + throw new DocumentNotFoundException(msg); + } + DocumentWrapper> wrapDoc = + new DocumentWrapperImpl>(prrl); + 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( + "PermissionRoleStorageClient.delete : ctx is missing"); + } + EntityManagerFactory emf = null; + EntityManager em = null; + try { + StringBuilder deleteStr = new StringBuilder("DELETE FROM "); + deleteStr.append(getEntityName(ctx)); + SubjectType subject = PermissionRoleUtil.getSubject(ctx); + String objectId = "permission_id"; + if (SubjectType.PERMISSION.equals(subject)) { + objectId = "role_id"; + } + deleteStr.append(" WHERE " + objectId + " = :objectId"); + emf = getEntityManagerFactory(); + em = emf.createEntityManager(); + 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); + } + } + } +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java new file mode 100644 index 000000000..6121b514b --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java @@ -0,0 +1,43 @@ +/** + * 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 2009 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.authorization.storage; + +import org.collectionspace.services.authorization.SubjectType; +import org.collectionspace.services.common.context.ServiceContext; + +/** + * + * @author + */ +public class PermissionRoleUtil { + + static SubjectType getSubject(ServiceContext ctx) { + Object o = ctx.getProperty("subject"); + if (o == null) { + throw new IllegalArgumentException("property subject missing in context " + + ctx.toString()); + } + return (SubjectType) o; + } +} diff --git a/services/authorization/jaxb/src/main/resources/permissions.xsd b/services/authorization/jaxb/src/main/resources/permissions.xsd index 94c696b4e..d0ed3f161 100644 --- a/services/authorization/jaxb/src/main/resources/permissions.xsd +++ b/services/authorization/jaxb/src/main/resources/permissions.xsd @@ -11,7 +11,7 @@ --> - + @@ -150,7 +150,7 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" - + @@ -162,7 +162,7 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" - + @@ -176,7 +176,7 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" - + diff --git a/services/authorization/jaxb/src/main/resources/permissions_roles.xsd b/services/authorization/jaxb/src/main/resources/permissions_roles.xsd index 492d64d6d..5d00ac2a0 100644 --- a/services/authorization/jaxb/src/main/resources/permissions_roles.xsd +++ b/services/authorization/jaxb/src/main/resources/permissions_roles.xsd @@ -3,23 +3,25 @@ - + + + + A list of permission_role association for a permission or a role + @@ -48,10 +64,43 @@ - + + + - PermissionRole defines association between permission and role in CollectionSpace + + PermissionRole defines 1-n association between + either permission and role or role and permission + + + + + + + + + + + + + + + + + + + + + + + + + + PermissionRoleRel defines 1-1 association between + permission and role in CollectionSpace. Note that this relation + is defined exclusively for service-side use only. + diff --git a/services/authorization/jaxb/src/main/resources/users_roles.xsd b/services/authorization/jaxb/src/main/resources/users_roles.xsd index 745d139b3..b9337bdda 100644 --- a/services/authorization/jaxb/src/main/resources/users_roles.xsd +++ b/services/authorization/jaxb/src/main/resources/users_roles.xsd @@ -10,16 +10,18 @@ $LastChangedDate: 2009-11-05 16:59:20 -0800 (Thu, 05 Nov 2009) $ --> - - - - - - - - - - - user role list - - - - - + + UserRole defines association between user and role in CollectionSpace @@ -104,6 +102,22 @@ + + + + users roles list + + + + + + + account role list + + + + + 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 ed8a21faf..18d7e06bf 100644 --- a/services/authorization/pstore/src/test/resources/META-INF/persistence.xml +++ b/services/authorization/pstore/src/test/resources/META-INF/persistence.xml @@ -4,13 +4,9 @@ org.collectionspace.services.authorization.Permission org.collectionspace.services.authorization.PermissionAction - org.collectionspace.services.authorization.PermissionsList - org.collectionspace.services.authorization.PermissionRole - org.collectionspace.services.authorization.PermissionsRolesList + org.collectionspace.services.authorization.PermissionRoleRel org.collectionspace.services.authorization.Role - org.collectionspace.services.authorization.RolesList org.collectionspace.services.authorization.UserRole - org.collectionspace.services.authorization.UsersRolesList diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java index 13547bb76..5a1168081 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java @@ -108,14 +108,15 @@ public class AuthZ { List permRoles) { List principals = new ArrayList(); for (PermissionRole permRole : permRoles) { - if (!perm.getCsid().equals(permRole.getPermissionId())) { + if (!perm.getCsid().equals(permRole.getPermissionIds().get(0))) { throw new IllegalArgumentException("permission ids do not" - + " match role=" + permRole.getRoleId() - + " permission=" + perm.getCsid()); + + " match for role=" + permRole.getRoleIds().get(0) + + " with permissionId=" + permRole.getPermissionIds().get(0) + + " for permission with csid=" + perm.getCsid()); } //assuming permrole belongs to the same perm //FIXME should use role name - principals.add(permRole.getRoleId()); + principals.add(permRole.getRoleIds().get(0)); } List permActions = perm.getActions(); for (PermissionAction permAction : permActions) { diff --git a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AbstractAuthorizationTestImpl.java b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AbstractAuthorizationTestImpl.java index f8364c9fc..259ae39c7 100644 --- a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AbstractAuthorizationTestImpl.java +++ b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AbstractAuthorizationTestImpl.java @@ -50,24 +50,16 @@ package org.collectionspace.services.authorization.test; import java.io.File; +import java.io.FileInputStream; import java.io.InputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashSet; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; -import org.collectionspace.services.authorization.ActionType; import org.collectionspace.services.authorization.AuthZ; -import org.collectionspace.services.authorization.Permission; -import org.collectionspace.services.authorization.EffectType; -import org.collectionspace.services.authorization.PermissionAction; -import org.collectionspace.services.authorization.PermissionsList; -import org.collectionspace.services.authorization.PermissionRole; -import org.collectionspace.services.authorization.PermissionsList; -import org.collectionspace.services.authorization.PermissionsRolesList; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -77,7 +69,6 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; -import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -89,6 +80,7 @@ public abstract class AbstractAuthorizationTestImpl { final Logger logger = LoggerFactory.getLogger(AbstractAuthorizationTestImpl.class); private org.springframework.jdbc.datasource.DataSourceTransactionManager txManager; + final static String testDataDir = "src/test/resources/test-data/"; /** * Returns the name of the currently running test. @@ -107,7 +99,6 @@ public abstract class AbstractAuthorizationTestImpl { }; } - protected void setup() { ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( new String[]{"applicationContext-authorization-test.xml"}); @@ -144,8 +135,7 @@ public abstract class AbstractAuthorizationTestImpl { txManager.commit(status); } - - protected void toFile(Object o, Class jaxbClass, String fileName) { + static void toFile(Object o, Class jaxbClass, String fileName) { File f = new File(fileName); try { JAXBContext jc = JAXBContext.newInstance(jaxbClass); @@ -158,14 +148,22 @@ public abstract class AbstractAuthorizationTestImpl { } } - protected Object fromFile(Class jaxbClass, String fileName) throws Exception { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - InputStream is = tccl.getResourceAsStream(fileName); - JAXBContext context = JAXBContext.newInstance(jaxbClass); - Unmarshaller unmarshaller = context.createUnmarshaller(); - //note: setting schema to null will turn validator off - unmarshaller.setSchema(null); - return jaxbClass.cast(unmarshaller.unmarshal(is)); + static Object fromFile(Class jaxbClass, String fileName) throws Exception { + InputStream is = new FileInputStream(fileName); + try { + JAXBContext context = JAXBContext.newInstance(jaxbClass); + Unmarshaller unmarshaller = context.createUnmarshaller(); + //note: setting schema to null will turn validator off + unmarshaller.setSchema(null); + return jaxbClass.cast(unmarshaller.unmarshal(is)); + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + } + } + } } @Test(dataProvider = "testName", dataProviderClass = AbstractAuthorizationTestImpl.class) diff --git a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGenTest.java b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGen.java similarity index 76% rename from services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGenTest.java rename to services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGen.java index 3896e8297..744540bb0 100644 --- a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGenTest.java +++ b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationGen.java @@ -48,6 +48,7 @@ package org.collectionspace.services.authorization.test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.List; import org.collectionspace.services.authorization.ActionType; import org.collectionspace.services.authorization.Permission; import org.collectionspace.services.authorization.EffectType; @@ -55,17 +56,16 @@ import org.collectionspace.services.authorization.PermissionAction; import org.collectionspace.services.authorization.PermissionRole; import org.collectionspace.services.authorization.PermissionsList; import org.collectionspace.services.authorization.PermissionsRolesList; -import org.testng.annotations.Test; +import org.collectionspace.services.authorization.SubjectType; /** * * @author */ -public class AuthorizationGenTest extends AbstractAuthorizationTestImpl { +public class AuthorizationGen { - final Logger logger = LoggerFactory.getLogger(AuthorizationGenTest.class); + final Logger logger = LoggerFactory.getLogger(AuthorizationGen.class); - @Test public void genPermissions() { PermissionsList pcList = new PermissionsList(); ArrayList apcList = new ArrayList(); @@ -75,7 +75,10 @@ public class AuthorizationGenTest extends AbstractAuthorizationTestImpl { apcList.add(accPerm); Permission coPerm = buildCommonPermission("2", "collectionobjects"); apcList.add(coPerm); - toFile(pcList, PermissionsList.class, "./target/test-permissions.xml"); + AbstractAuthorizationTestImpl.toFile(pcList, PermissionsList.class, + AbstractAuthorizationTestImpl.testDataDir + "test-permissions.xml"); + logger.info("generated permissions to " + + AbstractAuthorizationTestImpl.testDataDir + "test-permissions.xml"); } @@ -103,27 +106,31 @@ public class AuthorizationGenTest extends AbstractAuthorizationTestImpl { return perm; } - @Test public void genPermissionsRoles() { PermissionsRolesList psrsl = new PermissionsRolesList(); - ArrayList prl = buildCommonPermissionRoles("1"); - prl.addAll(buildCommonPermissionRoles("2")); + ArrayList prl = new ArrayList(); + prl.add(buildCommonPermissionRoles("1")); + prl.add(buildCommonPermissionRoles("2")); psrsl.setPermissionRoles(prl); - toFile(psrsl, PermissionsRolesList.class, "./target/test-permissions-roles.xml"); + AbstractAuthorizationTestImpl.toFile(psrsl, PermissionsRolesList.class, + AbstractAuthorizationTestImpl.testDataDir + "test-permissions-roles.xml"); + logger.info("generated permissions-roles to " + + AbstractAuthorizationTestImpl.testDataDir + "test-permissions-roles.xml"); } - private ArrayList buildCommonPermissionRoles(String id) { - ArrayList prl = new ArrayList(); + private PermissionRole buildCommonPermissionRoles(String id) { + PermissionRole pr = new PermissionRole(); - pr.setPermissionId(id); + pr.setSubject(SubjectType.ROLE); + List permIds = new ArrayList(); + permIds.add(id); + pr.setPermissionIds(permIds); //FIXME should using role id - pr.setRoleId("ROLE_USERS"); - prl.add(pr); - PermissionRole pr1 = new PermissionRole(); - pr1.setPermissionId(id); - //FIXME shoudl use role id - pr1.setRoleId("ROLE_ADMINISTRATOR"); - prl.add(pr1); - return prl; + List roleIds = new ArrayList(); + roleIds.add("ROLE_USERS"); + roleIds.add("ROLE_ADMINISTRATOR"); + pr.setRoleIds(roleIds); + return pr; + } } diff --git a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java index 63781455c..4abddef05 100644 --- a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java +++ b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java @@ -43,7 +43,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.collectionspace.services.authorization.test; import java.util.ArrayList; @@ -71,6 +70,9 @@ public class AuthorizationSeedTest extends AbstractAuthorizationTestImpl { setup(); TransactionStatus status = beginTransaction("seedData"); try { + AuthorizationGen authzGen = new AuthorizationGen(); + authzGen.genPermissions(); + authzGen.genPermissionsRoles(); seedRoles(); seedPermissions(); } catch (Exception ex) { @@ -88,12 +90,14 @@ public class AuthorizationSeedTest extends AbstractAuthorizationTestImpl { PermissionsList pcList = (PermissionsList) fromFile(PermissionsList.class, - "./test-data/test-permissions.xml"); - + AbstractAuthorizationTestImpl.testDataDir + "test-permissions.xml"); + logger.info("read permissions from " + + AbstractAuthorizationTestImpl.testDataDir + "test-permissions.xml"); PermissionsRolesList pcrList = (PermissionsRolesList) fromFile(PermissionsRolesList.class, - "./test-data/test-permissions-roles.xml"); - + AbstractAuthorizationTestImpl.testDataDir + "test-permissions-roles.xml"); + logger.info("read permissions-roles from " + + AbstractAuthorizationTestImpl.testDataDir + "test-permissions.xml"); AuthZ authZ = AuthZ.get(); for (Permission p : pcList.getPermissions()) { if (logger.isDebugEnabled()) { @@ -107,9 +111,9 @@ public class AuthorizationSeedTest extends AbstractAuthorizationTestImpl { private List getPermissionRoles(PermissionsRolesList pcrList, String permId) { List prList = new ArrayList(); for (PermissionRole pr : pcrList.getPermissionRoles()) { - if (pr.getPermissionId().equals(permId)) { - prList.add(pr); - } + if (pr.getPermissionIds().get(0).equals(permId)) { + prList.add(pr); + } } return prList; } diff --git a/services/authorization/service/src/test/resources/test-data/test-permissions-roles.xml b/services/authorization/service/src/test/resources/test-data/test-permissions-roles.xml index f58460500..67b54370b 100644 --- a/services/authorization/service/src/test/resources/test-data/test-permissions-roles.xml +++ b/services/authorization/service/src/test/resources/test-data/test-permissions-roles.xml @@ -1,19 +1,15 @@ + ROLE 1 ROLE_USERS - - - 1 ROLE_ADMINISTRATOR + ROLE 2 ROLE_USERS - - - 2 ROLE_ADMINISTRATOR diff --git a/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java b/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java index 7234718b7..a85550c40 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java +++ b/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java @@ -33,299 +33,298 @@ import org.w3c.dom.Document; public abstract class BaseServiceTest { - protected final Logger logger = LoggerFactory.getLogger(BaseServiceTest.class); - protected static final TestServiceClient serviceClient = new TestServiceClient(); - protected final String NON_EXISTENT_ID = createNonExistentIdentifier(); - protected int EXPECTED_STATUS_CODE = 0; - protected ServiceRequestType REQUEST_TYPE = ServiceRequestType.NON_EXISTENT; - protected static final String XML_DECLARATION = ""; - protected static final String MALFORMED_XML_DATA = XML_DECLARATION + - "wrong schema contentswrong schema contents"; - final String NULL_CHARSET = null; + static protected final Logger logger = LoggerFactory.getLogger(BaseServiceTest.class); + protected static final TestServiceClient serviceClient = new TestServiceClient(); + protected final String NON_EXISTENT_ID = createNonExistentIdentifier(); + protected int EXPECTED_STATUS_CODE = 0; + protected ServiceRequestType REQUEST_TYPE = ServiceRequestType.NON_EXISTENT; + protected static final String XML_DECLARATION = ""; + protected static final String MALFORMED_XML_DATA = XML_DECLARATION + + "wrong schema contentswrong schema contents"; + final String NULL_CHARSET = null; - /** - * Returns the name of the currently running test. - * - * Note: although the return type is listed as Object[][], - * this method instead returns a String. - * - * @param m The currently running test method. - * - * @return The name of the currently running test method. - */ - @DataProvider(name = "testName") - public static Object[][] testName(Method m) { - return new Object[][]{ - new Object[] { m.getName() } - }; - } + /** + * Returns the name of the currently running test. + * + * Note: although the return type is listed as Object[][], + * this method instead returns a String. + * + * @param m The currently running test method. + * + * @return The name of the currently running test method. + */ + @DataProvider(name = "testName") + public static Object[][] testName(Method m) { + return new Object[][]{ + new Object[]{m.getName()} + }; + } - /** - * Returns the URL path component of the service. - * - * This component will follow directly after the - * base path, if any. - * - * @return The URL path component of the service. - */ - protected abstract String getServicePathComponent(); + /** + * Returns the URL path component of the service. + * + * This component will follow directly after the + * base path, if any. + * + * @return The URL path component of the service. + */ + protected abstract String getServicePathComponent(); - /** - * Reinitializes setup values, to help expose any unintended reuse - * of those values between tests. - */ - protected void clearSetup() { - EXPECTED_STATUS_CODE = 0; - REQUEST_TYPE = ServiceRequestType.NON_EXISTENT; - } - - /** - * Initializes setup valuesfor a given test. - */ - protected void testSetup( - int expectedStatusCode, - ServiceRequestType reqType, - String bannerLabel ) { - clearSetup(); - EXPECTED_STATUS_CODE = expectedStatusCode; - REQUEST_TYPE = reqType; - // Print a banner identifying the test that will be run. - if (logger.isDebugEnabled()) { - banner(bannerLabel); - } - } + /** + * Reinitializes setup values, to help expose any unintended reuse + * of those values between tests. + */ + protected void clearSetup() { + EXPECTED_STATUS_CODE = 0; + REQUEST_TYPE = ServiceRequestType.NON_EXISTENT; + } + /** + * Initializes setup valuesfor a given test. + */ + protected void testSetup( + int expectedStatusCode, + ServiceRequestType reqType, + String bannerLabel) { + clearSetup(); + EXPECTED_STATUS_CODE = expectedStatusCode; + REQUEST_TYPE = reqType; + // Print a banner identifying the test that will be run. + if (logger.isDebugEnabled()) { + banner(bannerLabel); + } + } - public BaseServiceTest() { - super(); - } + public BaseServiceTest() { + super(); + } - /** - * Returns an error message indicating that the status code returned by a - * specific call to a service does not fall within a set of valid status - * codes for that service. - * - * @param serviceRequestType A type of service request (e.g. CREATE, DELETE). - * - * @param statusCode The invalid status code that was returned in the response, - * from submitting that type of request to the service. - * - * @return An error message. - */ - protected String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) { - return "Status code '" + statusCode + - "' in response is NOT within the expected set: " + - requestType.validStatusCodesAsString(); - } + /** + * Returns an error message indicating that the status code returned by a + * specific call to a service does not fall within a set of valid status + * codes for that service. + * + * @param serviceRequestType A type of service request (e.g. CREATE, DELETE). + * + * @param statusCode The invalid status code that was returned in the response, + * from submitting that type of request to the service. + * + * @return An error message. + */ + protected String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) { + return "Status code '" + statusCode + + "' in response is NOT within the expected set: " + + requestType.validStatusCodesAsString(); + } - /** - * Returns the root URL for a service. - * - * This URL consists of a base URL for all services, followed by - * a path component (or components) for a service. - * - * @return The root URL for a service. - */ - protected String getServiceRootURL() { - return serviceClient.getBaseURL() + getServicePathComponent(); - } + /** + * Returns the root URL for a service. + * + * This URL consists of a base URL for all services, followed by + * a path component (or components) for a service. + * + * @return The root URL for a service. + */ + protected String getServiceRootURL() { + return serviceClient.getBaseURL() + getServicePathComponent(); + } - /** - * Returns the URL of a specific resource managed by a service, and - * designated by an identifier (such as a universally unique ID, or UUID). - * - * @param resourceIdentifier An identifier (such as a UUID) for a resource. - * - * @return The URL of a specific resource managed by a service. - */ - protected String getResourceURL(String resourceIdentifier) { - return getServiceRootURL() + "/" + resourceIdentifier; - } + /** + * Returns the URL of a specific resource managed by a service, and + * designated by an identifier (such as a universally unique ID, or UUID). + * + * @param resourceIdentifier An identifier (such as a UUID) for a resource. + * + * @return The URL of a specific resource managed by a service. + */ + protected String getResourceURL(String resourceIdentifier) { + return getServiceRootURL() + "/" + resourceIdentifier; + } - /** - * Submits an HTTP request to a specified URL, and returns the - * status code of the response. Currently accepts GET and DELETE - * requests. - * - * @param method An HTTP method. - * - * @param url A String representation of a URL. - * - * @return The status code received in the HTTP response. - */ - protected int submitRequest(String method, String url) { - int statusCode = 0; - try{ - TestServiceClient client = new TestServiceClient(); - if(method.equals(javax.ws.rs.HttpMethod.DELETE)){ - DeleteMethod deleteMethod = new DeleteMethod(url); - statusCode = client.getHttpClient().executeMethod(deleteMethod); - }else if(method.equals(javax.ws.rs.HttpMethod.GET)){ - GetMethod getMethod = new GetMethod(url); - statusCode = client.getHttpClient().executeMethod(getMethod); - }else{ - // Do nothing - leave status code at default value. - } - }catch(Exception e){ - logger.error( - "Exception during HTTP " + method + " request to " + - url + ":", e); - } - return statusCode; - } + /** + * Submits an HTTP request to a specified URL, and returns the + * status code of the response. Currently accepts GET and DELETE + * requests. + * + * @param method An HTTP method. + * + * @param url A String representation of a URL. + * + * @return The status code received in the HTTP response. + */ + protected int submitRequest(String method, String url) { + int statusCode = 0; + try { + TestServiceClient client = new TestServiceClient(); + if (method.equals(javax.ws.rs.HttpMethod.DELETE)) { + DeleteMethod deleteMethod = new DeleteMethod(url); + statusCode = client.getHttpClient().executeMethod(deleteMethod); + } else if (method.equals(javax.ws.rs.HttpMethod.GET)) { + GetMethod getMethod = new GetMethod(url); + statusCode = client.getHttpClient().executeMethod(getMethod); + } else { + // Do nothing - leave status code at default value. + } + } catch (Exception e) { + logger.error( + "Exception during HTTP " + method + " request to " + + url + ":", e); + } + return statusCode; + } - /** - * Submits an HTTP request to a specified URL, with the submitted - * entity body, and returns the status code of the response. - * Currently accepts POST and PUT requests. - * - * @param method An HTTP method. - * - * @param url A String representation of a URL. - * - * @param mediaType The media type of the entity body to be submitted. - * - * @param entity The contents of the entity body to be submitted. - * - * @return The status code received in the HTTP response. - */ - protected int submitRequest(String method, String url, String mediaType, - String entityStr) { - int statusCode = 0; - try{ - TestServiceClient client = new TestServiceClient(); - if(method.equals(javax.ws.rs.HttpMethod.POST)){ - StringRequestEntity entityBody = - new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); - PostMethod postMethod = new PostMethod(url); - postMethod.setRequestEntity(entityBody); - statusCode = client.getHttpClient().executeMethod(postMethod); - }else if(method.equals(javax.ws.rs.HttpMethod.PUT)){ - StringRequestEntity entityBody = - new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); - PutMethod putMethod = new PutMethod(url); - putMethod.setRequestEntity(entityBody); - statusCode = client.getHttpClient().executeMethod(putMethod); - }else{ - // Do nothing - leave status code at default value. - } - }catch(Exception e){ - logger.error( - "Exception during HTTP " + method + " request to " + - url + ":", e); - } - return statusCode; - } + /** + * Submits an HTTP request to a specified URL, with the submitted + * entity body, and returns the status code of the response. + * Currently accepts POST and PUT requests. + * + * @param method An HTTP method. + * + * @param url A String representation of a URL. + * + * @param mediaType The media type of the entity body to be submitted. + * + * @param entity The contents of the entity body to be submitted. + * + * @return The status code received in the HTTP response. + */ + protected int submitRequest(String method, String url, String mediaType, + String entityStr) { + int statusCode = 0; + try { + TestServiceClient client = new TestServiceClient(); + if (method.equals(javax.ws.rs.HttpMethod.POST)) { + StringRequestEntity entityBody = + new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); + PostMethod postMethod = new PostMethod(url); + postMethod.setRequestEntity(entityBody); + statusCode = client.getHttpClient().executeMethod(postMethod); + } else if (method.equals(javax.ws.rs.HttpMethod.PUT)) { + StringRequestEntity entityBody = + new StringRequestEntity(mediaType, entityStr, NULL_CHARSET); + PutMethod putMethod = new PutMethod(url); + putMethod.setRequestEntity(entityBody); + statusCode = client.getHttpClient().executeMethod(putMethod); + } else { + // Do nothing - leave status code at default value. + } + } catch (Exception e) { + logger.error( + "Exception during HTTP " + method + " request to " + + url + ":", e); + } + return statusCode; + } - protected String extractId(ClientResponse res) { - MultivaluedMap mvm = res.getMetadata(); - String uri = (String) ((ArrayList) mvm.get("Location")).get(0); - if(logger.isDebugEnabled()){ - logger.debug("extractId:uri=" + uri); - } - String[] segments = uri.split("/"); - String id = segments[segments.length - 1]; - if(logger.isDebugEnabled()){ - logger.debug("id=" + id); - } - return id; - } + static protected String extractId(ClientResponse res) { + MultivaluedMap mvm = res.getMetadata(); + String uri = (String) ((ArrayList) mvm.get("Location")).get(0); + if (logger.isDebugEnabled()) { + logger.debug("extractId:uri=" + uri); + } + String[] segments = uri.split("/"); + String id = segments[segments.length - 1]; + if (logger.isDebugEnabled()) { + logger.debug("id=" + id); + } + return id; + } - protected String createIdentifier() { - long identifier = System.currentTimeMillis(); - return Long.toString(identifier); - } + static protected String createIdentifier() { + long identifier = System.currentTimeMillis(); + return Long.toString(identifier); + } - protected String createNonExistentIdentifier() { - return Long.toString(Long.MAX_VALUE); - } + protected String createNonExistentIdentifier() { + return Long.toString(Long.MAX_VALUE); + } - protected Object extractPart(MultipartInput input, String label, Class clazz) - throws Exception { - Object obj = null; - String partLabel = ""; - List parts = input.getParts(); - if (parts.size() == 0) { - logger.warn("No parts found in multipart body."); - } - if(logger.isDebugEnabled()){ - logger.debug("Parts:"); - for(InputPart part : parts){ - partLabel = part.getHeaders().getFirst("label"); - logger.debug("part = " + partLabel); - } - } - boolean partLabelMatched = false; - for(InputPart part : parts){ - partLabel = part.getHeaders().getFirst("label"); - if(label.equalsIgnoreCase(partLabel)){ - partLabelMatched = true; - if(logger.isDebugEnabled()){ - logger.debug("found part" + partLabel); - } - String partStr = part.getBodyAsString(); - if (partStr == null || partStr.trim().isEmpty()) { - logger.warn("Part '" + label + "' in multipart body is empty."); - } else { - if (logger.isDebugEnabled()){ - logger.debug("extracted part as str=\n" + partStr); - } - obj = part.getBody(clazz, null); - if(logger.isDebugEnabled()){ - logger.debug("extracted part as obj=\n", - objectAsXmlString(obj, clazz)); - } - } - break; - } - } - if (! partLabelMatched) { - logger.warn("Could not find part '" + label + "' in multipart body."); - // In the event that getBodyAsString() or getBody(), above, do *not* - // throw an IOException, but getBody() nonetheless retrieves a null object. - // This *may* be unreachable. - } else if (obj == null) { - logger.warn("Could not extract part '" + label + - "' in multipart body as an object."); - } - return obj; - } + static protected Object extractPart(MultipartInput input, String label, Class clazz) + throws Exception { + Object obj = null; + String partLabel = ""; + List parts = input.getParts(); + if (parts.size() == 0) { + logger.warn("No parts found in multipart body."); + } + if (logger.isDebugEnabled()) { + logger.debug("Parts:"); + for (InputPart part : parts) { + partLabel = part.getHeaders().getFirst("label"); + logger.debug("part = " + partLabel); + } + } + boolean partLabelMatched = false; + for (InputPart part : parts) { + partLabel = part.getHeaders().getFirst("label"); + if (label.equalsIgnoreCase(partLabel)) { + partLabelMatched = true; + if (logger.isDebugEnabled()) { + logger.debug("found part" + partLabel); + } + String partStr = part.getBodyAsString(); + if (partStr == null || partStr.trim().isEmpty()) { + logger.warn("Part '" + label + "' in multipart body is empty."); + } else { + if (logger.isDebugEnabled()) { + logger.debug("extracted part as str=\n" + partStr); + } + obj = part.getBody(clazz, null); + if (logger.isDebugEnabled()) { + logger.debug("extracted part as obj=\n", + objectAsXmlString(obj, clazz)); + } + } + break; + } + } + if (!partLabelMatched) { + logger.warn("Could not find part '" + label + "' in multipart body."); + // In the event that getBodyAsString() or getBody(), above, do *not* + // throw an IOException, but getBody() nonetheless retrieves a null object. + // This *may* be unreachable. + } else if (obj == null) { + logger.warn("Could not extract part '" + label + + "' in multipart body as an object."); + } + return obj; + } - protected Object getPartObject(String partStr, Class clazz) - throws JAXBException { - JAXBContext jc = JAXBContext.newInstance(clazz); - ByteArrayInputStream bais = null; - Object obj = null; - try{ - bais = new ByteArrayInputStream(partStr.getBytes()); - Unmarshaller um = jc.createUnmarshaller(); - obj = um.unmarshal(bais); - }finally{ - if(bais != null){ - try{ - bais.close(); - }catch(Exception e){ - } - } - } - return obj; - } + static protected Object getPartObject(String partStr, Class clazz) + throws JAXBException { + JAXBContext jc = JAXBContext.newInstance(clazz); + ByteArrayInputStream bais = null; + Object obj = null; + try { + bais = new ByteArrayInputStream(partStr.getBytes()); + Unmarshaller um = jc.createUnmarshaller(); + obj = um.unmarshal(bais); + } finally { + if (bais != null) { + try { + bais.close(); + } catch (Exception e) { + } + } + } + return obj; + } - protected String objectAsXmlString(Object o, Class clazz) { - StringWriter sw = new StringWriter(); - try{ - JAXBContext jc = JAXBContext.newInstance(clazz); - Marshaller m = jc.createMarshaller(); - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, - Boolean.TRUE); - m.marshal(o, sw); - }catch(Exception e){ - e.printStackTrace(); - } - return sw.toString(); - } + static protected String objectAsXmlString(Object o, Class clazz) { + StringWriter sw = new StringWriter(); + try { + JAXBContext jc = JAXBContext.newInstance(clazz); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + Boolean.TRUE); + m.marshal(o, sw); + } catch (Exception e) { + e.printStackTrace(); + } + return sw.toString(); + } /** * getObjectFromFile get object of given class from given file (in classpath) @@ -334,7 +333,7 @@ public abstract class BaseServiceTest { * @return * @throws Exception */ - protected Object getObjectFromFile(Class jaxbClass, String fileName) + static protected Object getObjectFromFile(Class jaxbClass, String fileName) throws Exception { JAXBContext context = JAXBContext.newInstance(jaxbClass); @@ -346,7 +345,7 @@ public abstract class BaseServiceTest { return getObjectFromStream(jaxbClass, is); } - protected Document getXmlDocument(String fileName) throws Exception { + static protected Document getXmlDocument(String fileName) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); File f = new File(fileName); if (!f.exists()) { @@ -356,12 +355,11 @@ public abstract class BaseServiceTest { return factory.newDocumentBuilder().parse(f); } - protected String getXmlDocumentAsString(String fileName) throws Exception { + static protected String getXmlDocumentAsString(String fileName) throws Exception { byte[] b = FileUtils.readFileToByteArray(new File(fileName)); return new String(b); } - /** * getObjectFromStream get object of given class from given inputstream * @param jaxbClass @@ -369,29 +367,29 @@ public abstract class BaseServiceTest { * @return * @throws Exception */ - protected Object getObjectFromStream(Class jaxbClass, InputStream is) throws Exception { + static protected Object getObjectFromStream(Class jaxbClass, InputStream is) throws Exception { JAXBContext context = JAXBContext.newInstance(jaxbClass); Unmarshaller unmarshaller = context.createUnmarshaller(); //note: setting schema to null will turn validator off unmarshaller.setSchema(null); return jaxbClass.cast(unmarshaller.unmarshal(is)); } - protected String mapAsString(MultivaluedMap map) { - StringBuffer sb = new StringBuffer(); - for(Object entry : map.entrySet()){ - MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; - sb.append(" name=" + mentry.getKey()); - sb.append(" value=" + mentry.getValue() + "\n"); - } - return sb.toString(); - } - protected void banner(String label) { - if(logger.isDebugEnabled()){ - logger.debug("==================================================="); - logger.debug(" Test = " + label); - logger.debug("==================================================="); - } - } + protected String mapAsString(MultivaluedMap map) { + StringBuffer sb = new StringBuffer(); + for (Object entry : map.entrySet()) { + MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; + sb.append(" name=" + mentry.getKey()); + sb.append(" value=" + mentry.getValue() + "\n"); + } + return sb.toString(); + } -} \ No newline at end of file + protected void banner(String label) { + if (logger.isDebugEnabled()) { + logger.debug("==================================================="); + logger.debug(" Test = " + label); + logger.debug("==================================================="); + } + } +} diff --git a/services/common/pom.xml b/services/common/pom.xml index b56021649..17befac66 100644 --- a/services/common/pom.xml +++ b/services/common/pom.xml @@ -31,7 +31,13 @@ org.collectionspace.services.authentication.service ${project.version} provided - + + + org.collectionspace.services + org.collectionspace.services.authorization.jaxb + ${project.version} + provided + org.collectionspace.services org.collectionspace.services.authorization.service @@ -104,7 +110,7 @@ javax.persistence persistence-api - + com.sun.xml.bind jaxb-impl diff --git a/services/common/src/main/config/services/tenant-bindings.xml b/services/common/src/main/config/services/tenant-bindings.xml index cdb85fb61..a2e82ac47 100644 --- a/services/common/src/main/config/services/tenant-bindings.xml +++ b/services/common/src/main/config/services/tenant-bindings.xml @@ -578,7 +578,7 @@ - + org.collectionspace.services.authorization.storage.PermissionDocumentHandler @@ -611,6 +611,39 @@ + + + + org.collectionspace.services.authorization.storage.PermissionRoleDocumentHandler + + + + + + + + + + + + + + + + + + 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 f865119a7..0203b73e1 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 @@ -103,6 +103,10 @@ public class JpaStorageClientImpl implements StorageClient { DocumentHandler handler) throws BadRequestException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.create: ctx is missing"); + } if (handler == null) { throw new IllegalArgumentException( "JpaStorageClient.create: handler is missing"); @@ -159,6 +163,10 @@ public class JpaStorageClientImpl implements StorageClient { @Override public void get(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.get: ctx is missing"); + } if (handler == null) { throw new IllegalArgumentException( "JpaStorageClient.get: handler is missing"); @@ -238,6 +246,10 @@ public class JpaStorageClientImpl implements StorageClient { @Override public void getFiltered(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.getFiltered: ctx is missing"); + } if (handler == null) { throw new IllegalArgumentException( "JpaStorageClient.getFiltered: handler is missing"); @@ -299,6 +311,10 @@ public class JpaStorageClientImpl implements StorageClient { public void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.update: ctx is missing"); + } if (handler == null) { throw new IllegalArgumentException( "JpaStorageClient.update: handler is missing"); @@ -357,6 +373,11 @@ public class JpaStorageClientImpl implements StorageClient { throws DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.delete: ctx is missing"); + } + if (logger.isDebugEnabled()) { logger.debug("deleting entity with id=" + id); } @@ -411,6 +432,10 @@ public class JpaStorageClientImpl implements StorageClient { throws DocumentNotFoundException, DocumentException { + if (ctx == null) { + throw new IllegalArgumentException( + "JpaStorageClient.deleteWhere: ctx is missing"); + } if (logger.isDebugEnabled()) { logger.debug("deleting entity with id=" + id); @@ -427,7 +452,7 @@ public class JpaStorageClientImpl implements StorageClient { em = emf.createEntityManager(); Query q = em.createQuery(deleteStr.toString()); q.setParameter("csid", id); - //TODO: add tenant id + int rcount = 0; em.getTransaction().begin(); rcount = q.executeUpdate(); -- 2.47.3