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