From a8abb38891c963eef8171f8cec575aea9e66704c Mon Sep 17 00:00:00 2001 From: Francesco Ceccon Date: Sat, 27 Jan 2024 14:29:53 +0100 Subject: [PATCH] sink: add filesystem read/write permissions **Summary** Allow indexers to read and write data from the filesystem. Filesystem access is granted with the `--allow-read` and `--allow-write` flags. --- cli/src/run.rs | 8 +++++ script/src/script.rs | 49 ++++++++++++++++++++------ sinks/sink-common/src/configuration.rs | 12 +++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/cli/src/run.rs b/cli/src/run.rs index 65758847..b3f4762f 100644 --- a/cli/src/run.rs +++ b/cli/src/run.rs @@ -62,6 +62,14 @@ pub async fn run(args: RunArgs) -> Result<(), CliError> { extra_args.push("--allow-net".to_string()); extra_args.push(allow_net.join(",").to_string()); }; + if let Some(allow_read) = args.transform.allow_read { + extra_args.push("--allow-read".to_string()); + extra_args.push(allow_read.join(",").to_string()); + }; + if let Some(allow_write) = args.transform.allow_write { + extra_args.push("--allow-write".to_string()); + extra_args.push(allow_write.join(",").to_string()); + }; if let Some(transform_timeout) = args.transform.script_transform_timeout_seconds { extra_args.push("--script-transform-timeout-seconds".to_string()); extra_args.push(transform_timeout.to_string()); diff --git a/script/src/script.rs b/script/src/script.rs index 06218bb0..301bd521 100644 --- a/script/src/script.rs +++ b/script/src/script.rs @@ -47,6 +47,14 @@ pub struct ScriptOptions { /// /// An empty list gives access to _ALL_ hosts. pub allow_net: Option>, + /// Allow read access to the given paths. + /// + /// An empty list gives access to _ALL_ paths. + pub allow_read: Option>, + /// Allow write access to the given paths. + /// + /// An empty list gives access to _ALL_ paths. + pub allow_write: Option>, /// Maximum time allowed to execute the transform function. pub transform_timeout: Option, /// Maximum time allowed to load the indexer script. @@ -355,22 +363,26 @@ impl Script { fn default_permissions(options: &ScriptOptions) -> Result { // If users use an empty hostname, allow all hosts. - let allow_net = options.allow_net.clone().map(|hosts| { - if hosts.len() == 1 { - if hosts[0].is_empty() { - vec![] - } else { - hosts - } - } else { - hosts - } + let allow_net = options.allow_net.clone().map(remove_empty_strings); + let allow_read = options.allow_read.clone().map(|paths| { + remove_empty_strings(paths) + .into_iter() + .map(Into::into) + .collect() + }); + let allow_write = options.allow_write.clone().map(|paths| { + remove_empty_strings(paths) + .into_iter() + .map(Into::into) + .collect() }); match Permissions::from_options(&PermissionsOptions { allow_env: options.allow_env.clone(), allow_hrtime: true, allow_net, + allow_read, + allow_write, prompt: false, ..PermissionsOptions::default() }) { @@ -381,3 +393,20 @@ impl Script { } } } + +pub fn remove_empty_strings(vec: Vec) -> Vec { + vec.into_iter().filter(|s| !s.is_empty()).collect() +} + +#[cfg(test)] +mod tests { + use super::remove_empty_strings; + + #[test] + fn test_remove_empty_string() { + let r0 = remove_empty_strings(vec!["".to_string()]); + assert!(r0.is_empty()); + let r1 = remove_empty_strings(vec!["abcd".to_string(), "".to_string()]); + assert_eq!(r1.len(), 1); + } +} diff --git a/sinks/sink-common/src/configuration.rs b/sinks/sink-common/src/configuration.rs index 8d6da91e..7519ddb3 100644 --- a/sinks/sink-common/src/configuration.rs +++ b/sinks/sink-common/src/configuration.rs @@ -85,6 +85,16 @@ pub struct ScriptOptions { /// Leave empty to allow all hosts, i.e. by specifying `--allow-net`. #[arg(long, env, value_delimiter = ',', num_args = 0..)] pub allow_net: Option>, + /// Grant file system write access to the paths. + /// + /// Leave empty to allow all paths, i.e. by specifying `--allow-write`. + #[arg(long, env, value_delimiter = ',', num_args = 0..)] + pub allow_write: Option>, + /// Grant file system read access to the paths. + /// + /// Leave empty to allow all paths, i.e. by specifying `--allow-write`. + #[arg(long, env, value_delimiter = ',', num_args = 0..)] + pub allow_read: Option>, /// Maximum time allowed to execute the transform function. #[arg(long, env)] pub script_transform_timeout_seconds: Option, @@ -365,6 +375,8 @@ impl ScriptOptions { IndexerOptions { allow_env: self.allow_env_from_env, allow_net: self.allow_net, + allow_read: self.allow_read, + allow_write: self.allow_write, transform_timeout: self .script_transform_timeout_seconds .map(Duration::from_secs),