diff --git a/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java index c49442267a..a279ea3b86 100644 --- a/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java @@ -629,6 +629,10 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl imp case Constants.DELETE: if (AuthorizeConfiguration.canCommunityAdminPerformSubelementDeletion()) { adminObject = getParentObject(context, community); + if (adminObject == null) { + //top-level community, has to be admin of the current communitu + adminObject = community; + } } break; case Constants.ADD: diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 9502a2ca32..20988d0625 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -1100,19 +1100,7 @@ prevent the generation of resource policy entry values with null dspace_object a } break; case Constants.DELETE: - if (item.getOwningCollection() != null) { - if (AuthorizeConfiguration.canCollectionAdminPerformItemDeletion()) { - adminObject = collection; - } else if (AuthorizeConfiguration.canCommunityAdminPerformItemDeletion()) { - adminObject = community; - } - } else { - if (AuthorizeConfiguration.canCollectionAdminManageTemplateItem()) { - adminObject = collection; - } else if (AuthorizeConfiguration.canCommunityAdminManageCollectionTemplateItem()) { - adminObject = community; - } - } + adminObject = item; break; case Constants.WRITE: // if it is a template item we need to check the diff --git a/dspace-api/src/test/java/org/dspace/content/CommunityTest.java b/dspace-api/src/test/java/org/dspace/content/CommunityTest.java index 812060d019..74f8c20cf2 100644 --- a/dspace-api/src/test/java/org/dspace/content/CommunityTest.java +++ b/dspace-api/src/test/java/org/dspace/content/CommunityTest.java @@ -1013,7 +1013,8 @@ public class CommunityTest extends AbstractDSpaceObjectTest { equalTo(c)); assertThat("testGetAdminObject 1", (Community) communityService.getAdminObject(context, c, Constants.ADD), equalTo(c)); - assertThat("testGetAdminObject 2", communityService.getAdminObject(context, c, Constants.DELETE), nullValue()); + assertThat("testGetAdminObject 2", (Community) communityService.getAdminObject(context, c, Constants.DELETE), + equalTo(c)); assertThat("testGetAdminObject 3", (Community) communityService.getAdminObject(context, c, Constants.ADMIN), equalTo(c)); } diff --git a/dspace-api/src/test/java/org/dspace/content/ItemTest.java b/dspace-api/src/test/java/org/dspace/content/ItemTest.java index 8c3cfa5a04..85b4fed60b 100644 --- a/dspace-api/src/test/java/org/dspace/content/ItemTest.java +++ b/dspace-api/src/test/java/org/dspace/content/ItemTest.java @@ -1598,8 +1598,8 @@ public class ItemTest extends AbstractDSpaceObjectTest { assertThat("testGetAdminObject 0", (Item) itemService.getAdminObject(context, it, Constants.REMOVE), equalTo(it)); assertThat("testGetAdminObject 1", (Item) itemService.getAdminObject(context, it, Constants.ADD), equalTo(it)); - assertThat("testGetAdminObject 2", (Collection) itemService.getAdminObject(context, it, Constants.DELETE), - equalTo(collection)); + assertThat("testGetAdminObject 2", (Item) itemService.getAdminObject(context, it, Constants.DELETE), + equalTo(it)); assertThat("testGetAdminObject 3", (Item) itemService.getAdminObject(context, it, Constants.ADMIN), equalTo(it)); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CreateBitstreamFeature.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CreateBitstreamFeature.java index e5b2f122d4..093885ca73 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CreateBitstreamFeature.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CreateBitstreamFeature.java @@ -19,8 +19,8 @@ import org.dspace.app.rest.security.DSpaceRestPermission; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.Bundle; -import org.dspace.content.Collection; import org.dspace.content.DSpaceObject; +import org.dspace.content.Item; import org.dspace.content.service.BundleService; import org.dspace.core.Constants; import org.dspace.core.Context; @@ -61,12 +61,12 @@ public class CreateBitstreamFeature implements AuthorizationFeature { DSpaceObject owningObject = bundleService.getParentObject(context, (Bundle)utils.getDSpaceAPIObjectFromRest(context, object)); - if (!(owningObject instanceof Collection)) { + if (!(owningObject instanceof Item)) { log.error("The partent object of bundle " + object.getType() + " is not an item"); return false; } - if (authorizeService.authorizeActionBoolean(context, context.getCurrentUser(), owningObject, + if (!authorizeService.authorizeActionBoolean(context, context.getCurrentUser(), owningObject, Constants.WRITE, true)) { return false; } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/GenericAuthorizationFeatureIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/GenericAuthorizationFeatureIT.java index ca9af6be1c..659e80eaa2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/GenericAuthorizationFeatureIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/GenericAuthorizationFeatureIT.java @@ -1,3 +1,10 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.app.rest.authorization; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -758,7 +765,7 @@ public class GenericAuthorizationFeatureIT extends AbstractControllerIntegration String communityAAdminToken = getAuthToken(communityAAdmin.getEmail(), password); String collectionXAdminToken = getAuthToken(collectionXAdmin.getEmail(), password); String item1AdminToken = getAuthToken(item1Admin.getEmail(), password); - String feature = "canMove"; + final String feature = "canMove"; // Verify the general admin has this feature on item 1 getClient(adminToken).perform( @@ -870,4 +877,833 @@ public class GenericAuthorizationFeatureIT extends AbstractControllerIntegration public void testCanMakeDiscoverableWriter() throws Exception { testWriteUsersHavePermissionsItem("canMakeDiscoverable", true); } + + @Test + public void testCanDeleteAdmin() throws Exception { + String adminToken = getAuthToken(admin.getEmail(), password); + String communityAAdminToken = getAuthToken(communityAAdmin.getEmail(), password); + String collectionXAdminToken = getAuthToken(collectionXAdmin.getEmail(), password); + String item1AdminToken = getAuthToken(item1Admin.getEmail(), password); + String siteId = ContentServiceFactory.getInstance().getSiteService().findSite(context).getID().toString(); + final String feature = "canDelete"; + + // Verify the general admin doesn’t have this feature on the site + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/sites/" + siteId)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify the general admin has this feature on community A + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on community A + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on community AA + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityAA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Create a community AA admin and verify the community AA admin doesn’t have this feature on community AA + context.turnOffAuthorisationSystem(); + EPerson communityAAAdmin = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("communityAAAdmin@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(communityAA) + .withAction(Constants.ADMIN) + .withUser(communityAAAdmin) + .build(); + context.restoreAuthSystemState(); + String communityAAAdminToken = getAuthToken(communityAAAdmin.getEmail(), password); + getClient(communityAAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityAA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify collection X admin doesn’t have this feature on community A + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify community A admin doesn’t have this feature on community B + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityB.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify the general admin has this feature on collection X + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on collection X + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify collection X admin doesn’t have this feature on collection X + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify item 1 admin doesn’t have this feature on collection X + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify collection X admin doesn’t have this feature on collection Y + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionY.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify the general admin has this feature on item 1 + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on item 1 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify collection X admin has this feature on item 1 + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin doesn’t have this feature on item 1 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify item 1 admin doesn’t have this feature on item 2 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item2.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify the general admin has this feature on the bundle in item 1 + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on the bundle in item 1 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify collection X admin has this feature on the bundle in item 1 + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin has this feature on the bundle in item 1 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin doesn’t have this feature on the bundle in item 2 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle2.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify the general admin has this feature on the bitstream in item 1 + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on the bitstream in item 1 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify collection X admin has this feature on the bitstream in item 1 + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin has this feature on the bitstream in item 1 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin doesn’t have this feature on the bitstream in item 2 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream2.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + } + + @Test + public void testCanDeleteAdminParent() throws Exception { + String collectionXAdminToken = getAuthToken(collectionXAdmin.getEmail(), password); + String item1AdminToken = getAuthToken(item1Admin.getEmail(), password); + final String feature = "canDelete"; + + // Create a community AA admin, grant REMOVE permissions on community A to this user + context.turnOffAuthorisationSystem(); + EPerson communityAAAdmin = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("communityAAAdmin@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(communityA) + .withAction(Constants.REMOVE) + .withUser(communityAAAdmin) + .build(); + context.restoreAuthSystemState(); + String communityAAAdminToken = getAuthToken(communityAAAdmin.getEmail(), password); + //verify the community AA admin has this feature on community AA + getClient(communityAAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityAA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Grant REMOVE permissions on community AA for collection X admin + context.turnOffAuthorisationSystem(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(communityAA) + .withAction(Constants.REMOVE) + .withUser(collectionXAdmin) + .build(); + context.restoreAuthSystemState(); + // verify collection X admin has this feature on collection X + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Grant REMOVE permissions on collection X for item 1 admin + context.turnOffAuthorisationSystem(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(collectionX) + .withAction(Constants.REMOVE) + .withUser(item1Admin) + .build(); + context.restoreAuthSystemState(); + // verify item 1 admin has this feature on item 1 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + } + + @Test + public void testCanDeleteWriter() throws Exception { + testWriteUsersHavePermissionsAllDso("canManagePolicies", false); + } + + @Test + public void testCanDeleteMinimalPermissions() throws Exception { + final String feature = "canDelete"; + + // Create a new user, grant DELETE permissions on community A to this user + context.turnOffAuthorisationSystem(); + EPerson communityADeleter = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("communityADeleter@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(communityA) + .withAction(Constants.DELETE) + .withUser(communityADeleter) + .build(); + context.restoreAuthSystemState(); + String communityADeleterToken = getAuthToken(communityADeleter.getEmail(), password); + // Verify the user has this feature on community A + getClient(communityADeleterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + // Verify this user doesn’t have this feature on community AA + getClient(communityADeleterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityAA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + + // Create a new user, grant REMOVE permissions on community A to this user + context.turnOffAuthorisationSystem(); + EPerson communityARemover = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("communityARemover@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(communityA) + .withAction(Constants.REMOVE) + .withUser(communityARemover) + .build(); + context.restoreAuthSystemState(); + String communityARemoverToken = getAuthToken(communityARemover.getEmail(), password); + // Verify the user has this feature on community AA + getClient(communityARemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityAA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + // Verify this user doesn’t have this feature on community A + getClient(communityARemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + // Verify this user doesn’t have this feature on collection X + getClient(communityARemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant REMOVE permissions on community AA to this user + context.turnOffAuthorisationSystem(); + EPerson communityAARemover = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("communityAARemover@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(communityAA) + .withAction(Constants.REMOVE) + .withUser(communityAARemover) + .build(); + context.restoreAuthSystemState(); + String communityAARemoverToken = getAuthToken(communityAARemover.getEmail(), password); + // Verify the user has this feature on collection X + getClient(communityAARemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + // Verify this user doesn’t have this feature on community AA + getClient(communityAARemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/communities/" + communityAA.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + // Verify this user doesn’t have this feature on item 1 + getClient(communityAARemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant REMOVE permissions on collection X to this user + context.turnOffAuthorisationSystem(); + EPerson collectionXRemover = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("communityXRemover@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(collectionX) + .withAction(Constants.REMOVE) + .withUser(collectionXRemover) + .build(); + context.restoreAuthSystemState(); + String collectionXRemoverToken = getAuthToken(collectionXRemover.getEmail(), password); + // Verify the user doesn’t have this feature on item 1 + getClient(collectionXRemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant DELETE permissions on item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson item1Deleter = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("item1Deleter@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.DELETE) + .withUser(item1Deleter) + .build(); + context.restoreAuthSystemState(); + String item1DeleterToken = getAuthToken(item1Deleter.getEmail(), password); + // Verify the user doesn’t have this feature on item 1 + getClient(item1DeleterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant REMOVE permissions on collection X and DELETE permissions on item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson collectionXRemoverItem1Deleter = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("collectionXDeleter@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(collectionX) + .withAction(Constants.REMOVE) + .withUser(collectionXRemoverItem1Deleter) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.DELETE) + .withUser(collectionXRemoverItem1Deleter) + .build(); + context.restoreAuthSystemState(); + String collectionXRemoverItem1DeleterToken = getAuthToken(collectionXRemoverItem1Deleter.getEmail(), password); + // Verify the user has this feature on item 1 + getClient(collectionXRemoverItem1DeleterToken).perform( + get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + // Verify this user doesn’t have this feature on collection X + getClient(collectionXRemoverItem1DeleterToken).perform( + get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/collections/" + collectionX.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + // Verify this user doesn’t have this feature on the bundle in item 1 + getClient(collectionXRemoverItem1DeleterToken).perform( + get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant REMOVE permissions on item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson item1Remover = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("item1Remover@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.REMOVE) + .withUser(item1Remover) + .build(); + context.restoreAuthSystemState(); + String item1RemoverToken = getAuthToken(item1Remover.getEmail(), password); + // Verify the user has this feature on the bundle in item 1 + getClient(item1RemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + // Verify this user doesn’t have this feature on item 1 + getClient(item1RemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + // Verify this user doesn’t have this feature on the bitstream in item 1 + getClient(item1RemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant REMOVE permissions on the bundle in item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson bundle1Remover = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("bundle1Remover@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(bundle1) + .withAction(Constants.REMOVE) + .withUser(bundle1Remover) + .build(); + context.restoreAuthSystemState(); + String bundle1RemoverToken = getAuthToken(bundle1Remover.getEmail(), password); + // Verify the user doesn’t have this feature on the bitstream in item 1 + getClient(bundle1RemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant REMOVE permissions on the bundle in item 1 + // and REMOVE permissions on item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson bundle1item1Remover = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("bundle1item1Remover@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(bundle1) + .withAction(Constants.REMOVE) + .withUser(bundle1item1Remover) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.REMOVE) + .withUser(bundle1item1Remover) + .build(); + context.restoreAuthSystemState(); + String bundle1item1RemoverToken = getAuthToken(bundle1item1Remover.getEmail(), password); + // Verify the user has this feature on the bitstream in item 1 + getClient(bundle1item1RemoverToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bitstreams/" + bitstream1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + } + + @Test + public void testCanReorderBitstreamsAdmin() throws Exception { + String adminToken = getAuthToken(admin.getEmail(), password); + String communityAAdminToken = getAuthToken(communityAAdmin.getEmail(), password); + String collectionXAdminToken = getAuthToken(collectionXAdmin.getEmail(), password); + String item1AdminToken = getAuthToken(item1Admin.getEmail(), password); + final String feature = "canReorderBitstreams"; + + // Verify the general admin has this feature on the bundle in item 1 + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on the bundle in item 1 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify collection X admin has this feature on the bundle in item 1 + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin has this feature on the bundle in item 1 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin doesn’t have this feature on the bundle in item 2 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle2.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + } + + @Test + public void testCanReorderBitstreamsWriter() throws Exception { + String communityAWriterToken = getAuthToken(communityAWriter.getEmail(), password); + String collectionXWriterToken = getAuthToken(collectionXWriter.getEmail(), password); + String item1WriterToken = getAuthToken(item1Writer.getEmail(), password); + final String feature = "canReorderBitstreams"; + + // Verify community A write doesn’t have this feature on the bundle in item 1 + getClient(communityAWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + // Verify collection X write doesn’t have this feature on the bundle in item 1 + getClient(collectionXWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + // Verify item 1 write doesn’t have this feature on the bundle in item 1 + getClient(item1WriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant WRITE permissions on the bundle in item 1 to this user + // Verify the user has this feature on the bundle in item 1 + getClient(communityAWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + } + + @Test + public void testCanCreateBitstreamAdmin() throws Exception { + String adminToken = getAuthToken(admin.getEmail(), password); + String communityAAdminToken = getAuthToken(communityAAdmin.getEmail(), password); + String collectionXAdminToken = getAuthToken(collectionXAdmin.getEmail(), password); + String item1AdminToken = getAuthToken(item1Admin.getEmail(), password); + final String feature = "canCreateBitstream"; + + // Verify the general admin has this feature on the bundle in item 1 + getClient(adminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin has this feature on the bundle in item 1 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify collection X admin has this feature on the bundle in item 1 + getClient(collectionXAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify item 1 admin has this feature on the bundle in item 1 + getClient(item1AdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + + // Verify community A admin doesn’t have this feature on the bundle in item 2 + getClient(communityAAdminToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle2.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + } + + @Test + public void testCanCreateBitstreamWriter() throws Exception { + String communityAWriterToken = getAuthToken(communityAWriter.getEmail(), password); + String collectionXWriterToken = getAuthToken(collectionXWriter.getEmail(), password); + String item1WriterToken = getAuthToken(item1Writer.getEmail(), password); + final String feature = "canCreateBitstream"; + + // Verify community A write doesn’t have this feature on the bundle in item 1 + getClient(communityAWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify collection X write doesn’t have this feature on the bundle in item 1 + getClient(collectionXWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify item 1 write doesn’t have this feature on the bundle in item 1 + getClient(item1WriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant WRITE permissions on the bundle in item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson bundle1Writer = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("bundle1Writer@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(bundle1) + .withAction(Constants.WRITE) + .withUser(bundle1Writer) + .build(); + context.restoreAuthSystemState(); + String bundle1WriterToken = getAuthToken(bundle1Writer.getEmail(), password); + // Verify the user doesn’t have this feature on the bundle in item 1 + getClient(bundle1WriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant ADD permissions on the bundle in item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson bundle1Adder = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("bundle1Adder@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(bundle1) + .withAction(Constants.ADD) + .withUser(bundle1Adder) + .build(); + context.restoreAuthSystemState(); + String bundle1AdderToken = getAuthToken(bundle1Adder.getEmail(), password); + // Verify the user doesn’t have this feature on the bundle in item 1 + getClient(bundle1AdderToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant ADD and WRITE permissions on the bundle in item 1 + // and ADD and WRITE permission on the item to this user + context.turnOffAuthorisationSystem(); + EPerson bundle1WriterAdder = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("bundle1WriterAdder@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(bundle1) + .withAction(Constants.ADD) + .withUser(bundle1WriterAdder) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(bundle1) + .withAction(Constants.WRITE) + .withUser(bundle1WriterAdder) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.ADD) + .withUser(bundle1WriterAdder) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.WRITE) + .withUser(bundle1WriterAdder) + .build(); + context.restoreAuthSystemState(); + String bundle1WriterAdderToken = getAuthToken(bundle1WriterAdder.getEmail(), password); + // Verify the user has this feature on the bundle in item 1 + getClient(bundle1WriterAdderToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/bundles/" + bundle1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + } + + @Test + public void testCanCreateBundleAdmin() throws Exception { + testAdminsHavePermissionsItem("canCreateBundle"); + } + + @Test + public void testCanCreateBundleWriter() throws Exception { + String communityAWriterToken = getAuthToken(communityAWriter.getEmail(), password); + String collectionXWriterToken = getAuthToken(collectionXWriter.getEmail(), password); + String item1WriterToken = getAuthToken(item1Writer.getEmail(), password); + final String feature = "canCreateBundle"; + + // Verify community A write doesn’t have this feature on item 1 + getClient(communityAWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify collection X write doesn’t have this feature on item 1 + getClient(collectionXWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Verify item 1 write doesn’t have this feature on item 1 + getClient(item1WriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").doesNotExist()); + + // Create a new user, grant ADD and WRITE permissions on item 1 to this user + context.turnOffAuthorisationSystem(); + EPerson item1AdderWriter = EPersonBuilder.createEPerson(context) + .withNameInMetadata("Jhon", "Brown") + .withEmail("item1AdderWriter@my.edu") + .withPassword(password) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.ADD) + .withUser(item1AdderWriter) + .build(); + ResourcePolicyBuilder.createResourcePolicy(context) + .withDspaceObject(item1) + .withAction(Constants.WRITE) + .withUser(item1AdderWriter) + .build(); + context.restoreAuthSystemState(); + String item1AdderWriterToken = getAuthToken(item1AdderWriter.getEmail(), password); + // Verify the user has this feature on item 1 + getClient(item1AdderWriterToken).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" + + "http://localhost/api/core/items/" + item1.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='" + + feature + "')]").exists()); + } } \ No newline at end of file