Skip to content

Commit

Permalink
Merged dspace-cris-2023_02_x into task/dspace-cris-2023_02_x/DSC-1709…
Browse files Browse the repository at this point in the history
…_CC-license-step-doesn't-work
  • Loading branch information
atarix83 committed Jul 3, 2024
2 parents 202762f + deba0f2 commit ec44369
Show file tree
Hide file tree
Showing 26 changed files with 769 additions and 200 deletions.
14 changes: 10 additions & 4 deletions dspace-api/src/main/java/org/dspace/app/bulkedit/BulkImport.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
import org.dspace.app.bulkimport.model.ImportAction;
import org.dspace.app.bulkimport.model.MetadataGroup;
import org.dspace.app.bulkimport.model.UploadDetails;
import org.dspace.app.bulkimport.util.BulkImportFileUtil;
import org.dspace.app.bulkimport.util.ImportFileUtil;
import org.dspace.app.util.DCInputsReader;
import org.dspace.app.util.DCInputsReaderException;
import org.dspace.authority.service.ItemSearchService;
Expand Down Expand Up @@ -210,7 +210,7 @@ public class BulkImport extends DSpaceRunnable<BulkImportScriptConfiguration<Bul

private Context context;

private BulkImportFileUtil bulkImportFileUtil;
private ImportFileUtil importFileUtil;

private BundleService bundleService;

