]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-1304 create permission
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Wed, 7 Apr 2010 18:23:06 +0000 (18:23 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Wed, 7 Apr 2010 18:23:06 +0000 (18:23 +0000)
CSPACE-1305 delete permission
CPSACE-1306 get permission
CSPACE-1307 update permission
CSPACE-1309 search permission with resource name only
CSPACE-1311 list permissions

added new service authorization/permissions first checkin. permissions are yet to be plugged in with spring acls.
minor copyright javadoc changes in role and account classes
jpastorageclient now supports delete (with parent deleting children) and deletewhere (a shallow delete with where clause)

test: mvn test at the service level, added PermissionServiceTest in authorization-mgt/client

M    services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
M    services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml
_M   services/authorization-mgt/service
A    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java
M    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java
M    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java
M    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java
A    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java
A    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java
A    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java
A    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java
M    services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java
M    services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java
A    services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java
A    services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java
A    services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java
M    services/authorization/jaxb/src/main/resources/roles.xsd
A    services/authorization/jaxb/src/main/resources/permissions_list.xsd
M    services/authorization/jaxb/src/main/resources/permissions.xsd
M    services/authorization/jaxb/src/main/resources/roles_list.xsd
M    services/authorization/pstore/src/main/resources/db/mysql/authorization.sql
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/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java
M    services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java
D    services/account/client/src/test/java/org/collectionspace/services/client

24 files changed:
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java
services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java [new file with mode: 0644]
services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java [new file with mode: 0644]
services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java [new file with mode: 0644]
services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java [new file with mode: 0644]
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java [new file with mode: 0644]
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java [new file with mode: 0644]
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java [new file with mode: 0644]
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java [new file with mode: 0644]
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java
services/authorization/jaxb/src/main/resources/permissions.xsd
services/authorization/jaxb/src/main/resources/permissions_list.xsd [new file with mode: 0644]
services/authorization/jaxb/src/main/resources/roles.xsd
services/authorization/jaxb/src/main/resources/roles_list.xsd
services/authorization/pstore/src/main/resources/db/mysql/authorization.sql
services/common/src/main/config/services/tenant-bindings.xml
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java

index baa7c5f627c535075b8103c08941334fc6f18eaa..10c7b755446b6fe740696c31390a2e91d2dd209d 100644 (file)
@@ -41,6 +41,7 @@ import org.collectionspace.services.person.PersonAuthorityResource;
 import javax.ws.rs.core.Application;
 import java.util.HashSet;
 import java.util.Set;
+import org.collectionspace.services.authorization.PermissionResource;
 import org.collectionspace.services.authorization.RoleResource;
 import org.collectionspace.services.common.security.SecurityInterceptor;
 
@@ -61,6 +62,7 @@ public class CollectionSpaceJaxRsApplication extends Application {
         singletons.add(new SecurityInterceptor());
         singletons.add(new AccountResource());
         singletons.add(new RoleResource());
+        singletons.add(new PermissionResource());
         singletons.add(new CollectionObjectResource());
         singletons.add(new IDResource());
         singletons.add(new IntakeResource());
index dc4ee66434cc4f0322afe8721d3466b7fbbccd54..120511413f69f8317f7d81d84625c979146ef9a5 100644 (file)
@@ -9,6 +9,9 @@
         <class>org.collectionspace.services.account.AccountTenant</class>
         <class>org.collectionspace.services.account.Status</class>
         <class>org.collectionspace.services.authentication.User</class>
+        <class>org.collectionspace.services.authorization.Permission</class>
+        <class>org.collectionspace.services.authorization.PermissionAction</class>
+        <class>org.collectionspace.services.authorization.PermissionsList</class>
         <class>org.collectionspace.services.authorization.Role</class>
         <class>org.collectionspace.services.authorization.RolesList</class>
         <class>org.collectionspace.services.authorization.UserRole</class>
index ad6c95353c702684e6598d34c93f234444c25642..21d04f781e3dcb5a66d54b928b43acffb87468a0 100644 (file)
  *  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.
- *//**
- *  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.
- */
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
  */
 package org.collectionspace.services.account.storage;
 
index db960b1a489cb6219332b8dd20d7e73fc9239b8d..be4c7482da8cfa53247506a605a9887d82de4f51 100644 (file)
@@ -198,12 +198,6 @@ public class AccountStorageClient extends JpaStorageClientImpl {
             //query an delete is inefficient
             AccountsCommon accountFound = getAccount(em, id);
 
-            StringBuilder accDelStr = new StringBuilder("DELETE FROM ");
-            accDelStr.append(getEntityName(ctx));
-            accDelStr.append(" WHERE csid = :csid");
-            //TODO: add tenant id
-            Query accDel = em.createQuery(accDelStr.toString());
-            accDel.setParameter("csid", id);
             //TODO: add tenant id
 
             //if userid gives any indication about the id provider, it should
@@ -219,12 +213,7 @@ public class AccountStorageClient extends JpaStorageClientImpl {
                 usrDel.setParameter("username", accountFound.getUserId());
             }
             em.getTransaction().begin();
-//            int accDelCount = accDel.executeUpdate();
-//            if (accDelCount != 1) {
-//                if (em != null && em.getTransaction().isActive()) {
-//                    em.getTransaction().rollback();
-//                }
-//            }
+
             if (userLocal != null) {
                 int usrDelCount = usrDel.executeUpdate();
                 if (usrDelCount != 1) {
diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java
new file mode 100644 (file)
index 0000000..bea5c33
--- /dev/null
@@ -0,0 +1,132 @@
+/**    
+ * PermissionClient.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.Permission;
+import org.collectionspace.services.authorization.PermissionsList;
+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 PermissionClient.
+
+ * @version $Revision:$
+ */
+public class PermissionClient extends AbstractServiceClientImpl {
+
+    /**
+     *
+     */
+    private PermissionProxy permissionProxy;
+
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.client.AbstractServiceClientImpl#getServicePathComponent()
+     */
+    public String getServicePathComponent() {
+        return "authorization/permissions";
+    }
+
+    /**
+     *
+     * Default constructor for PermissionClient class.
+     *
+     */
+    public PermissionClient() {
+        ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
+        RegisterBuiltin.register(factory);
+        setProxy();
+    }
+
+    /**
+     * allow to reset proxy as per security needs
+     */
+    public void setProxy() {
+        if (useAuth()) {
+            permissionProxy = ProxyFactory.create(PermissionProxy.class,
+                    getBaseURL(), getHttpClient());
+        } else {
+            permissionProxy = ProxyFactory.create(PermissionProxy.class,
+                    getBaseURL());
+        }
+    }
+
+    /**
+     * @return
+     * @see org.collectionspace.hello.client.PermissionProxy#readList()
+     */
+    public ClientResponse<PermissionsList> readList() {
+        return permissionProxy.readList();
+
+    }
+
+    public ClientResponse<PermissionsList> readSearchList(String resourceName) {
+        return permissionProxy.readSearchList(resourceName);
+
+    }
+
+    /**
+     * @param csid
+     * @return
+     * @see org.collectionspace.hello.client.PermissionProxy#getAccount(java.lang.String)
+     */
+    public ClientResponse<Permission> read(String csid) {
+        return permissionProxy.read(csid);
+    }
+
+    /**
+     * @param permission
+     * @return
+     * @see org.collectionspace.hello.client.PermissionProxy#create(org.collectionspace.services.permission.Permission)
+     */
+    public ClientResponse<Response> create(Permission permission) {
+        return permissionProxy.create(permission);
+    }
+
+    /**
+     * @param csid
+     * @param permission
+     * @return
+     * @see org.collectionspace.hello.client.PermissionProxy#updateAccount(java.lang.Long, org.collectionspace.services.permission.Permission)
+     */
+    public ClientResponse<Permission> update(String csid, Permission permission) {
+        return permissionProxy.update(csid, permission);
+    }
+
+    /**
+     * @param csid
+     * @return
+     * @see org.collectionspace.hello.client.PermissionProxy#deleteAccount(java.lang.Long)
+     */
+    public ClientResponse<Response> delete(String csid) {
+        return permissionProxy.delete(csid);
+    }
+}
diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java
new file mode 100644 (file)
index 0000000..f096f82
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * PermissionProxy.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.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+
+
+import org.collectionspace.services.authorization.Permission;
+import org.collectionspace.services.authorization.PermissionsList;
+import org.jboss.resteasy.client.ClientResponse;
+
+/**
+ * @version $Revision:$
+ */
+@Path("/authorization/permissions")
+@Produces({"application/xml"})
+@Consumes({"application/xml"})
+public interface PermissionProxy {
+
+    @GET
+    @Produces({"application/xml"})
+    ClientResponse<PermissionsList> readList();
+
+    @GET
+
+    ClientResponse<PermissionsList> readSearchList(@QueryParam("res") String resourceName);
+
+    //(C)reate
+    @POST
+    ClientResponse<Response> create(Permission permission);
+
+    //(R)ead
+    @GET
+    @Path("/{csid}")
+    ClientResponse<Permission> read(@PathParam("csid") String csid);
+
+    //(U)pdate
+    @PUT
+    @Path("/{csid}")
+    ClientResponse<Permission> update(@PathParam("csid") String csid, Permission permission);
+
+    //(D)elete
+    @DELETE
+    @Path("/{csid}")
+    ClientResponse<Response> delete(@PathParam("csid") String csid);
+}
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
new file mode 100644 (file)
index 0000000..3a15e30
--- /dev/null
@@ -0,0 +1,604 @@
+/**
+ * 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 permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.authorization.client.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.collectionspace.services.authorization.ActionType;
+import org.collectionspace.services.authorization.EffectType;
+
+import org.collectionspace.services.client.PermissionClient;
+import org.collectionspace.services.authorization.Permission;
+import org.collectionspace.services.authorization.PermissionAction;
+import org.collectionspace.services.authorization.PermissionsList;
+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;
+
+/**
+ * PermissionServiceTest, carries out tests against a
+ * deployed and running Permission Service.
+ * 
+ * $LastChangedRevision: 917 $
+ * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $
+ */
+public class PermissionServiceTest extends AbstractServiceTestImpl {
+
+    private final Logger logger =
+            LoggerFactory.getLogger(PermissionServiceTest.class);
+    // Instance variables specific to this test.
+    private PermissionClient client = new PermissionClient();
+    private String knownResourceId = null;
+    private List<String> allResourceIdsCreated = new ArrayList();
+    boolean addTenant = true;
+    /*
+     * This method is called only by the parent class, AbstractServiceTestImpl
+     */
+
+    @Override
+    protected String getServicePathComponent() {
+        return client.getServicePathComponent();
+    }
+
+    // ---------------------------------------------------------------
+    // 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.
+        List<PermissionAction> actions = getDefaultActions();
+        Permission permission = createPermissionInstance("accounts",
+                "default permissions for account",
+                actions,
+                EffectType.PERMIT,
+                true,
+                true,
+                true);
+        ClientResponse<Response> res = client.create(permission);
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        //
+        // Specifically:
+        // Does it fall within the set of valid status codes?
+        // Does it exactly match the expected status code?
+        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.
+        knownResourceId = extractId(res);
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": knownResourceId=" + knownResourceId);
+        }
+    }
+
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"create"})
+    public void createWithoutResourceName(String testName) throws Exception {
+
+        setupCreate(testName);
+
+        // Submit the request to the service and store the response.
+        List<PermissionAction> actions = getDefaultActions();
+        Permission permission = createPermissionInstance(null,
+                "default permissions for account",
+                actions,
+                EffectType.PERMIT,
+                false,
+                true,
+                true);
+        ClientResponse<Response> res = client.create(permission);
+        int statusCode = res.getStatus();
+        // Does it exactly match the expected status code?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
+    }
+
+    //to not cause uniqueness violation for permission, 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.
+        List<PermissionAction> actions = getDefaultActions();
+        Permission permission1 = createPermissionInstance("collectionobjects",
+                "default permissions for collectionobjects",
+                actions,
+                EffectType.PERMIT,
+                true,
+                true,
+                true);
+        ClientResponse<Response> res = client.create(permission1);
+        int statusCode = res.getStatus();
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        allResourceIdsCreated.add(extractId(res));
+
+        Permission permission2 = createPermissionInstance("intakes",
+                "default permissions for intakes",
+                actions,
+                EffectType.PERMIT,
+                true,
+                true,
+                true);
+        res = client.create(permission2);
+        statusCode = res.getStatus();
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        allResourceIdsCreated.add(extractId(res));
+
+        Permission permission3 = createPermissionInstance("ids",
+                "default permissions for id service",
+                actions,
+                EffectType.PERMIT,
+                true,
+                true,
+                true);
+        res = client.create(permission3);
+        statusCode = res.getStatus();
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        allResourceIdsCreated.add(extractId(res));
+    }
+
+    // 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<Permission> res = client.read(knownResourceId);
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+        Permission output = (Permission) res.getEntity();
+        Assert.assertNotNull(output);
+    }
+
+    // Failure outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"read"})
+    public void readNonExistent(String testName) throws Exception {
+
+        // Perform setup.
+        setupReadNonExistent(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<Permission> res = client.read(NON_EXISTENT_ID);
+        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 {
+
+        // Perform setup.
+        setupReadList(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<PermissionsList> res = client.readList();
+        PermissionsList list = res.getEntity();
+        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);
+
+        // Optionally output additional data about list members for debugging.
+        boolean iterateThroughList = true;
+        if (iterateThroughList && logger.isDebugEnabled()) {
+            printList(testName, list);
+        }
+    }
+
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"createList", "read"})
+    public void searchResourceName(String testName) throws Exception {
+
+        // Perform setup.
+        setupReadList(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<PermissionsList> res = client.readSearchList("intake");
+        PermissionsList list = res.getEntity();
+        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);
+        int EXPECTED_ITEMS = 1;
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": received = " + list.getPermissions().size()
+                    + " expected=" + EXPECTED_ITEMS);
+        }
+        Assert.assertEquals(EXPECTED_ITEMS, list.getPermissions().size());
+        // Optionally output additional data about list members for debugging.
+        boolean iterateThroughList = true;
+        if (iterateThroughList && logger.isDebugEnabled()) {
+            printList(testName, list);
+        }
+    }
+
+    // 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 {
+
+        // Perform setup.
+        setupUpdate(testName);
+
+
+        ClientResponse<Permission> res =
+                client.read(knownResourceId);
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": read status = " + res.getStatus());
+        }
+        Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("got object to update with ID: " + knownResourceId);
+        }
+        Permission toUpdatePermission =
+                (Permission) res.getEntity();
+        Assert.assertNotNull(toUpdatePermission);
+
+        // Update the content of this resource.
+        toUpdatePermission.setResourceName("updated-" + toUpdatePermission.getResourceName());
+        if (logger.isDebugEnabled()) {
+            logger.debug("updated object");
+            logger.debug(objectAsXmlString(toUpdatePermission,
+                    Permission.class));
+        }
+
+        // Submit the request to the service and store the response.
+        res = client.update(knownResourceId, toUpdatePermission);
+        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);
+
+
+        Permission updatedPermission = (Permission) res.getEntity();
+        Assert.assertNotNull(updatedPermission);
+
+        Assert.assertEquals(updatedPermission.getResourceName(),
+                toUpdatePermission.getResourceName(),
+                "Data in updated object did not match submitted data.");
+    }
+
+    // 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 {
+
+        // Perform setup.
+        setupUpdateNonExistent(testName);
+
+        // Submit the request to the service and store the response.
+        //
+        // Note: The ID used in this 'create' call may be arbitrary.
+        // The only relevant ID may be the one used in updatePermission(), below.
+        List<PermissionAction> actions = getDefaultActions();
+        Permission permission = createPermissionInstance("intakes",
+                "default permissions for intakes",
+                actions,
+                EffectType.PERMIT,
+                true,
+                true,
+                true);
+        ClientResponse<Permission> res =
+                client.update(NON_EXISTENT_ID, permission);
+        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 : DELETE tests
+    // ---------------------------------------------------------------
+    // Success outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"update"})
+    public void delete(String testName) throws Exception {
+
+        // Perform setup.
+        setupDelete(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<Response> res = client.delete(knownResourceId);
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": 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,
+    dependsOnMethods = {"delete"})
+    public void deleteNonExistent(String testName) throws Exception {
+
+        // Perform setup.
+        setupDeleteNonExistent(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
+        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", "read"})
+    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(knownResourceId);
+        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 permission instance
+     * @param resourceName
+     * @param description
+     * @param actionList list of actions for this permission
+     * @param effect effect of the permission
+     * @param useResourceName
+     * @param useAction
+     * @param useEffect
+     * @return
+     */
+    private Permission createPermissionInstance(String resourceName,
+            String description,
+            List<PermissionAction> actionList,
+            EffectType effect,
+            boolean useResourceName,
+            boolean useAction,
+            boolean useEffect) {
+
+        Permission permission = new Permission();
+        if (useResourceName) {
+            permission.setResourceName(resourceName);
+        }
+        if (useAction) {
+            permission.setActions(actionList);
+        }
+        if (useEffect) {
+            permission.setEffect(effect);
+        }
+
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("to be created, permission common");
+            logger.debug(objectAsXmlString(permission, Permission.class));
+        }
+        return permission;
+    }
+
+    private List<PermissionAction> getDefaultActions() {
+        List<PermissionAction> actions = new ArrayList<PermissionAction>();
+        PermissionAction create = new PermissionAction();
+        create.setName(ActionType.CREATE);
+        actions.add(create);
+
+        PermissionAction read = new PermissionAction();
+        read.setName(ActionType.READ);
+        actions.add(read);
+
+        PermissionAction update = new PermissionAction();
+        update.setName(ActionType.UPDATE);
+        actions.add(update);
+
+        PermissionAction delete = new PermissionAction();
+        delete.setName(ActionType.DELETE);
+        actions.add(delete);
+
+        PermissionAction search = new PermissionAction();
+        search.setName(ActionType.SEARCH);
+        actions.add(search);
+
+        return actions;
+    }
+
+    @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<Response> res = client.delete(resourceId);
+            int statusCode = res.getStatus();
+            Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+            Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        }
+    }
+
+    private int printList(String testName, PermissionsList list) {
+
+        int i = 0;
+
+        for (Permission permission : list.getPermissions()) {
+            logger.debug(testName + " permission csid=" + permission.getCsid()
+                    + " name=" + permission.getResourceName()
+                    + " desc=" + permission.getDescription());
+            i++;
+        }
+        return i;
+    }
+}
index cda37b7b678d7a1efb0fa77ae2f448ccb4537a6a..59e085de749a1a4796097ca70d2be74c64a72d24 100644 (file)
@@ -310,8 +310,8 @@ public class RoleServiceTest extends AbstractServiceTestImpl {
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
         int EXPECTED_ITEMS = 1;
         if (logger.isDebugEnabled()) {
-            logger.debug(testName + ": received = " + list.getRoles().size() +
-                    " expected=" + EXPECTED_ITEMS);
+            logger.debug(testName + ": received = " + list.getRoles().size()
+                    " expected=" + EXPECTED_ITEMS);
         }
         Assert.assertEquals(EXPECTED_ITEMS, list.getRoles().size());
         // Optionally output additional data about list members for debugging.
@@ -428,7 +428,7 @@ public class RoleServiceTest extends AbstractServiceTestImpl {
     // Success outcomes
     @Override
     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
-    dependsOnMethods = {"testSubmitRequest"})
+    dependsOnMethods = {"update"})
     public void delete(String testName) throws Exception {
 
         // Perform setup.
@@ -517,7 +517,7 @@ public class RoleServiceTest extends AbstractServiceTestImpl {
         if (useRoleName) {
             role.setRoleName(roleName);
         }
-
+        role.setDescription(description);
         if (logger.isDebugEnabled()) {
             logger.debug("to be created, role common");
             logger.debug(objectAsXmlString(role, Role.class));
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
new file mode 100644 (file)
index 0000000..37a0f0a
--- /dev/null
@@ -0,0 +1,302 @@
+/**
+ *  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.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+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.common.AbstractCollectionSpaceResourceImpl;
+import org.collectionspace.services.common.context.RemoteServiceContextImpl;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
+import org.collectionspace.services.common.document.DocumentHandler;
+import org.collectionspace.services.common.security.UnauthorizedException;
+import org.collectionspace.services.common.storage.StorageClient;
+import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl;
+import org.jboss.resteasy.util.HttpResponseCodes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/authorization/permissions")
+@Consumes("application/xml")
+@Produces("application/xml")
+public class PermissionResource
+        extends AbstractCollectionSpaceResourceImpl {
+
+    final private String serviceName = "authorization/permissions";
+    final Logger logger = LoggerFactory.getLogger(PermissionResource.class);
+    final StorageClient storageClient = new JpaStorageClientImpl(Permission.class);
+
+    @Override
+    protected String getVersionString() {
+        /** The last change revision. */
+        final String lastChangeRevision = "$LastChangedRevision: 1165 $";
+        return lastChangeRevision;
+    }
+
+    @Override
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    private <T> ServiceContext createServiceContext(T obj) throws Exception {
+        ServiceContext ctx = new RemoteServiceContextImpl<T, T>(getServiceName());
+        ctx.setInput(obj);
+        ctx.setDocumentType(Permission.class.getPackage().getName()); //persistence unit
+        ctx.setProperty("entity-name", Permission.class.getName());
+        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;
+    }
+
+    @POST
+    public Response createPermission(Permission input) {
+        try {
+            ServiceContext ctx = createServiceContext(input);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            String csid = getStorageClient(ctx).create(ctx, handler);
+            UriBuilder path = UriBuilder.fromResource(PermissionResource.class);
+            path.path("" + csid);
+            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 createPermission", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                    "Create failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+    }
+
+    @GET
+    @Path("{csid}")
+    public Permission getPermission(
+            @PathParam("csid") String csid) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("getPermission with csid=" + csid);
+        }
+        if (csid == null || "".equals(csid)) {
+            logger.error("getPermission: missing csid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "get failed on Permission csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        Permission result = null;
+        try {
+            ServiceContext ctx = createServiceContext((Permission) null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getStorageClient(ctx).get(ctx, csid, handler);
+            result = (Permission) ctx.getOutput();
+        } 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("getPermission", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Get failed on Permission csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("getPermission", 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 Permission CSID:" + csid + ": was not found.").type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return result;
+    }
+
+    @GET
+    @Produces("application/xml")
+    public PermissionsList getPermissionList(
+            @Context UriInfo ui) {
+        PermissionsList permissionList = new PermissionsList();
+        try {
+            ServiceContext ctx = createServiceContext((PermissionsList) null);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
+            DocumentFilter myFilter = handler.createDocumentFilter(ctx);
+            myFilter.setPagination(queryParams);
+            myFilter.setQueryParams(queryParams);
+            handler.setDocumentFilter(myFilter);
+            getStorageClient(ctx).getFiltered(ctx, handler);
+            permissionList = (PermissionsList) handler.getCommonPartList();
+        } catch (UnauthorizedException ue) {
+            Response response = Response.status(
+                    Response.Status.UNAUTHORIZED).entity("Index failed reason "
+                    + ue.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception in getPermissionsList", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                    "Index failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return permissionList;
+    }
+
+    @PUT
+    @Path("{csid}")
+    public Permission updatePermission(
+            @PathParam("csid") String csid,
+            Permission theUpdate) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("updatePermission with csid=" + csid);
+        }
+        if (csid == null || "".equals(csid)) {
+            logger.error("updatePermission: missing csid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "update failed on Permission csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        Permission result = null;
+        try {
+            ServiceContext ctx = createServiceContext(theUpdate);
+            DocumentHandler handler = createDocumentHandler(ctx);
+            getStorageClient(ctx).update(ctx, csid, handler);
+            result = (Permission) ctx.getOutput();
+        } catch (BadRequestException bre) {
+            Response response = Response.status(
+                    Response.Status.BAD_REQUEST).entity("Update failed reason "
+                    + bre.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (UnauthorizedException ue) {
+            Response response = Response.status(
+                    Response.Status.UNAUTHORIZED).entity("Update failed reason "
+                    + ue.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (DocumentNotFoundException dnfe) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("caugth exception in updatePermission", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Update failed on Permission csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (Exception e) {
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                    "Update failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return result;
+    }
+
+    @DELETE
+    @Path("{csid}")
+    public Response deletePermission(@PathParam("csid") String csid) {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("deletePermission with csid=" + csid);
+        }
+        if (csid == null || "".equals(csid)) {
+            logger.error("deletePermission: missing csid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "delete failed on Permission csid=" + csid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        try {
+            ServiceContext ctx = createServiceContext((Permission) null);
+            getStorageClient(ctx).delete(ctx, csid);
+            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 deletePermission", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Delete failed on Permission csid=" + csid).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);
+        }
+
+    }
+}
index 67edf0acbc0cc4e6438274c772fa1fb8f18abf8e..d36d497f5581487951a5440e4db4457583b5f04d 100644 (file)
@@ -266,7 +266,7 @@ public class RoleResource
         }
         try {
             ServiceContext ctx = createServiceContext((Role) null);
-            getStorageClient(ctx).delete(ctx, csid);
+            ((JpaStorageClientImpl)getStorageClient(ctx)).deleteWhere(ctx, csid);
             return Response.status(HttpResponseCodes.SC_OK).build();
         } catch (UnauthorizedException ue) {
             Response response = Response.status(
diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java
new file mode 100644 (file)
index 0000000..cc613fc
--- /dev/null
@@ -0,0 +1,161 @@
+/**
+ *  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.List;
+import java.util.UUID;
+
+import org.collectionspace.services.authorization.Permission;
+import org.collectionspace.services.authorization.PermissionsList;
+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 Permission
+ * @author 
+ */
+public class PermissionDocumentHandler
+        extends AbstractDocumentHandlerImpl<Permission, PermissionsList, Permission, List> {
+
+    private final Logger logger = LoggerFactory.getLogger(PermissionDocumentHandler.class);
+    private Permission permission;
+    private PermissionsList permissionsList;
+
+    @Override
+    public void handleCreate(DocumentWrapper<Permission> wrapDoc) throws Exception {
+        String id = UUID.randomUUID().toString();
+        Permission permission = wrapDoc.getWrappedObject();
+        permission.setCsid(id);
+        //FIXME: if admin updating the permission is a CS admin rather than
+        //the tenant admin, tenant id should be retrieved from the request
+        permission.setTenantId(getServiceContext().getTenantId());
+    }
+
+    @Override
+    public void handleUpdate(DocumentWrapper<Permission> wrapDoc) throws Exception {
+        Permission permission = wrapDoc.getWrappedObject();
+        //FIXME: if admin updating the permission is a CS admin rather than
+        //the tenant admin, tenant id should be retrieved from the request
+        permission.setTenantId(getServiceContext().getTenantId());
+    }
+
+    @Override
+    public void completeUpdate(DocumentWrapper<Permission> wrapDoc) throws Exception {
+        Permission upAcc = wrapDoc.getWrappedObject();
+        getServiceContext().setOutput(permission);
+        sanitize(upAcc);
+    }
+
+    @Override
+    public void handleGet(DocumentWrapper<Permission> wrapDoc) throws Exception {
+        setCommonPart(extractCommonPart(wrapDoc));
+        sanitize(getCommonPart());
+        getServiceContext().setOutput(permission);
+    }
+
+    @Override
+    public void handleGetAll(DocumentWrapper<List> wrapDoc) throws Exception {
+        PermissionsList permissionsList = extractCommonPartList(wrapDoc);
+        setCommonPartList(permissionsList);
+        getServiceContext().setOutput(getCommonPartList());
+    }
+
+    @Override
+    public Permission extractCommonPart(
+            DocumentWrapper<Permission> wrapDoc)
+            throws Exception {
+        return wrapDoc.getWrappedObject();
+    }
+
+    @Override
+    public void fillCommonPart(Permission obj, DocumentWrapper<Permission> wrapDoc)
+            throws Exception {
+        throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler");
+    }
+
+    @Override
+    public PermissionsList extractCommonPartList(
+            DocumentWrapper<List> wrapDoc)
+            throws Exception {
+
+        PermissionsList permissionsList = new PermissionsList();
+        List<Permission> list = new ArrayList<Permission>();
+        permissionsList.setPermissions(list);
+        for (Object obj : wrapDoc.getWrappedObject()) {
+            Permission permission = (Permission) obj;
+            sanitize(permission);
+            list.add(permission);
+        }
+        return permissionsList;
+    }
+
+    @Override
+    public Permission getCommonPart() {
+        return permission;
+    }
+
+    @Override
+    public void setCommonPart(Permission permission) {
+        this.permission = permission;
+    }
+
+    @Override
+    public PermissionsList getCommonPartList() {
+        return permissionsList;
+    }
+
+    @Override
+    public void setCommonPartList(PermissionsList permissionsList) {
+        this.permissionsList = permissionsList;
+    }
+
+    @Override
+    public String getQProperty(
+            String prop) {
+        return null;
+    }
+
+    @Override
+    public DocumentFilter createDocumentFilter(ServiceContext ctx) {
+        DocumentFilter filter = new PermissionJpaFilter();
+        filter.setPageSize(
+                ctx.getServiceBindingPropertyValue(
+                DocumentFilter.PAGE_SIZE_DEFAULT_PROPERTY));
+        return filter;
+    }
+
+    /**
+     * sanitize removes data not needed to be sent to the consumer
+     * @param permission
+     */
+    private void sanitize(Permission permission) {
+        permission.setTenantId(null);
+    }
+}
diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java
new file mode 100644 (file)
index 0000000..e5cae5b
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ *  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.List;
+import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * PermissionJpaFilter is to build where clause for role queries
+ * @author 
+ */
+public class PermissionJpaFilter extends JpaDocumentFilter {
+
+    private final Logger logger = LoggerFactory.getLogger(PermissionJpaFilter.class);
+
+    @Override
+    public List<ParamBinding> buildWhereForSearch(StringBuilder queryStrBldr) {
+
+        List<ParamBinding> paramList = new ArrayList<ParamBinding>();
+        boolean hasWhere = false;
+        //TODO: add tenant id
+
+        String resName = null;
+        List<String> rn = getQueryParam(PermissionStorageConstants.Q_RESOURCE_NAME);
+        if (null != rn) {
+            resName = rn.get(0);
+        }
+        if (null != resName && !resName.isEmpty()) {
+            hasWhere = true;
+            queryStrBldr.append(" WHERE");
+            queryStrBldr.append(" UPPER(a." + PermissionStorageConstants.RESOURCE_NAME + ")");
+            queryStrBldr.append(" LIKE");
+            queryStrBldr.append(" :" + PermissionStorageConstants.Q_RESOURCE_NAME);
+            paramList.add(new ParamBinding(PermissionStorageConstants.Q_RESOURCE_NAME, "%"
+                    + resName.toUpperCase() + "%"));
+        }
+
+        if (logger.isDebugEnabled()) {
+            String query = queryStrBldr.toString();
+            logger.debug("query=" + query);
+        }
+
+        return paramList;
+    }
+
+    @Override
+    public List<ParamBinding> buildWhere(StringBuilder queryStrBldr) {
+        return new ArrayList<ParamBinding>();
+    }
+}
diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java
new file mode 100644 (file)
index 0000000..08f7a01
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ *  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;
+
+/**
+ * PermissionStorageConstants declares query params, etc.
+ * @author
+ */
+public class PermissionStorageConstants {
+
+    final public static String Q_RESOURCE_NAME = "res";
+
+    final public static String RESOURCE_NAME = "resourceName";
+
+}
diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java
new file mode 100644 (file)
index 0000000..05980eb
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ *  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.Permission;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentHandler.Action;
+import org.collectionspace.services.common.document.InvalidDocumentException;
+import org.collectionspace.services.common.document.ValidatorHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * PermissionValidatorHandler executes validation rules for permission
+ * @author 
+ */
+public class PermissionValidatorHandler implements ValidatorHandler {
+
+    final Logger logger = LoggerFactory.getLogger(PermissionValidatorHandler.class);
+
+    @Override
+    public void validate(Action action, ServiceContext ctx)
+            throws InvalidDocumentException {
+        if (logger.isDebugEnabled()) {
+            logger.debug("validate() action=" + action.name());
+        }
+        try {
+            Permission permission = (Permission) ctx.getInput();
+            StringBuilder msgBldr = new StringBuilder("validate() ");
+            boolean invalid = false;
+
+            if (action.equals(Action.CREATE)) {
+
+                //create specific validation here
+                if (permission.getResourceName() == null || permission.getResourceName().isEmpty()) {
+                    invalid = true;
+                    msgBldr.append("\npermissionName : missing");
+                }
+            } else if (action.equals(Action.UPDATE)) {
+                //update specific validation here
+                if (permission.getResourceName() != null && permission.getResourceName().isEmpty()) {
+                    invalid = true;
+                    msgBldr.append("\npermissionName : cannot be changed!");
+                }
+            }
+            if (invalid) {
+                String msg = msgBldr.toString();
+                logger.error(msg);
+                throw new InvalidDocumentException(msg);
+            }
+        } catch (InvalidDocumentException ide) {
+            throw ide;
+        } catch (Exception e) {
+            throw new InvalidDocumentException(e);
+        }
+    }
+
+}
index 51c2028f219174c9af5a05bc0ac824b358967f2f..7cb44c05d338b18609b2e9ef0abbcda13c1710e6 100644 (file)
  *  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.
- *//**
- *  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.
- */
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
  */
 package org.collectionspace.services.authorization.storage;
 
@@ -72,7 +46,7 @@ public class RoleJpaFilter extends JpaDocumentFilter {
 
         String roleName = null;
         List<String> rn = getQueryParam(RoleStorageConstants.Q_ROLE_NAME);
-        if (rn != null) {
+        if (null != rn) {
             roleName = rn.get(0);
         }
         if (null != roleName && !roleName.isEmpty()) {
index 4ee7dfec6c9cb14565fc686dd9376a09e272f341..85e40523b1077cc50fcce1a11246147de9e09df3 100644 (file)
  *  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.
- *//**
- *  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.
- */
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
  */
 
 package org.collectionspace.services.authorization.storage;
index 9686fc6175fa9b50b585a552473ecb34a4833c44..7216502480228ff6f8b1d4903db55b622f7a7644 100644 (file)
  *  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.
- *//**
- *  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;
index b63c557d22ba7fe7fe355e0d01e95ae24336c36c..94c696b4eb1d9711e1fef79e369eca7a43725115 100644 (file)
@@ -3,7 +3,7 @@
 <!--
     CollectionSpace default (security) authorization provider schema (XSD)
 
-    Entity(s)  : roles, users_roles
+    Entity(s)  : permission
     Used for:
 
     $LastChangedRevision: 916 $
 -->
 
 <xs:schema 
-    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
     xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"
     xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
     xmlns:ns="http://collectionspace.org/services/authorization"
     xmlns="http://collectionspace.org/services/authorization"
     targetNamespace="http://collectionspace.org/services/authorization"
     version="0.1"
-    jaxb:extensionBindingPrefixes="hj orm"
+    jaxb:version="1.0"
+    jaxb:extensionBindingPrefixes="hj orm xjc"
     >
 
     <!--
     See http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html
 -->
 
-
-    <xs:element name="permissions_list">
-        <xs:complexType>
-            <xs:annotation>
-                <xs:appinfo>
-                    <hj:ignored/>
-                </xs:appinfo>
-            </xs:annotation>
-            <xs:sequence>
-                <xs:annotation>
-                    <xs:documentation>permission configuration list</xs:documentation>
-                </xs:annotation>
-                <xs:element name="permission" type="permission" minOccurs="1" maxOccurs="unbounded"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-
+    <!--
+    see http://weblogs.java.net/blog/2006/03/03/why-does-jaxb-put-xmlrootelement-sometimes-not-always
+    for more details behind xjc:simple
+    -->
+    <!--xs:annotation>
+    Note that roles.xsd already defines global bindings for the authorization namespace
+    so, it is not necessary to give the bindingings here because all the xsds are compiled
+    at once for this namespace
+        <xs:appinfo>
+            <jaxb:globalBindings>
+                <xjc:simple />
+            </jaxb:globalBindings>
+        </xs:appinfo>
+    </xs:annotation-->
+    <xs:element name="permission" type="permission"/>
     <xs:complexType name="permission">
         <xs:annotation>
             <xs:documentation>
                     </xs:appinfo>
                 </xs:annotation>
             </xs:element>
+            <xs:element name="tenant_id" type="xs:string" minOccurs="1">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <hj:basic>
+                            <orm:column name="tenant_id" length="128" nullable="false"/>
+                        </hj:basic>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:element>
             <xs:element name="createdAt" type="xs:dateTime">
                 <xs:annotation>
                     <xs:appinfo>
diff --git a/services/authorization/jaxb/src/main/resources/permissions_list.xsd b/services/authorization/jaxb/src/main/resources/permissions_list.xsd
new file mode 100644 (file)
index 0000000..2a3e515
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!--
+    CollectionSpace default (security) authorization provider schema (XSD)
+
+    Entity(s)  : permission
+    Used for:
+
+    $LastChangedRevision: 916 $
+    $LastChangedDate: 2009-11-05 16:59:20 -0800 (Thu, 05 Nov 2009) $
+-->
+
+<xs:schema 
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+    xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"
+    xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
+    xmlns:ns="http://collectionspace.org/services/authorization"
+    xmlns="http://collectionspace.org/services/authorization"
+    targetNamespace="http://collectionspace.org/services/authorization"
+    version="0.1"
+    jaxb:extensionBindingPrefixes="hj orm"
+    >
+
+    <!--
+    Avoid XmlRootElement nightmare:
+    See http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html
+-->
+
+    <xs:import namespace="http://collectionspace.org/services/authorization"
+            schemaLocation="permissions.xsd"/>
+    <xs:element name="permissions_list">
+        <xs:complexType>
+            <xs:annotation>
+                <xs:appinfo>
+                    <hj:ignored/>
+                </xs:appinfo>
+            </xs:annotation>
+            <xs:sequence>
+                <xs:annotation>
+                    <xs:documentation>permission configuration list</xs:documentation>
+                </xs:annotation>
+                <xs:element name="permission" type="ns:permission" minOccurs="1" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+</xs:schema>
+
index 32e76eaca7260ecbacd3faeb17cab4ce60ef0255..74eaae89d2a0a4a296806959e073d54368d158f6 100644 (file)
@@ -3,7 +3,7 @@
 <!--
     CollectionSpace default (security) authorization provider schema (XSD)
 
-    Entity(s)  : roles, users_roles
+    Entity(s)  : role
     Used for:
 
     $LastChangedRevision: 916 $
index 6a038ddc0012e7a66662a334611f7b440a692f7b..dac098062b2156f5b57f6950381773294f6249cc 100644 (file)
@@ -3,7 +3,7 @@
 <!--
     CollectionSpace default (security) authorization provider schema (XSD)
 
-    Entity(s)  : roles, users_roles
+    Entity(s)  : roles_list
     Used for:
 
     $LastChangedRevision: 916 $
index 33b5cf107b10ee3795de24d271f8a829b18fcb0d..0b00e294486fb1f019a073473e867656b2f73fd9 100644 (file)
@@ -4,7 +4,7 @@ drop table if exists permissions_actions;
 drop table if exists permissions_roles;
 drop table if exists roles;
 drop table if exists users_roles;
-create table permissions (csid varchar(128) not null, attribute_name varchar(128), created_at datetime not null, description varchar(255), effect varchar(32) not null, resource_name varchar(128) not null, updated_at datetime, primary key (csid));
+create table permissions (csid varchar(128) not null, attribute_name varchar(128), created_at datetime not null, description varchar(255), effect varchar(32) not null, resource_name varchar(128) not null, tenant_id varchar(128) not null, updated_at datetime, primary key (csid));
 create table permissions_actions (HJID bigint not null auto_increment, name varchar(128) not null, ACTIONS_PERMISSION_CSID varchar(128), primary key (HJID));
 create table permissions_roles (HJID bigint not null auto_increment, created_at datetime not null, permission_id varchar(128) not null, role_id varchar(128) not null, updated_at datetime, primary key (HJID), unique (permission_id, role_id));
 create table roles (csid varchar(128) not null, created_at datetime not null, description varchar(255), rolegroup varchar(255), rolename varchar(200) not null, tenant_id varchar(128) not null, updated_at datetime, primary key (csid), unique (rolename));
index 83f3d7fc6e04c16ce33c2d3c5511346838312963..cdb85fb611187df5a9efbf23ddaca865c0850fa4 100644 (file)
             </service:object>
         </tenant:serviceBindings>
         <!-- end role service meta-data -->
+                <!-- begin permission service meta-data -->
+        <tenant:serviceBindings name="authorization/permissions" version="0.1">
+            <service:documentHandler xmlns:service='http://collectionspace.org/services/common/service'>
+                org.collectionspace.services.authorization.storage.PermissionDocumentHandler
+            </service:documentHandler>
+            <service:validatorHandler xmlns:service='http://collectionspace.org/services/common/service'>
+                org.collectionspace.services.authorization.storage.PermissionValidatorHandler
+            </service:validatorHandler>
+            <service:object name="Permission" version="0.1"
+                            xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:part id="0" control_group="Managed"
+                              versionable="true" auditable="false"
+                              label="permissions_system" updated="" order="0">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                            namespaceURI="http://collectionspace.org/services/common/system"
+                            schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+                <service:part id="1" control_group="Managed"
+                              versionable="true" auditable="false"
+                              label="permissions" updated="" order="1">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                            namespaceURI="http://collectionspace.org/services/authorization"
+                            schemaLocation="http://collectionspace.org/services/authorization http://services.collectionspace.org/authorization/permissions.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+            </service:object>
+        </tenant:serviceBindings>
+        <!-- end permission service meta-data -->
     </tenant:tenantBinding>
     <!-- end movingimages.us tenant meta-data -->
 </tenant:TenantBindingConfig>
index d9d11e56d7ef1880c248bdc51ab3eb2019155277..f865119a786e5b143eb214bbdba76b189c97d473 100644 (file)
@@ -83,6 +83,7 @@ public class JpaStorageClientImpl implements StorageClient {
     private final Logger logger = LoggerFactory.getLogger(JpaStorageClientImpl.class);
     /** The Constant CS_PERSISTENCE_UNIT. */
     public final static String CS_PERSISTENCE_UNIT = "org.collectionspace.services";
+    private Class entityClazz;
 
     /**
      * Instantiates a new jpa storage client.
@@ -90,6 +91,10 @@ public class JpaStorageClientImpl implements StorageClient {
     public JpaStorageClientImpl() {
     }
 
+    public JpaStorageClientImpl(Class entityClazz) {
+        this.entityClazz = entityClazz;
+    }
+
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.storage.StorageClient#create(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.document.DocumentHandler)
      */
@@ -98,11 +103,6 @@ public class JpaStorageClientImpl implements StorageClient {
             DocumentHandler handler) throws BadRequestException,
             DocumentException {
 
-        String docType = ctx.getDocumentType();
-        if (docType == null) {
-            throw new DocumentNotFoundException(
-                    "Unable to find DocumentType for service " + ctx.getServiceName());
-        }
         if (handler == null) {
             throw new IllegalArgumentException(
                     "JpaStorageClient.create: handler is missing");
@@ -167,11 +167,6 @@ public class JpaStorageClientImpl implements StorageClient {
         if (docFilter == null) {
             docFilter = handler.createDocumentFilter(ctx);
         }
-        String docType = ctx.getDocumentType();
-        if (docType == null) {
-            throw new DocumentNotFoundException(
-                    "Unable to find DocumentType for service " + ctx.getServiceName());
-        }
         EntityManagerFactory emf = null;
         EntityManager em = null;
         try {
@@ -251,12 +246,6 @@ public class JpaStorageClientImpl implements StorageClient {
         if (docFilter == null) {
             docFilter = handler.createDocumentFilter(ctx);
         }
-        String docType = ctx.getDocumentType();
-        if (docType == null) {
-            throw new DocumentNotFoundException(
-                    "Unable to find DocumentType for service " + ctx.getServiceName());
-        }
-
         EntityManagerFactory emf = null;
         EntityManager em = null;
         try {
@@ -310,11 +299,6 @@ public class JpaStorageClientImpl implements StorageClient {
     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 (handler == null) {
             throw new IllegalArgumentException(
                     "JpaStorageClient.update: handler is missing");
@@ -365,7 +349,7 @@ public class JpaStorageClientImpl implements StorageClient {
         }
     }
 
-    /* (non-Javadoc)
+    /* delete use delete to remove parent entity along with child entities
      * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String)
      */
     @Override
@@ -376,10 +360,60 @@ public class JpaStorageClientImpl implements StorageClient {
         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());
+        EntityManagerFactory emf = null;
+        EntityManager em = null;
+        try {
+
+            //TODO: add tenant id
+
+            emf = getEntityManagerFactory();
+            em = emf.createEntityManager();
+
+            em.getTransaction().begin();
+            Object entityFound = getEntity(em, id);
+            if (entityFound == null) {
+                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.remove(entityFound);
+            em.getTransaction().commit();
+
+        } catch (DocumentException de) {
+            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);
+            }
+        }
+    }
+
+    /**
+     * deleteWhere uses the where clause to delete an entity represented by the id
+     * it does not delete any child entities.
+     * @param ctx
+     * @param id
+     * @throws DocumentNotFoundException
+     * @throws DocumentException
+     */
+    public void deleteWhere(ServiceContext ctx, String id)
+            throws DocumentNotFoundException,
+            DocumentException {
+
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleting entity with id=" + id);
         }
         EntityManagerFactory emf = null;
         EntityManager em = null;
@@ -563,6 +597,37 @@ public class JpaStorageClientImpl implements StorageClient {
         return (String) o;
     }
 
+    /**
+     * getEntity returns persistent entity for given id. it assumes that
+     * JpaStorageClientImpl is implemented using the JpaStorageClientImpl(entityClazz)
+     * constructor
+     * @param em
+     * @param id
+     * @return
+     * @throws DocumentNotFoundException
+     * @throws UnsupportedOperationException if JpaStorageClientImpl is not implemented
+     * using the JpaStorageClientImpl(entityClazz)
+     * constructor
+     */
+    protected Object getEntity(EntityManager em, String id) throws DocumentNotFoundException {
+        if (entityClazz == null) {
+            String msg = "Not constructed with JpaStorageClientImpl(entityClazz) ctor";
+            logger.error(msg);
+            throw new UnsupportedOperationException(msg);
+        }
+        Object entityFound = em.find(entityClazz, id);
+        if (entityFound == null) {
+            if (em != null && em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            String msg = "could not find entity of type=" + entityClazz.getName()
+                    + " with id=" + id;
+            logger.error(msg);
+            throw new DocumentNotFoundException(msg);
+        }
+        return entityFound;
+    }
+
     @Override
     public void get(ServiceContext ctx, DocumentHandler handler)
             throws DocumentNotFoundException, DocumentException {