Skip to content

Commit

Permalink
implement authorized check for xlscollectionCrosswalk
Browse files Browse the repository at this point in the history
implement interface method for fine granular check to export these issues only to Administrator group. Configured crosswalk to stay to the current behaviour (export to all)
4Science#422
  • Loading branch information
floriangantner committed Feb 28, 2024
1 parent 029adbc commit ea733c1
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.dspace.app.bulkedit.BulkImport;
Expand All @@ -31,6 +33,9 @@
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.springframework.beans.factory.annotation.Autowired;

/**
Expand All @@ -52,6 +57,9 @@ public class XlsCollectionCrosswalk implements ItemExportCrosswalk {
@Autowired
private BulkImportWorkbookBuilder bulkImportWorkbookBuilder;

@Autowired
private GroupService groupService;

@Override
public boolean canDisseminate(Context context, DSpaceObject dso) {
return dso.getType() == Constants.COLLECTION;
Expand All @@ -71,6 +79,16 @@ public CrosswalkMode getCrosswalkMode() {
return CrosswalkMode.MULTIPLE;
}

private List<String> allowedGroups;

public List<String> getAllowedGroups() {
return allowedGroups;
}

public void setAllowedGroups(List<String> allowedGroups) {
this.allowedGroups = allowedGroups;
}

@Override
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throws CrosswalkException, IOException, SQLException, AuthorizeException {
Expand All @@ -79,6 +97,10 @@ public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throw new CrosswalkObjectNotSupported("Can only crosswalk a Collection");
}

if (!isAuthorized(context)) {
throw new AuthorizeException("The current user is not allowed to perform a xls collection export");
}

Collection collection = (Collection) dso;

Iterator<Item> itemIterator = itemService.findByCollection(context, collection);
Expand Down Expand Up @@ -133,4 +155,28 @@ private Collection findCollection(Context context, Item item) throws SQLExceptio
return collection;
}

@Override
public boolean isAuthorized(Context context) {
if (CollectionUtils.isEmpty(getAllowedGroups())) {
return true;
}

EPerson ePerson = context.getCurrentUser();
if (ePerson == null) {
return getAllowedGroups().contains(Group.ANONYMOUS);
}

return getAllowedGroups().stream()
.anyMatch(groupName -> isMemberOfGroupNamed(context, ePerson, groupName));
}

private boolean isMemberOfGroupNamed(Context context, EPerson ePerson, String groupName) {
try {
Group group = groupService.findByName(context, groupName);
return groupService.isMember(context, ePerson, group);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Constants;
import org.dspace.core.CrisConstants;
import org.dspace.eperson.Group;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.utils.DSpace;
Expand All @@ -86,6 +89,8 @@ public class XlsCollectionCrosswalkIT extends AbstractIntegrationTestWithDatabas

private ConfigurationService configurationService;

private GroupService groupService;

private Community community;

private static final String BITSTREAM_URL_FORMAT = "%s/api/core/bitstreams/%s/content";
Expand All @@ -103,6 +108,9 @@ public void setup() throws SQLException, AuthorizeException {
.getServicesByType(BulkImportWorkbookBuilderImpl.class).get(0);

configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();

groupService = EPersonServiceFactory.getInstance().getGroupService();

context.turnOffAuthorisationSystem();
community = createCommunity(context).build();
Expand Down Expand Up @@ -332,6 +340,109 @@ public void testCollectionDisseminateWithEmptyCollection() throws Exception {
assertThat(getRowValues(mainSheet.getRow(0), mainSheetHeader.length), contains(mainSheetHeader));
}

@Test
public void testCollectionIsNotAuthorized() throws Exception {

context.turnOffAuthorisationSystem();
Collection collection = createCollection(context, community)
.withAdminGroup(eperson)
.build();
context.restoreAuthSystemState();

List<String> groups = new ArrayList<>();
groups.add("Test1");
xlsCollectionCrosswalk.setAllowedGroups(groups);
context.commit();

ByteArrayOutputStream baos = new ByteArrayOutputStream();

assertThat(xlsCollectionCrosswalk.isAuthorized(context), equalTo(false));

AuthorizeException authorizeException = Assert.assertThrows(AuthorizeException.class,
() -> xlsCollectionCrosswalk.disseminate(context, collection, baos));

assertThat(authorizeException.getMessage(),
is("The current user is not allowed to perform a xls collection export"));


}

@Test
public void testCollectionIsAuthorizedEmptyCollection() throws Exception {

context.turnOffAuthorisationSystem();
Collection collection = createCollection(context, community)
.withAdminGroup(eperson)
.build();

Group group = groupService.create(context);
groupService.setName(group, "Test");
groupService.addMember(context, group, eperson);
context.commit();

context.restoreAuthSystemState();

ByteArrayOutputStream baos = new ByteArrayOutputStream();

List<String> groups = new ArrayList<>();
groups.add("Test");

xlsCollectionCrosswalk.setAllowedGroups(groups);

assertThat(xlsCollectionCrosswalk.isAuthorized(context), equalTo(true));

xlsCollectionCrosswalk.disseminate(context, collection, baos);

Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(baos.toByteArray()));
assertThat(workbook.getNumberOfSheets(), equalTo(2));

Sheet mainSheet = workbook.getSheetAt(0);
String[] mainSheetHeader = { "ID", "DISCOVERABLE", "dc.contributor.author", "dc.title", "dc.title.alternative",
"dc.date.issued", "dc.publisher", "dc.identifier.citation", "dc.relation.ispartofseries",
"dc.identifier.doi", "dc.identifier.scopus", "dc.identifier.isi", "dc.identifier.adsbibcode",
"dc.identifier.pmid", "dc.identifier.arxiv", "dc.identifier.issn", "dc.identifier.other",
"dc.identifier.ismn", "dc.identifier.govdoc", "dc.identifier.uri", "dc.identifier.isbn",
"dc.type", "dc.language.iso", "dc.subject", "dc.description.abstract", "dc.description.sponsorship",
"dc.description" };
assertThat(mainSheet.getPhysicalNumberOfRows(), equalTo(1));
assertThat(getRowValues(mainSheet.getRow(0), mainSheetHeader.length), contains(mainSheetHeader));
}

@Test
public void testCollectionIsAuthorizedAnonymousEmptyCollection() throws Exception {

context.turnOffAuthorisationSystem();
Collection collection = createCollection(context, community)
.withAdminGroup(eperson)
.build();
context.restoreAuthSystemState();

ByteArrayOutputStream baos = new ByteArrayOutputStream();

List<String> groups = new ArrayList<>();
groups.add("Anonymous");

xlsCollectionCrosswalk.setAllowedGroups(groups);

assertThat(xlsCollectionCrosswalk.isAuthorized(context), equalTo(true));

xlsCollectionCrosswalk.disseminate(context, collection, baos);

Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(baos.toByteArray()));
assertThat(workbook.getNumberOfSheets(), equalTo(2));

Sheet mainSheet = workbook.getSheetAt(0);
String[] mainSheetHeader = { "ID", "DISCOVERABLE", "dc.contributor.author", "dc.title", "dc.title.alternative",
"dc.date.issued", "dc.publisher", "dc.identifier.citation", "dc.relation.ispartofseries",
"dc.identifier.doi", "dc.identifier.scopus", "dc.identifier.isi", "dc.identifier.adsbibcode",
"dc.identifier.pmid", "dc.identifier.arxiv", "dc.identifier.issn", "dc.identifier.other",
"dc.identifier.ismn", "dc.identifier.govdoc", "dc.identifier.uri", "dc.identifier.isbn",
"dc.type", "dc.language.iso", "dc.subject", "dc.description.abstract", "dc.description.sponsorship",
"dc.description" };
assertThat(mainSheet.getPhysicalNumberOfRows(), equalTo(1));
assertThat(getRowValues(mainSheet.getRow(0), mainSheetHeader.length), contains(mainSheetHeader));
}

@Test
public void testCollectionDisseminateWithMockSubmissionFormConfiguration() throws Exception {

Expand Down
9 changes: 8 additions & 1 deletion dspace/config/spring/api/crosswalks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,14 @@
<property name="crosswalkMode" value="#{T(org.dspace.content.crosswalk.CrosswalkMode).MULTIPLE}"/>
</bean>

<bean class="org.dspace.content.integration.crosswalks.XlsCollectionCrosswalk" id="xlsCrosswalkCollection"/>
<bean class="org.dspace.content.integration.crosswalks.XlsCollectionCrosswalk" id="xlsCrosswalkCollection">
<property name="allowedGroups">
<list>
<value>Administrator</value>
<value>Anonymous</value>
</list>
</property>
</bean>

<bean class="org.dspace.content.integration.crosswalks.ZipItemExportCrosswalk" id="zipCrosswalk">
<property name="zipName" value="items.zip"/>
Expand Down

0 comments on commit ea733c1

Please sign in to comment.