use std::path::Path;
use crate::Result;
use crate::SecurityConfig;
use crate::types::DestDir;
use crate::types::SafePath;
use crate::types::SafeSymlink;
pub fn validate_symlink(
link_path: &SafePath,
target: &Path,
dest: &DestDir,
config: &SecurityConfig,
) -> Result<SafeSymlink> {
SafeSymlink::validate(link_path, target, dest, config)
}
#[cfg(test)]
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::field_reassign_with_default
)]
mod tests {
use super::*;
use std::path::PathBuf;
use tempfile::TempDir;
fn create_test_dest() -> (TempDir, DestDir) {
let temp = TempDir::new().expect("failed to create temp dir");
let dest = DestDir::new(temp.path().to_path_buf()).expect("failed to create dest");
(temp, dest)
}
#[test]
fn test_validate_symlink_allowed() {
let (_temp, dest) = create_test_dest();
let mut config = SecurityConfig::default();
config.allowed.symlinks = true;
let link = SafePath::validate(&PathBuf::from("link"), &dest, &config).unwrap();
let target = PathBuf::from("target.txt");
assert!(validate_symlink(&link, &target, &dest, &config).is_ok());
}
#[test]
fn test_validate_symlink_disabled() {
let (_temp, dest) = create_test_dest();
let config = SecurityConfig::default();
let link = SafePath::validate(&PathBuf::from("link"), &dest, &config).unwrap();
let target = PathBuf::from("target.txt");
assert!(validate_symlink(&link, &target, &dest, &config).is_err());
}
#[test]
fn test_validate_symlink_escape() {
let (_temp, dest) = create_test_dest();
let mut config = SecurityConfig::default();
config.allowed.symlinks = true;
let link = SafePath::validate(&PathBuf::from("link"), &dest, &config).unwrap();
let target = PathBuf::from("../../etc/passwd");
assert!(validate_symlink(&link, &target, &dest, &config).is_err());
}
#[test]
fn test_validate_symlink_relative_safe() {
let (_temp, dest) = create_test_dest();
let mut config = SecurityConfig::default();
config.allowed.symlinks = true;
let link = SafePath::validate(&PathBuf::from("foo/link"), &dest, &config).unwrap();
let target = PathBuf::from("../bar/target.txt");
let result = validate_symlink(&link, &target, &dest, &config);
assert!(result.is_ok());
}
}