Skip to content

Commit 0ea913b

Browse files
committed
Support for webdav data file paths, better validation for server side file paths
1 parent 79a318e commit 0ea913b

1 file changed

Lines changed: 56 additions & 11 deletions

File tree

signalData/src/org/labkey/signaldata/pipeline/SignalDataImportTask.java

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import org.labkey.api.assay.AssayRunUploadContext;
99
import org.labkey.api.assay.AssayService;
1010
import org.labkey.api.assay.DefaultAssayRunCreator;
11+
import org.labkey.api.assay.transform.DataTransformService;
1112
import org.labkey.api.collections.CaseInsensitiveHashMap;
1213
import org.labkey.api.data.Container;
14+
import org.labkey.api.data.ContainerManager;
1315
import org.labkey.api.dataiterator.MapDataIterator;
1416
import org.labkey.api.exp.ExperimentException;
1517
import org.labkey.api.exp.api.ExpData;
@@ -36,6 +38,7 @@
3638
import org.labkey.vfs.FileLike;
3739
import org.labkey.vfs.FileSystemLike;
3840

41+
import java.io.File;
3942
import java.io.IOException;
4043
import java.io.InputStream;
4144
import java.net.URI;
@@ -128,24 +131,41 @@ public RecordedActionSet run()
128131
// If the value is just a filename (no directory separators), resolve it relative to
129132
// the metadata file's directory; otherwise treat it as a full server-side path
130133
String dataFileName = FileUtil.getFileName(Path.of(dataFilePath));
131-
FileLike sourceFile;
134+
FileLike sourceFile = null;
132135
if (dataFilePath.equals(dataFileName))
133136
{
134-
sourceFile = dataFile.getParent().resolveChild(dataFilePath);
137+
String sourcePath = support.getParameters().get(DataTransformService.ORIGINAL_SOURCE_PATH);
138+
if (StringUtils.isNotBlank(sourcePath))
139+
{
140+
FileLike originalSource = FileSystemLike.wrapFile(new File(sourcePath));
141+
sourceFile = originalSource.getParent().resolveChild(dataFilePath);
142+
}
135143
}
136144
else
137145
{
138-
Path resolvedPath = Path.of(dataFilePath).toAbsolutePath().normalize();
139-
if (!isUnderAnyPipelineRoot(resolvedPath))
146+
// check to see if it's a webdav url
147+
WebdavResource resource = WebdavService.get().lookup(dataFilePath);
148+
if (resource != null)
149+
{
150+
sourceFile = FileSystemLike.wrapFile(resource.getFile());
151+
}
152+
153+
// check to see if it's a server-side path
154+
if (sourceFile == null)
140155
{
141-
log.error("DataFile '{}' is not under a server-managed pipeline root", dataFilePath);
142-
row.remove(INPUT_DATA_FILE);
143-
continue;
156+
Path resolvedPath = Path.of(dataFilePath).toAbsolutePath().normalize();
157+
158+
if (!isUnderAnyPipelineRoot(resolvedPath))
159+
{
160+
log.error("DataFile '{}' is not under a server-managed pipeline root", dataFilePath);
161+
row.remove(INPUT_DATA_FILE);
162+
continue;
163+
}
164+
sourceFile = FileSystemLike.wrapFile(resolvedPath.toFile());
144165
}
145-
sourceFile = FileSystemLike.wrapFile(resolvedPath.toFile());
146166
}
147167

148-
if (!sourceFile.exists())
168+
if (sourceFile != null && !sourceFile.exists())
149169
{
150170
log.info("Data file not found: {}", sourceFile.getPath());
151171
row.remove(INPUT_DATA_FILE);
@@ -283,10 +303,35 @@ private FileLike getTargetFolder(Container container, Logger log) throws IOExcep
283303
return null;
284304
}
285305

306+
/**
307+
* Determine whether the given path falls under a pipeline root for some container, using the same semantics as
308+
* {@link PipelineService#findPipelineRoot(Container)} (which includes the default file-root fallback, not just
309+
* explicitly configured pipeline roots). First try to resolve the path directly to its owning container(s); if
310+
* that comes up empty (e.g. a container with a custom, non-default file root that the path-resolution logic does
311+
* not yet handle), fall back to scanning every container's pipeline root.
312+
*/
286313
private boolean isUnderAnyPipelineRoot(Path resolvedPath)
287314
{
288-
return PipelineService.get().getAllPipelineRoots().values().stream()
289-
.anyMatch(pipeRoot -> pipeRoot.isUnderRoot(resolvedPath));
315+
for (Container c : FileContentService.get().getContainersForFilePath(resolvedPath))
316+
{
317+
if (isUnderPipelineRoot(c, resolvedPath))
318+
return true;
319+
}
320+
321+
// Path could not be resolved to a container directly; fall back to scanning all containers
322+
for (Container c : ContainerManager.getAllChildren(ContainerManager.getRoot()))
323+
{
324+
if (isUnderPipelineRoot(c, resolvedPath))
325+
return true;
326+
}
327+
328+
return false;
329+
}
330+
331+
private boolean isUnderPipelineRoot(Container container, Path resolvedPath)
332+
{
333+
PipeRoot root = PipelineService.get().findPipelineRoot(container);
334+
return root != null && root.isUnderRoot(resolvedPath);
290335
}
291336

292337
public static class Factory extends AbstractTaskFactory<AbstractTaskFactorySettings, Factory>

0 commit comments

Comments
 (0)