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;
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());
<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>
* 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;
//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
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) {
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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);
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
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.
// Success outcomes
@Override
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
- dependsOnMethods = {"testSubmitRequest"})
+ dependsOnMethods = {"update"})
public void delete(String testName) throws Exception {
// Perform setup.
if (useRoleName) {
role.setRoleName(roleName);
}
-
+ role.setDescription(description);
if (logger.isDebugEnabled()) {
logger.debug("to be created, role common");
logger.debug(objectAsXmlString(role, Role.class));
--- /dev/null
+/**
+ * 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);
+ }
+
+ }
+}
}
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(
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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>();
+ }
+}
--- /dev/null
+/**
+ * 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";
+
+}
--- /dev/null
+/**
+ * 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);
+ }
+ }
+
+}
* 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;
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()) {
* 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;
* 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;
<!--
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>
--- /dev/null
+<?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>
+
<!--
CollectionSpace default (security) authorization provider schema (XSD)
- Entity(s) : roles, users_roles
+ Entity(s) : role
Used for:
$LastChangedRevision: 916 $
<!--
CollectionSpace default (security) authorization provider schema (XSD)
- Entity(s) : roles, users_roles
+ Entity(s) : roles_list
Used for:
$LastChangedRevision: 916 $
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));
</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>
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.
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)
*/
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");
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 {
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 {
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");
}
}
- /* (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
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;
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 {