Skip to content

Commit

Permalink
[DSC-737] Restrict export formats by groups and Bulk Item export with…
Browse files Browse the repository at this point in the history
… metadata and bitstream
  • Loading branch information
mohamed eskander committed Nov 29, 2023
1 parent a6c4932 commit e87c9f8
Show file tree
Hide file tree
Showing 10 changed files with 744 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,13 @@ public Bitstream getBitstreamByName(Item item, String bundleName, String bitstre
return null;
}

@Override
public List<Bitstream> getBitstreamByBundleName(Item item, String bundleName) throws SQLException {
return itemService.getBundles(item, bundleName).stream()
.flatMap(bundle -> bundle.getBitstreams().stream())
.collect(Collectors.toList());
}

@Override
public Bitstream getFirstBitstream(Item item, String bundleName) throws SQLException {
List<Bundle> bundles = itemService.getBundles(item, bundleName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ public class METSDisseminationCrosswalk
private static final String schemaLocation =
METS_NS.getURI() + " " + METS_XSD;

private String metsPackagerPlugin;

public METSDisseminationCrosswalk() {
this.metsPackagerPlugin = METS_PACKAGER_PLUGIN;
}

public METSDisseminationCrosswalk(String metsPackagerPlugin) {
this.metsPackagerPlugin = metsPackagerPlugin;
}

@Override
public Namespace[] getNamespaces() {
return (Namespace[]) ArrayUtils.clone(namespaces);
Expand Down Expand Up @@ -103,10 +113,10 @@ public Element disseminateElement(Context context, DSpaceObject dso)

PackageDisseminator dip = (PackageDisseminator)
CoreServiceFactory.getInstance().getPluginService()
.getNamedPlugin(PackageDisseminator.class, METS_PACKAGER_PLUGIN);
.getNamedPlugin(PackageDisseminator.class, metsPackagerPlugin);
if (dip == null) {
throw new CrosswalkInternalException(
"Cannot find a disseminate plugin for package=" + METS_PACKAGER_PLUGIN);
"Cannot find a disseminate plugin for package=" + metsPackagerPlugin);
}

try {
Expand All @@ -117,11 +127,16 @@ public Element disseminateElement(Context context, DSpaceObject dso)
// Create a temporary file to disseminate into
ConfigurationService configurationService
= DSpaceServicesFactory.getInstance().getConfigurationService();
String tempDirectory = (configurationService.hasProperty("upload.temp.dir"))
String tempDirectoryPath = (configurationService.hasProperty("upload.temp.dir"))
? configurationService.getProperty("upload.temp.dir")
: System.getProperty("java.io.tmpdir");

File tempFile = File.createTempFile("METSDissemination" + dso.hashCode(), null, new File(tempDirectory));
File tempDirectory = new File(tempDirectoryPath);
if (!tempDirectory.exists()) {
tempDirectory.mkdirs();
}

File tempFile = File.createTempFile("METSDissemination" + dso.hashCode(), null, tempDirectory);
tempFile.deleteOnExit();

// Disseminate METS to temp file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import org.dspace.content.crosswalk.CrosswalkMode;
import org.dspace.content.crosswalk.StreamDisseminationCrosswalk;
import org.dspace.core.Context;

/**
* Implementation of {@link StreamDisseminationCrosswalk} related to item
Expand Down Expand Up @@ -40,4 +41,8 @@ public default Optional<String> getEntityType() {
public default CrosswalkMode getCrosswalkMode() {
return CrosswalkMode.SINGLE;
}

public default boolean isAuthorized(Context context) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* 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.content.integration.crosswalks;

import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import javax.annotation.PostConstruct;

import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject;
import org.dspace.content.crosswalk.CrosswalkException;
import org.dspace.content.crosswalk.METSDisseminationCrosswalk;
import org.dspace.content.crosswalk.StreamDisseminationCrosswalk;
import org.dspace.core.Context;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

/**
* Implementation of {@link StreamDisseminationCrosswalk} that produces a METS
* manifest for the DSpace item as a metadata description, using
* {@link METSDisseminationCrosswalk}.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
*
*/
public class METSStreamDisseminationCrosswalk implements StreamDisseminationCrosswalk {

private METSDisseminationCrosswalk metsDisseminationCrosswalk;

@PostConstruct
public void setup() {
metsDisseminationCrosswalk = new METSDisseminationCrosswalk("AIP");
}

@Override
public boolean canDisseminate(Context context, DSpaceObject dso) {
return metsDisseminationCrosswalk.canDisseminate(dso);
}

@Override
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throws CrosswalkException, IOException, SQLException, AuthorizeException {

Element element = metsDisseminationCrosswalk.disseminateElement(context, dso);

XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
xmlOutputter.output(element, out);

}

@Override
public String getMIMEType() {
return "application/xml";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.configuration.DiscoveryConfigurationUtilsService;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.dspace.util.UUIDUtils;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -94,6 +97,9 @@ public class ReferCrosswalk implements ItemExportCrosswalk {
@Autowired
private MetadataSecurityService metadataSecurityService;

@Autowired
private GroupService groupService;

private Converter<String, String> converter;

private Consumer<List<String>> linesPostProcessor;
Expand All @@ -116,6 +122,8 @@ public class ReferCrosswalk implements ItemExportCrosswalk {

private CrosswalkMode crosswalkMode;

private List<String> allowedGroups;

@PostConstruct
private void postConstruct() throws IOException {
String parent = configurationService.getProperty("dspace.dir") + File.separator + "config" + File.separator;
Expand All @@ -128,6 +136,21 @@ private void postConstruct() throws IOException {
}
}

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

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

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

@Override
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throws CrosswalkException, IOException, SQLException, AuthorizeException {
Expand All @@ -136,6 +159,10 @@ public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throw new CrosswalkObjectNotSupported("Can only crosswalk an Item with the configured type: " + entityType);
}

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

List<String> lines = getItemLines(context, dso, true);

if (linesPostProcessor != null) {
Expand All @@ -154,6 +181,10 @@ public void disseminate(Context context, Iterator<? extends DSpaceObject> dsoIte
throw new UnsupportedOperationException("No template defined for multiple items");
}

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

List<String> lines = new ArrayList<String>();

for (TemplateLine line : multipleItemsTemplateLines) {
Expand Down Expand Up @@ -466,6 +497,15 @@ private boolean hasExpectedEntityType(Item item) {
return Objects.equals(itemEntityType, entityType);
}

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

public void setConverter(Converter<String, String> converter) {
this.converter = converter;
}
Expand Down Expand Up @@ -525,4 +565,12 @@ public void setPubliclyReadable(boolean isPubliclyReadable) {
this.publiclyReadable = isPubliclyReadable;
}

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

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

}
Loading

0 comments on commit e87c9f8

Please sign in to comment.