1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use dev_prefix::*;
use types::*;
pub fn validate(repo: &Path, project: &Project) -> Result<()> {
let mut files: HashSet<&PathBuf> = HashSet::new();
files.extend(project.artifacts.values().map(|a| &a.def));
files.extend(project.files.iter());
files.extend(project.repo_map.keys());
for f in files {
if !f.is_absolute() {
let msg = format!("{} is not an absolute path", f.display());
return Err(ErrorKind::Internal(msg).into());
}
if !f.starts_with(repo) {
let msg = format!(
"{} is not a subdir of cwd repo {}",
f.display(),
repo.display()
);
return Err(ErrorKind::Security(msg).into());
}
if !project
.settings
.artifact_paths
.iter()
.any(|p| f.starts_with(p))
{
let msg = format!(
"{} is not a subdir of any artifact_paths {:?}",
f.display(),
project.settings.artifact_paths
);
return Err(ErrorKind::Security(msg).into());
}
if !f.exists() {
let msg = format!(
"{} does not already exist and cannot be created here",
f.display()
);
return Err(ErrorKind::Security(msg).into());
}
}
Ok(())
}
pub fn validate_settings(repo: &Path, settings: &Settings) -> Result<()> {
if settings.artifact_paths.iter().any(|p| !p.starts_with(repo)) {
let msg = "`artifact_paths` invalid".to_string();
Err(ErrorKind::Security(msg).into())
} else {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_data;
use utils;
use user;
use tempdir;
use fs_extra::dir;
#[test]
fn test_bounds() {
test_bounds_init();
test_bounds_edit();
}
fn test_bounds_init() {
let design = test_data::TINVALID_BOUNDS.join("repo").join("design");
let repo = utils::find_repo(&design).unwrap();
match user::load_repo(&repo) {
Err(e) => {
match *e.kind() {
ErrorKind::Security(_) => { }
_ => panic!("Unexpected error: {:?}", e.display()),
}
}
Ok(_) => panic!(
"CRITICAL: Fmt suceeded when it should not have -- may need to reset with git"
),
}
}
fn test_bounds_edit() {
let tmpdir = tempdir::TempDir::new("artifact").unwrap();
let writedir = tmpdir.path();
dir::copy(
&test_data::TSIMPLE_DIR.as_path(),
&writedir,
&dir::CopyOptions::new(),
).unwrap();
let simple = writedir.join("simple");
let repo = utils::find_repo(&simple).unwrap();
let mut project = user::load_repo(&repo).unwrap();
let (name, mut art) = Artifact::from_str("[SPC-out_bounds]\n").unwrap();
art.def = writedir.to_path_buf();
project.artifacts.insert(name, art);
assert!(validate(&repo, &project).is_err());
}
}