Skip to content

Commit

Permalink
Harvester / Local folder / Allow known scripts.
Browse files Browse the repository at this point in the history
  • Loading branch information
fxprunayre authored and cmangeat committed Jan 24, 2023
1 parent 7c7d166 commit ac21994
Showing 1 changed file with 54 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.fao.geonet.ApplicationContextHolder;
import org.fao.geonet.Logger;
import org.fao.geonet.domain.AbstractMetadata;
import org.fao.geonet.domain.ISODate;
import org.fao.geonet.domain.Metadata;
import org.fao.geonet.domain.MetadataType;
import org.fao.geonet.kernel.GeonetworkDataDirectory;
import org.fao.geonet.kernel.UpdateDatestamp;
import org.fao.geonet.kernel.harvest.BaseAligner;
import org.fao.geonet.kernel.harvest.harvester.AbstractHarvester;
Expand All @@ -54,6 +56,7 @@
import com.google.common.collect.Sets;

import java.util.*;
import java.util.stream.Collectors;

/**
* Harvester for local filesystem.
Expand Down Expand Up @@ -235,19 +238,56 @@ private void runBeforeScript() throws IOException, InterruptedException {
return;
}

throw new InterruptedException("Script option is currently disabled.");
// TODO: Script MUST be limited to well known ones added by a
// catalog admin in the data directory. To be improved
// log.info("Running the before script: " + params.beforeScript);
// List<String> args = new ArrayList<String>(Arrays.asList(params.beforeScript.split(" ")));
// Process process = new ProcessBuilder(args).
// redirectError(ProcessBuilder.Redirect.INHERIT).
// redirectOutput(ProcessBuilder.Redirect.INHERIT).
// start();
// int result = process.waitFor();
// if ( result != 0 ) {
// log.warning("The beforeScript failed with exit value=" + Integer.toString(result));
// throw new RuntimeException("The beforeScript returned an error: " + Integer.toString(result));
// }
// Script MUST be limited to well known ones added by a
// catalog admin in the data directory.
log.info("Checking script: " + params.beforeScript);
List<String> args = new ArrayList<String>(Arrays.asList(params.beforeScript.split(" ")));
if (isScriptAllowed(args)) {
log.info("Running script: " + params.beforeScript);
Process process = new ProcessBuilder(args).
redirectError(ProcessBuilder.Redirect.INHERIT).
redirectOutput(ProcessBuilder.Redirect.INHERIT).
start();
int result = process.waitFor();
if (result != 0) {
log.warning("The beforeScript failed with exit value=" + Integer.toString(result));
throw new RuntimeException("The beforeScript returned an error: " + Integer.toString(result));
}
} else {
throw new RuntimeException(String.format(
"Script %s is not allowed. Only script in the data directory can be triggered.",
params.beforeScript));
}
}

private boolean isScriptAllowed(List<String> args) {
String scriptFile = args.get(0);
if(scriptFile == null) {
log.warning("The beforeScript can't be null.");
return false;
}
if(scriptFile.contains("..")) {
log.warning("The beforeScript can't contains '..'.");
return false;
}

GeonetworkDataDirectory dataDirectory = ApplicationContextHolder.get().getBean(GeonetworkDataDirectory.class);
Path scriptPath = dataDirectory.getConfigDir().resolve(scriptFile);
if(!Files.exists(scriptPath)) {
log.warning("The beforeScript MUST exists.");
return false;
} else {
args.set(0, scriptPath.toString());
}

List<String> argsWithSemiColon = args
.stream()
.filter(a -> a.contains(";"))
.collect(Collectors.toList());
if (argsWithSemiColon.size() > 0) {
log.warning("The beforeScript can't contains ';'. Only one script can be triggered.");
return false;
}
return true;
}
}

0 comments on commit ac21994

Please sign in to comment.