Expand Down Expand Up @@ -241,7 +241,9 @@ public void setup() throws ParseException {
this.workflowItemService = WorkflowServiceFactory.getInstance().getWorkflowItemService();
this.bulkImportTransformerService = new DSpace().getServiceManager().getServiceByName(
BulkImportTransformerService.class.getName(), BulkImportTransformerService.class);
this.bulkImportFileUtil = new BulkImportFileUtil(this.handler);
if (this.importFileUtil == null) {
this.importFileUtil = new ImportFileUtil(this.handler);
}
this.bundleService = ContentServiceFactory.getInstance().getBundleService();
this.bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
this.bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
Expand Down Expand Up @@ -1041,7 +1043,7 @@ private void createBitstream(Item item, UploadDetails uploadDetails) {

String filePath = uploadDetails.getFilePath();

Optional<InputStream> inputStream = bulkImportFileUtil.getInputStream(filePath);
Optional<InputStream> inputStream = importFileUtil.getInputStream(filePath);

if (inputStream.isEmpty()) {
handler.logError("Cannot create bitstream from file at path " + filePath);
Expand Down Expand Up @@ -1633,6 +1635,10 @@ private boolean isAppendModeDisabled() {
return !configurationService.getBooleanProperty("core.authorization.installitem.inheritance-read.append-mode");
}

public void setImportFileUtil(ImportFileUtil importFileUtil) {
this.importFileUtil = importFileUtil;
}

@Override
@SuppressWarnings("unchecked")
public BulkImportScriptConfiguration<BulkImport> getScriptConfiguration() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/**
* 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.bulkimport.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.scripts.handler.DSpaceRunnableHandler;
import org.dspace.services.factory.DSpaceServicesFactory;

/*
* @author Jurgen Mamani
*/
public class ImportFileUtil {

private static final Logger log = LogManager.getLogger(ImportFileUtil.class);

public static final String REMOTE = "REMOTE";

private static final String LOCAL = "LOCAL";

public static final String FTP = "FTP";

private static final String HTTP_PREFIX = "http:";

private static final String HTTPS_PREFIX = "https:";

private static final String LOCAL_PREFIX = "file:";

private static final String FTP_PREFIX = "ftp:";

private static final String UNKNOWN = "UNKNOWN";

/**
* This method check if the given {@param possibleChild} is contained in the specified
* {@param possibleParent}, i.e. it's a sub-path of it.
*
* @param possibleParent
* @param possibleChild
* @return true if sub-path, false otherwise.
*/
private static boolean isChild(File possibleParent, File possibleChild) {
File parent = possibleChild.getParentFile();
while (parent != null) {
if (parent.equals(possibleParent)) {
return true;
}
parent = parent.getParentFile();
}
return false;
}

private static String[] getAllowedIps() {
return DSpaceServicesFactory.getInstance()
.getConfigurationService()
.getArrayProperty("allowed.ips.import");
}

protected DSpaceRunnableHandler handler;

public ImportFileUtil() {}

public ImportFileUtil(DSpaceRunnableHandler handler) {
this.handler = handler;
}

public Optional<InputStream> getInputStream(String path) {
String fileLocationType = getFileLocationTypeByPath(path);

if (UNKNOWN.equals(fileLocationType)) {
logWarning("File path is of UNKNOWN type: [" + path + "]");
return Optional.empty();
}

return getInputStream(path, fileLocationType);
}

protected void logWarning(String message) {
log.warn(message);
if (handler != null) {
handler.logWarning(message);
}
}

private String getFileLocationTypeByPath(String path) {
if (StringUtils.isNotBlank(path)) {
if (path.startsWith(HTTP_PREFIX) || path.startsWith(HTTPS_PREFIX)) {
return REMOTE;
} else if (path.startsWith(LOCAL_PREFIX)) {
return LOCAL;
} else if (path.startsWith(FTP_PREFIX)) {
return FTP;
} else {
return UNKNOWN;
}
}

return UNKNOWN;
}

private Optional<InputStream> getInputStream(String path, String fileLocationType) {
try {
switch (fileLocationType) {
case REMOTE:
return getInputStreamOfRemoteFile(path);
case LOCAL:
return getInputStreamOfLocalFile(path);
case FTP:
return getInputStreamOfFtpFile(path);
default:
}
} catch (IOException e) {
logError(e.getMessage());
}

return Optional.empty();
}

private void logError(String message) {
log.error(message);
if (handler != null) {
handler.logError(message);
}
}

private Optional<InputStream> getInputStreamOfLocalFile(String path) throws IOException {
Path uploadPath = Paths.get(
DSpaceServicesFactory.getInstance()
.getConfigurationService()
.getProperty("uploads.local-folder")
);
File file = uploadPath.resolve(path.replace(LOCAL_PREFIX + "//", ""))
.toFile()
.getCanonicalFile();
File possibleParent = uploadPath.toFile().getCanonicalFile();
if (!isChild(possibleParent, file)) {
throw new IOException("Access to the specified file " + path + " is not allowed");
}
if (!file.exists()) {
throw new IOException("file " + path + " is not found");
}
return Optional.of(FileUtils.openInputStream(file));
}

private Optional<InputStream> getInputStreamOfRemoteFile(String path) throws IOException {
return Optional.of(new URL(path))
.filter(url -> Set.of(getAllowedIps()).contains(url.getHost()))
.map(this::openStream);
}

protected InputStream openStream(URL url) {
try {
return url.openStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private Optional<InputStream> getInputStreamOfFtpFile(String url) throws IOException {
URL urlObject = new URL(url);
URLConnection urlConnection = urlObject.openConnection();
return Optional.of(urlConnection.getInputStream());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -490,19 +490,26 @@ public void exportAsZip(Context context, Iterator<Item> items,

File wkDir = new File(workDir);
if (!wkDir.exists() && !wkDir.mkdirs()) {
logError("Unable to create working direcory");
logError("Unable to create working directory");
}

File dnDir = new File(destDirName);
if (!dnDir.exists() && !dnDir.mkdirs()) {
logError("Unable to create destination directory");
}

// export the items using normal export method
exportItem(context, items, workDir, seqStart, migrate, excludeBitstreams);
try {
// export the items using normal export method (this exports items to our workDir)
exportItem(context, items, workDir, seqStart, migrate, excludeBitstreams);

// now zip up the export directory created above
zip(workDir, destDirName + System.getProperty("file.separator") + zipFileName);
// now zip up the workDir directory created above
zip(workDir, destDirName + System.getProperty("file.separator") + zipFileName);
} finally {
// Cleanup workDir created above, if it still exists
if (wkDir.exists()) {
deleteDirectory(wkDir);
}
}
}

@Override
Expand Down
Loading

0 comments on commit ec44369

Please sign in to comment.