Skip to content

Commit c5847b7

Browse files
authored
Stricter checks for explicit local mag paths (#8547)
* Stricter checks for explicit local mag paths * unify flatmap
1 parent cbe28a0 commit c5847b7

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/DataSourceService.scala

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ class DataSourceService @Inject()(
212212
.exploreMappings(dataBaseDir.resolve(organizationId).resolve(datasetName).resolve(dataLayerName))
213213
.getOrElse(Set())
214214

215-
private def validateDataSource(dataSource: DataSource): Box[Unit] = {
215+
private def validateDataSource(dataSource: DataSource, organizationDir: Path): Box[Unit] = {
216216
def Check(expression: Boolean, msg: String): Option[String] = if (!expression) Some(msg) else None
217217

218218
// Check that when mags are sorted by max dimension, all dimensions are sorted.
@@ -222,6 +222,16 @@ class DataSourceService @Inject()(
222222
val magsYIsSorted = magsSorted.map(_.map(_.y)) == magsSorted.map(_.map(_.y).sorted)
223223
val magsZIsSorted = magsSorted.map(_.map(_.z)) == magsSorted.map(_.map(_.z).sorted)
224224

225+
def pathOk(pathStr: String): Boolean = {
226+
val uri = new URI(pathStr)
227+
if (DataVaultService.isRemoteScheme(uri.getScheme)) true
228+
else {
229+
val path = Path.of(new URI(pathStr).getPath).normalize().toAbsolutePath
230+
val allowedParent = organizationDir.toAbsolutePath
231+
if (path.startsWith(allowedParent)) true else false
232+
}
233+
}
234+
225235
val errors = List(
226236
Check(dataSource.scale.factor.isStrictlyPositive, "DataSource voxel size (scale) is invalid"),
227237
Check(magsXIsSorted && magsYIsSorted && magsZIsSorted, "Mags do not monotonically increase in all dimensions"),
@@ -242,6 +252,10 @@ class DataSourceService @Inject()(
242252
Check(
243253
dataSource.dataLayers.map(_.name).distinct.length == dataSource.dataLayers.length,
244254
"Layer names must be unique. At least two layers have the same name."
255+
),
256+
Check(
257+
dataSource.dataLayers.flatMap(_.mags).flatMap(_.path).forall(pathOk),
258+
"Mags with explicit paths must stay within the organization directory."
245259
)
246260
).flatten
247261

@@ -252,17 +266,19 @@ class DataSourceService @Inject()(
252266
}
253267
}
254268

255-
def updateDataSource(dataSource: DataSource, expectExisting: Boolean): Fox[Unit] =
269+
def updateDataSource(dataSource: DataSource, expectExisting: Boolean): Fox[Unit] = {
270+
val organizationDir = dataBaseDir.resolve(dataSource.id.organizationId)
271+
val dataSourcePath = organizationDir.resolve(dataSource.id.directoryName)
256272
for {
257-
_ <- validateDataSource(dataSource).toFox
258-
dataSourcePath = dataBaseDir.resolve(dataSource.id.organizationId).resolve(dataSource.id.directoryName)
273+
_ <- validateDataSource(dataSource, organizationDir).toFox
259274
propertiesFile = dataSourcePath.resolve(propertiesFileName)
260275
_ <- Fox.runIf(!expectExisting)(ensureDirectoryBox(dataSourcePath))
261276
_ <- Fox.runIf(!expectExisting)(bool2Fox(!Files.exists(propertiesFile))) ?~> "dataSource.alreadyPresent"
262277
_ <- Fox.runIf(expectExisting)(backupPreviousProperties(dataSourcePath)) ?~> "Could not update datasource-properties.json"
263278
_ <- JsonHelper.jsonToFile(propertiesFile, dataSource) ?~> "Could not update datasource-properties.json"
264279
_ <- dataSourceRepository.updateDataSource(dataSource)
265280
} yield ()
281+
}
266282

267283
private def backupPreviousProperties(dataSourcePath: Path): Box[Unit] = {
268284
val propertiesFile = dataSourcePath.resolve(propertiesFileName)

0 commit comments

Comments
 (0)