Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

authorize-check for xlscollectionCrosswalk #432

Open
wants to merge 1 commit into
base: main-cris
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
implement authorized check for xlscollectionCrosswalk
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)
#422
floriangantner committed Feb 28, 2024
commit ea733c12878ae5f22cfb589fcaea56b1af79a4ac
Original file line number Diff line number Diff line change
@@ -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;
@@ -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;

/**
@@ -52,6 +57,9 @@
@Autowired
private BulkImportWorkbookBuilder bulkImportWorkbookBuilder;

@Autowired
private GroupService groupService;

@Override
public boolean canDisseminate(Context context, DSpaceObject dso) {
return dso.getType() == Constants.COLLECTION;
@@ -71,6 +79,16 @@
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 {
@@ -79,6 +97,10 @@
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);
@@ -133,4 +155,28 @@
return collection;
}

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

Check warning on line 161 in dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCollectionCrosswalk.java

Codecov / codecov/patch

dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCollectionCrosswalk.java#L161

Added line #L161 was not covered by tests
}

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

Check warning on line 166 in dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCollectionCrosswalk.java

Codecov / codecov/patch

dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCollectionCrosswalk.java#L166

Added line #L166 was not covered by tests
}

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);

Check warning on line 178 in dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCollectionCrosswalk.java

Codecov / codecov/patch

dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCollectionCrosswalk.java#L177-L178

Added lines #L177 - L178 were not covered by tests
}
}

}
Original file line number Diff line number Diff line change
@@ -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;
@@ -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";
@@ -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();
@@ -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 {

9 changes: 8 additions & 1 deletion dspace/config/spring/api/crosswalks.xml
Original file line number Diff line number Diff line change
@@ -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"/>