mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-15 14:03:17 +00:00
84100: Admin only files rights issue IT
This commit is contained in:
@@ -1072,7 +1072,7 @@ prevent the generation of resource policy entry values with null dspace_object a
|
||||
private boolean isNotAlreadyACustomRPOfThisTypeOnDSO(Context context, DSpaceObject dso) throws SQLException {
|
||||
List<ResourcePolicy> readRPs = resourcePolicyService.find(context, dso, Constants.READ);
|
||||
for (ResourcePolicy readRP : readRPs) {
|
||||
if (readRP.getRpType().equals(ResourcePolicy.TYPE_CUSTOM)) {
|
||||
if (readRP.getRpType() != null && readRP.getRpType().equals(ResourcePolicy.TYPE_CUSTOM)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -43,12 +43,16 @@ import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.dspace.app.rest.matcher.CollectionMatcher;
|
||||
import org.dspace.app.rest.matcher.ItemMatcher;
|
||||
import org.dspace.app.rest.matcher.MetadataMatcher;
|
||||
import org.dspace.app.rest.matcher.ResourcePolicyMatcher;
|
||||
import org.dspace.app.rest.matcher.WorkspaceItemMatcher;
|
||||
import org.dspace.app.rest.model.patch.AddOperation;
|
||||
import org.dspace.app.rest.model.patch.Operation;
|
||||
import org.dspace.app.rest.model.patch.RemoveOperation;
|
||||
import org.dspace.app.rest.model.patch.ReplaceOperation;
|
||||
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.builder.BitstreamBuilder;
|
||||
import org.dspace.builder.CollectionBuilder;
|
||||
import org.dspace.builder.CommunityBuilder;
|
||||
@@ -67,9 +71,11 @@ import org.dspace.content.Item;
|
||||
import org.dspace.content.Relationship;
|
||||
import org.dspace.content.RelationshipType;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
@@ -88,6 +94,10 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
||||
@Autowired
|
||||
private ConfigurationService configurationService;
|
||||
|
||||
private GroupService groupService;
|
||||
|
||||
private ResourcePolicyService resourcePolicyService;
|
||||
|
||||
private Group embargoedGroups;
|
||||
private Group embargoedGroup1;
|
||||
private Group embargoedGroup2;
|
||||
@@ -98,6 +108,8 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
context.turnOffAuthorisationSystem();
|
||||
this.groupService = EPersonServiceFactory.getInstance().getGroupService();
|
||||
this.resourcePolicyService = AuthorizeServiceFactory.getInstance().getResourcePolicyService();
|
||||
|
||||
embargoedGroups = GroupBuilder.createGroup(context)
|
||||
.withName("Embargoed Groups")
|
||||
@@ -5299,4 +5311,232 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchUploadAddAdminRPInstallAndVerifyOnlyAdminCanView() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
Community community = CommunityBuilder.createCommunity(context).withName("Com").build();
|
||||
Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build();
|
||||
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
|
||||
WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
|
||||
.withSubmitter(eperson)
|
||||
.withTitle(
|
||||
"Test Item patchUploadAddAdminRPInstallAndVerifyOnlyAdminCanView")
|
||||
.withIssueDate("2019-03-06")
|
||||
.withFulltext("upload2.pdf", "/local/path/simple-article.pdf", pdf)
|
||||
.build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// auth
|
||||
String epersonToken = getAuthToken(eperson.getEmail(), password);
|
||||
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// prepare patch body
|
||||
Map<String, String> accessCondition = new HashMap<>();
|
||||
accessCondition.put("name", "administrator");
|
||||
List<Operation> ops = new ArrayList<>();
|
||||
ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition));
|
||||
String patchBody = getPatchContent(ops);
|
||||
|
||||
// submit patch and verify response
|
||||
getClient(epersonToken)
|
||||
.perform(
|
||||
patch("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.content(patchBody)
|
||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON)
|
||||
)
|
||||
.andExpect(status().isOk());
|
||||
|
||||
Bitstream bitstream = wItem.getItem().getBundles().get(0).getBitstreams().get(0);
|
||||
Group adminGroup = groupService.findByName(context, Group.ADMIN);
|
||||
|
||||
// verify that bitstream of workspace item has this admin RP
|
||||
getClient(adminToken).perform(get("/api/authz/resourcepolicies/search/resource")
|
||||
.param("uuid", bitstream.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.hasItems(
|
||||
ResourcePolicyMatcher.matchResourcePolicyProperties(adminGroup, null, bitstream,
|
||||
ResourcePolicy.TYPE_CUSTOM, Constants.READ, "administrator")
|
||||
)));
|
||||
|
||||
// submit the workspaceitem to complete the deposit (as there is no workflow configured)
|
||||
getClient(epersonToken)
|
||||
.perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems")
|
||||
.content("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.contentType(textUriContentType))
|
||||
.andExpect(status().isCreated());
|
||||
|
||||
Group anonGroup = groupService.findByName(context, Group.ANONYMOUS);
|
||||
|
||||
// verify that bitstream of workspace item still has this admin RP and no Anon READ inherited policy
|
||||
getClient(adminToken).perform(get("/api/authz/resourcepolicies/search/resource")
|
||||
.param("uuid", bitstream.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.hasItems(
|
||||
ResourcePolicyMatcher.matchResourcePolicyProperties(adminGroup, null, bitstream,
|
||||
ResourcePolicy.TYPE_CUSTOM, Constants.READ, "administrator")
|
||||
)))
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.not(Matchers.hasItems(
|
||||
ResourcePolicyMatcher
|
||||
.matchResourcePolicyProperties(anonGroup, null, bitstream, null, Constants.READ,
|
||||
null)
|
||||
))));
|
||||
|
||||
// Bitstream should NOT be accessible to anon or eperson user, only to admin
|
||||
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||
.andExpect(status().isUnauthorized());
|
||||
getClient(epersonToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||
.andExpect(status().isForbidden());
|
||||
getClient(adminToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchUploadAddOpenAccessRPInstallAndVerifyAnonCanView() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
Community community = CommunityBuilder.createCommunity(context).withName("Com").build();
|
||||
Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build();
|
||||
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
|
||||
WorkspaceItem wItem =
|
||||
WorkspaceItemBuilder.createWorkspaceItem(context, collection).withSubmitter(eperson)
|
||||
.withTitle("Test Item patchUploadAddOpenAccessRPInstallAndVerifyOnlyAdminCanView")
|
||||
.withIssueDate("2019-03-06")
|
||||
.withFulltext("upload2.pdf", "/local/path/simple-article.pdf", pdf)
|
||||
.build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// auth
|
||||
String epersonToken = getAuthToken(eperson.getEmail(), password);
|
||||
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// prepare patch body
|
||||
Map<String, String> accessCondition = new HashMap<>();
|
||||
accessCondition.put("name", "openaccess");
|
||||
List<Operation> ops = new ArrayList<>();
|
||||
ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition));
|
||||
String patchBody = getPatchContent(ops);
|
||||
|
||||
// submit patch and verify response
|
||||
getClient(epersonToken)
|
||||
.perform(
|
||||
patch("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.content(patchBody)
|
||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON)
|
||||
)
|
||||
.andExpect(status().isOk());
|
||||
|
||||
Bitstream bitstream = wItem.getItem().getBundles().get(0).getBitstreams().get(0);
|
||||
|
||||
// verify that bitstream of workspace item has this open access RP
|
||||
getClient(adminToken).perform(get("/api/authz/resourcepolicies/search/resource")
|
||||
.param("uuid", bitstream.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.hasItems(
|
||||
ResourcePolicyMatcher.matchResourcePolicyProperties(anonymousGroup, null, bitstream,
|
||||
ResourcePolicy.TYPE_CUSTOM, Constants.READ, "openaccess")
|
||||
)));
|
||||
|
||||
// submit the workspaceitem to complete the deposit (as there is no workflow configured)
|
||||
getClient(epersonToken)
|
||||
.perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems")
|
||||
.content("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.contentType(textUriContentType))
|
||||
.andExpect(status().isCreated());
|
||||
|
||||
// verify that bitstream of workspace item still has this open access RP
|
||||
getClient(adminToken).perform(get("/api/authz/resourcepolicies/search/resource")
|
||||
.param("uuid", bitstream.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.hasItems(
|
||||
ResourcePolicyMatcher.matchResourcePolicyProperties(anonymousGroup, null, bitstream,
|
||||
ResourcePolicy.TYPE_CUSTOM, Constants.READ, "openaccess")
|
||||
)));
|
||||
|
||||
// Bitstream should be accessible to anon
|
||||
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchUploadAddAdminThenOpenAccessRPInstallAndVerifyAnonCanView() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
Community community = CommunityBuilder.createCommunity(context).withName("Com").build();
|
||||
Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build();
|
||||
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
|
||||
WorkspaceItem wItem =
|
||||
WorkspaceItemBuilder.createWorkspaceItem(context, collection).withSubmitter(eperson)
|
||||
.withTitle("Test Item patchUploadAddOpenAccessRPInstallAndVerifyOnlyAdminCanView")
|
||||
.withIssueDate("2019-03-06")
|
||||
.withFulltext("upload2.pdf", "/local/path/simple-article.pdf", pdf)
|
||||
.build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// auth
|
||||
String epersonToken = getAuthToken(eperson.getEmail(), password);
|
||||
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// prepare patch body
|
||||
Map<String, String> accessCondition = new HashMap<>();
|
||||
accessCondition.put("name", "administrator");
|
||||
List<Operation> ops = new ArrayList<>();
|
||||
ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition));
|
||||
String patchBody = getPatchContent(ops);
|
||||
|
||||
// submit patch and verify response
|
||||
getClient(epersonToken)
|
||||
.perform(
|
||||
patch("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.content(patchBody)
|
||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON)
|
||||
)
|
||||
.andExpect(status().isOk());
|
||||
|
||||
Bitstream bitstream = wItem.getItem().getBundles().get(0).getBitstreams().get(0);
|
||||
Group adminGroup = groupService.findByName(context, Group.ADMIN);
|
||||
|
||||
// verify that bitstream of workspace item has this admin RP
|
||||
getClient(adminToken).perform(get("/api/authz/resourcepolicies/search/resource")
|
||||
.param("uuid", bitstream.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.hasItems(
|
||||
ResourcePolicyMatcher.matchResourcePolicyProperties(adminGroup, null, bitstream,
|
||||
ResourcePolicy.TYPE_CUSTOM, Constants.READ, "administrator")
|
||||
)));
|
||||
|
||||
// prepare patch body
|
||||
Map<String, String> accessCondition2 = new HashMap<>();
|
||||
accessCondition2.put("name", "openaccess");
|
||||
List<Operation> ops2 = new ArrayList<>();
|
||||
ops2.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition2));
|
||||
String patchBody2 = getPatchContent(ops2);
|
||||
|
||||
// submit patch and verify response
|
||||
getClient(epersonToken)
|
||||
.perform(
|
||||
patch("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.content(patchBody2)
|
||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON)
|
||||
)
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// verify that bitstream of workspace item has this open access RP
|
||||
getClient(adminToken).perform(get("/api/authz/resourcepolicies/search/resource")
|
||||
.param("uuid", bitstream.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.hasItems(
|
||||
ResourcePolicyMatcher.matchResourcePolicyProperties(anonymousGroup, null, bitstream,
|
||||
ResourcePolicy.TYPE_CUSTOM, Constants.READ, "openaccess")
|
||||
)));
|
||||
|
||||
// submit the workspaceitem to complete the deposit (as there is no workflow configured)
|
||||
getClient(epersonToken)
|
||||
.perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems")
|
||||
.content("/api/submission/workspaceitems/" + wItem.getID())
|
||||
.contentType(textUriContentType))
|
||||
.andExpect(status().isCreated());
|
||||
|
||||
// Bitstream should be accessible to anon
|
||||
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -14,8 +14,13 @@ import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.hamcrest.Matcher;
|
||||
|
||||
/**
|
||||
@@ -29,6 +34,27 @@ public class ResourcePolicyMatcher {
|
||||
private ResourcePolicyMatcher() {
|
||||
}
|
||||
|
||||
public static Matcher<? super Object> matchResourcePolicyProperties(@Nullable Group group,
|
||||
@Nullable EPerson eperson, DSpaceObject dso, @Nullable String rpType, int action, @Nullable String name) {
|
||||
return allOf(
|
||||
hasJsonPath("$.name", is(name)),
|
||||
hasJsonPath("$.action", is(Constants.actionText[action])),
|
||||
rpType != null ?
|
||||
hasJsonPath("$.policyType", is(rpType)) :
|
||||
hasNoJsonPath("$.policyType"),
|
||||
hasJsonPath("$.type", is("resourcepolicy")),
|
||||
hasJsonPath("$._embedded.resource.id", is(dso.getID().toString())),
|
||||
eperson != null ?
|
||||
hasJsonPath("$._embedded.eperson.id",
|
||||
is(eperson.getID().toString())) :
|
||||
hasJsonPath("$._embedded.eperson", nullValue()),
|
||||
group != null ?
|
||||
hasJsonPath("$._embedded.group.id",
|
||||
is(group.getID().toString())) :
|
||||
hasJsonPath("$._embedded.group", nullValue())
|
||||
);
|
||||
}
|
||||
|
||||
public static Matcher<? super Object> matchResourcePolicy(ResourcePolicy resourcePolicy) {
|
||||
return allOf(hasJsonPath("$.id", is(resourcePolicy.getID())),
|
||||
hasJsonPath("$.name", is(resourcePolicy.getRpName())),
|
||||
|
Reference in New Issue
Block a user