From 9caaefa91558a004c0cba494429184aefbfa2300 Mon Sep 17 00:00:00 2001 From: Richard Millet Date: Thu, 12 Apr 2012 19:42:57 -0700 Subject: [PATCH] CSPACE-4964: Fixing bugs related to authority item workflow related permissions. --- .../OSGI-INF/default-life-cycle-contrib.xml | 7 +--- .../common/vocabulary/AuthorityResource.java | 16 +++++++--- .../client/test/PermissionServiceTest.java | 2 +- .../services/client/AuthorityClient.java | 2 +- .../services/client/AuthorityClientImpl.java | 4 +-- .../services/client/AuthorityProxy.java | 7 ++-- .../client/test/AbstractServiceTestImpl.java | 6 ++-- .../client/workflow/WorkflowClient.java | 1 + .../tenants/tenant-bindings-proto.xml | 32 +------------------ ...tMultiPartCollectionSpaceResourceImpl.java | 2 +- .../services/common/ServiceMain.java | 2 +- .../AuthorizationCommon.java | 13 +------- .../common/security/SecurityInterceptor.java | 4 +-- .../common/security/SecurityUtils.java | 21 ++++++++++++ 14 files changed, 51 insertions(+), 68 deletions(-) diff --git a/3rdparty/nuxeo/nuxeo-platform-collectionspace/src/main/resources/OSGI-INF/default-life-cycle-contrib.xml b/3rdparty/nuxeo/nuxeo-platform-collectionspace/src/main/resources/OSGI-INF/default-life-cycle-contrib.xml index 3d605cde6..038f3a7fd 100644 --- a/3rdparty/nuxeo/nuxeo-platform-collectionspace/src/main/resources/OSGI-INF/default-life-cycle-contrib.xml +++ b/3rdparty/nuxeo/nuxeo-platform-collectionspace/src/main/resources/OSGI-INF/default-life-cycle-contrib.xml @@ -45,9 +45,6 @@ Lock document - - Unlock the document - Move document to trash (temporary delete) @@ -63,9 +60,7 @@ - - unlock - + diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java index 8e1c5d5a4..bf47c2dae 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java @@ -56,12 +56,14 @@ import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumen import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler; import org.collectionspace.services.config.ClientType; import org.collectionspace.services.jaxb.AbstractCommonList; +import org.collectionspace.services.lifecycle.TransitionDef; import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl; import org.collectionspace.services.relation.RelationResource; import org.collectionspace.services.relation.RelationsCommonList; import org.collectionspace.services.relation.RelationshipType; +import org.collectionspace.services.workflow.WorkflowCommon; import org.jboss.resteasy.util.HttpResponseCodes; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.repository.RepositoryInstance; @@ -550,18 +552,22 @@ public abstract class AuthorityResource } @PUT - @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH) - public byte[] updateWorkflow( + @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH + "/{transition}") + public byte[] updateItemWorkflowWithTransition( @PathParam("csid") String csid, @PathParam("itemcsid") String itemcsid, - String xmlPayload) { + @PathParam("transition") String transition) { PoxPayloadOut result = null; try { + PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(), + WorkflowClient.SERVICE_COMMONPART_NAME); + ServiceContext parentCtx = createServiceContext(getItemServiceName()); String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName(); - PoxPayloadIn workflowUpdate = new PoxPayloadIn(xmlPayload); - MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, workflowUpdate); + TransitionDef transitionDef = getTransitionDef(parentCtx, transition); + MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, input); + ctx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef); WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx); ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace getRepositoryClient(ctx).update(ctx, itemcsid, handler); diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java index 11b044f82..3b254001e 100644 --- a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java @@ -146,7 +146,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl updateItemWorkflow(@PathParam("vcsid") String vcsid, + @Path("/{vcsid}/items/{csid}" + WorkflowClient.SERVICE_PATH + "/{transition}") + ClientResponse updateItemWorkflowWithTransition( + @PathParam("vcsid") String vcsid, @PathParam("csid") String csid, - byte[] xmlPayload); + @PathParam("transition") String transition); } diff --git a/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java b/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java index 510ad38f2..7e3c1fb59 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java +++ b/services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java @@ -1041,7 +1041,7 @@ public abstract class AbstractServiceTestImpl - /collectionobjects/*/workflow/ - /blobs/*/workflow/ default-domain org.collectionspace.services.blob.nuxeo.BlobDocumentModelHandler @@ -690,7 +688,6 @@ - /intakes/*/workflow/ - /loansin/*/workflow/ - /loansout/*/workflow/ - /objectexit/*/workflow/ default-domain org.collectionspace.services.objectexit.nuxeo.ObjectExitDocumentModelHandler @@ -1151,7 +1145,6 @@ - /batch/*/workflow/ default-domain org.collectionspace.services.batch.nuxeo.BatchDocumentModelHandler @@ -1188,7 +1181,6 @@ - /groups/*/workflow/ default-domain org.collectionspace.services.group.nuxeo.GroupDocumentModelHandler @@ -1250,7 +1242,6 @@ - /imports/*/workflow/ default-domain org.collectionspace.services.imports.nuxeo.ImportsDocumentModelHandler @@ -1294,7 +1285,6 @@ - /media/*/workflow/ default-domain org.collectionspace.services.media.nuxeo.MediaDocumentModelHandler @@ -1411,7 +1401,6 @@ - /movements/*/workflow/ - /reports/*/workflow/ - /vocabularies/*/workflow/ - /vocabularies/*/items/*/workflow/ default-domain org.collectionspace.services.vocabulary.nuxeo.VocabularyDocumentModelHandler @@ -1663,7 +1649,6 @@ Repository workspace so we have to configure that. --> - /vocabularyitems/*/workflow/ - /orgauthorities/*/workflow/ - /orgauthorities/*/items/*/workflow/ - /personauthorities/*/workflow/ - /personauthorities/*/items/*/workflow/ - /locationauthorities/*/workflow/ - /locationauthorities/*/items/*/workflow/ - /placeauthorities/*/workflow/ - /placeauthorities/*/items/*/workflow/ - /taxonomyauthority/*/workflow/ - /taxonomyauthority/*/items/*/workflow/ - /conceptauthorities/*/workflow/ - /conceptauthorities/*/items/*/workflow/ - /acquisitions/*/workflow/ - /relations/*/workflow/ default-domain org.collectionspace.services.relation.nuxeo.RelationDocumentModelHandler @@ -2986,7 +2957,7 @@ - /dimensions/*/workflow/ + /dimensions/workflow/ default-domain org.collectionspace.services.dimension.nuxeo.DimensionDocumentModelHandler @@ -3090,7 +3061,6 @@ - /notes/*/workflow/ default-domain org.collectionspace.services.note.nuxeo.NoteDocumentModelHandler diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java index 9728a8dc2..217cf60e8 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java @@ -193,7 +193,7 @@ public abstract class AbstractMultiPartCollectionSpaceResourceImpl extends Abstr return result.getBytes(); } - private TransitionDef getTransitionDef(ServiceContext ctx, String transition) { + protected TransitionDef getTransitionDef(ServiceContext ctx, String transition) { TransitionDef result = null; try { diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java index 0c98156ee..4fc06ff32 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java @@ -164,7 +164,7 @@ public class ServiceMain { // Create all the default user accounts and permissions // try { - AuthorizationCommon.createDefaultPermissions(tenantBindingConfigReader); + AuthorizationCommon.createDefaultWorkflowPermissions(tenantBindingConfigReader); AuthorizationCommon.createDefaultAccounts(tenantBindingConfigReader); } catch(Throwable e) { logger.error("Default accounts and permissions setup failed with exception(s): " + e.getLocalizedMessage(), e); diff --git a/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java b/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java index 16f3153ab..90d4543e3 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java +++ b/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java @@ -798,7 +798,7 @@ public class AuthorizationCommon { return result; } - public static void createDefaultPermissions(TenantBindingConfigReaderImpl tenantBindingConfigReader) throws Exception //FIXME: REM - 4/11/2012 - Rename to createWorkflowPermissions + public static void createDefaultWorkflowPermissions(TenantBindingConfigReaderImpl tenantBindingConfigReader) throws Exception //FIXME: REM - 4/11/2012 - Rename to createWorkflowPermissions { AuthZ.get().login(); //login to Spring Security manager @@ -820,17 +820,6 @@ public class AuthorizationCommon { if (prop == null ? true : Boolean.parseBoolean(prop)) { try { em.getTransaction().begin(); - // - // For the default admin role, create the base workflow (aka, "/workflow" permissions for the service. - Permission baseAdminPerm = createWorkflowPermission(tenantBinding, serviceBinding, null, ACTIONGROUP_CRUDL); - persist(em, baseAdminPerm, adminRole, true); - // - // For the default read-only role, create the base workflow (aka, "/workflow" permissions for the service. - Permission baseReadonlyPerm = createWorkflowPermission(tenantBinding, serviceBinding, null, ACTIONGROUP_RL); - persist(em, baseReadonlyPerm, readonlyRole, true); - // - // Next, create a permission for each workflow transition supported by the service's document type. - // TransitionDefList transitionDefList = getTransitionDefList(tenantBinding, serviceBinding); for (TransitionDef transitionDef : transitionDefList.getTransitionDef()) { // diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java index 2bd6a0d59..6cc115505 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java @@ -137,8 +137,8 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn // to perform a workflow state change and make sure they are allowed to to this. // if (uriPath.contains(WorkflowClient.SERVICE_PATH) == true) { - String workflowSubResName = SecurityUtils.getResourceName(request.getUri()); - res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), workflowSubResName, httpMethod); + String workflowProxyResource = SecurityUtils.getWorkflowResourceName(request); + res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), workflowProxyResource, httpMethod); if (authZ.isAccessAllowed(res) == false) { logger.error("Access to " + resName + ":" + res.getId() + " is NOT allowed to " + " user=" + AuthN.get().getUserId()); diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java index 9d0df0934..796b1dbce 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java @@ -32,6 +32,7 @@ import java.util.StringTokenizer; import org.collectionspace.services.authorization.AuthZ; import org.collectionspace.services.authorization.CSpaceResource; import org.collectionspace.services.authorization.URIResourceImpl; +import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.config.service.ServiceBindingType; import javax.ws.rs.core.MultivaluedMap; @@ -42,6 +43,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.jboss.crypto.digest.DigestCallback; +import org.jboss.resteasy.spi.HttpRequest; import org.jboss.security.Base64Encoder; import org.jboss.security.Base64Utils; @@ -98,6 +100,25 @@ public class SecurityUtils { } } + public static String getWorkflowResourceName(HttpRequest request) { + String result = null; + + UriInfo uriInfo = request.getUri(); + String workflowSubResName = SecurityUtils.getResourceName(uriInfo); + String resEntity = SecurityUtils.getResourceEntity(workflowSubResName); + + MultivaluedMap pathParams = uriInfo.getPathParameters(); + String workflowTransition = pathParams.getFirst(WorkflowClient.TRANSITION_PARAM_JAXRS); + if (workflowTransition != null) { + result = resEntity + "/*/" + WorkflowClient.SERVICE_NAME + "/" + workflowTransition; + } else { + // e.g., intakes/workflow or intakes/*/workflow + result = resEntity; + } + + return result; + } + /** * Gets the resource name. * -- 2.47.3