signstar_crypto/secret_file/
common.rs1use std::{os::unix::fs::PermissionsExt, path::Path};
4
5use signstar_common::common::SECRET_FILE_MODE;
6
7pub(crate) fn check_secrets_file(path: impl AsRef<Path>) -> Result<(), crate::Error> {
25 let path = path.as_ref();
26
27 if !path.exists() {
29 return Err(crate::secret_file::Error::SecretsFileMissing {
30 path: path.to_path_buf(),
31 }
32 .into());
33 }
34
35 if !path.is_file() {
37 return Err(crate::secret_file::Error::SecretsFileNotAFile {
38 path: path.to_path_buf(),
39 }
40 .into());
41 }
42
43 match path.metadata() {
45 Ok(metadata) => {
46 let mode = metadata.permissions().mode();
47 if mode != SECRET_FILE_MODE {
48 return Err(crate::secret_file::Error::SecretsFilePermissions {
49 path: path.to_path_buf(),
50 mode,
51 }
52 .into());
53 }
54 }
55 Err(source) => {
56 return Err(crate::secret_file::Error::SecretsFileMetadata {
57 path: path.to_path_buf(),
58 source,
59 }
60 .into());
61 }
62 }
63
64 Ok(())
65}
66
67#[cfg(test)]
68mod tests {
69 use std::fs::{Permissions, set_permissions};
70
71 use log::{LevelFilter, debug};
72 use signstar_common::logging::setup_logging;
73 use tempfile::{NamedTempFile, TempDir};
74 use testresult::TestResult;
75
76 use super::*;
77
78 #[test]
81 fn check_secrets_file_succeeds() -> TestResult {
82 setup_logging(LevelFilter::Debug)?;
83
84 let temp_file = NamedTempFile::new()?;
85 let path = temp_file.path();
86 set_permissions(path, Permissions::from_mode(SECRET_FILE_MODE))?;
87 debug!(
88 "Created {path:?} with mode {:o}",
89 path.metadata()?.permissions().mode()
90 );
91
92 check_secrets_file(path)?;
93
94 Ok(())
95 }
96
97 #[test]
99 fn check_secrets_file_fails_on_missing_file() -> TestResult {
100 setup_logging(LevelFilter::Debug)?;
101
102 let temp_file = NamedTempFile::new()?;
103 let path = temp_file.path().to_path_buf();
104 temp_file.close()?;
105
106 if check_secrets_file(&path).is_ok() {
107 panic!("The path {path:?} is missing and should not have passed as a secrets file.");
108 }
109
110 Ok(())
111 }
112
113 #[test]
115 fn check_secrets_file_fails_on_dir() -> TestResult {
116 setup_logging(LevelFilter::Debug)?;
117
118 let temp_file = TempDir::new()?;
119 let path = temp_file.path();
120 debug!(
121 "Created {path:?} with mode {:o}",
122 path.metadata()?.permissions().mode()
123 );
124
125 if check_secrets_file(path).is_ok() {
126 panic!("The dir {path:?} should not have passed as a secrets file.");
127 }
128
129 Ok(())
130 }
131
132 #[test]
134 fn check_secrets_file_fails_on_invalid_permissions() -> TestResult {
135 setup_logging(LevelFilter::Debug)?;
136
137 let temp_file = NamedTempFile::new()?;
138 let path = temp_file.path();
139 set_permissions(path, Permissions::from_mode(0o100644))?;
140 debug!(
141 "Created {path:?} with mode {:o}",
142 path.metadata()?.permissions().mode()
143 );
144
145 if check_secrets_file(path).is_ok() {
146 panic!("The file at {path:?} should not have passed as a secrets file.");
147 }
148
149 Ok(())
150 }
151}