cyfs_base/objects/object_map/
access.rs1use crate::*;
2
3use std::borrow::Cow;
4
5pub struct OpEnvPathAccess {
6 limit_path: String,
7 access: AccessPermissions,
8}
9
10impl OpEnvPathAccess {
11 pub fn new(path: &str, access: AccessPermissions) -> Self {
12 let limit_path = Self::fix_path(path).into_owned();
13
14 Self { limit_path, access }
15 }
16
17 fn fix_path(path: &str) -> Cow<str> {
19 if path.starts_with('/') {
20 if path.ends_with('/') {
21 Cow::Borrowed(path)
22 } else {
23 Cow::Owned(format!("{}/", path))
24 }
25 } else {
26 if path.ends_with('/') {
27 Cow::Owned(format!("/{}", path))
28 } else {
29 Cow::Owned(format!("/{}/", path))
30 }
31 }
32 }
33
34 pub fn check_full_path(&self, full_path: &str, op_type: RequestOpType) -> BuckyResult<()> {
35 let full_path = Self::fix_path(full_path);
36 assert!(full_path.starts_with('/'));
37
38 if full_path.starts_with(self.limit_path.as_str()) {
39 if self.access.test_op(op_type) {
40 Ok(())
41 } else {
42 let msg = format!("op is not allowed within path limiter! path={}, limiter={}, access={}, op='{:?}'",
43 full_path, self.limit_path, self.access.as_str(), op_type);
44 error!("{}", msg);
45 Err(BuckyError::new(BuckyErrorCode::PermissionDenied, msg))
46 }
47 } else {
48 let msg = format!(
49 "full path is out of path limiter! path={}, limiter={}",
50 full_path, self.limit_path
51 );
52 error!("{}", msg);
53 Err(BuckyError::new(BuckyErrorCode::PermissionDenied, msg))
54 }
55 }
56
57 pub fn check_full_path_list(
58 &self,
59 list: &Vec<String>,
60 op_type: RequestOpType,
61 ) -> BuckyResult<()> {
62
63 for full_path in list {
64 self.check_full_path(full_path.as_str(), op_type)?;
65 }
66
67 Ok(())
68 }
69
70 pub fn check_path_key(&self, path: &str, key: &str, op_type: RequestOpType) -> BuckyResult<()> {
71 let full_path = if path.ends_with('/') {
74 format!("{}{}", path, key)
75 } else {
76 format!("{}/{}", path, key)
77 };
78
79 self.check_full_path(&full_path, op_type)
80 }
81}
82
83#[cfg(test)]
84mod test {
85 use super::*;
86
87 #[test]
88 fn test() {
89 let limiter = OpEnvPathAccess::new("/a/b/c", AccessPermissions::ReadAndCall);
90 limiter
91 .check_full_path("/a/b", RequestOpType::Read)
92 .unwrap_err();
93 limiter
94 .check_full_path("/a/d", RequestOpType::Call)
95 .unwrap_err();
96 limiter
97 .check_full_path("/a/d/c1", RequestOpType::Call)
98 .unwrap_err();
99 limiter
100 .check_full_path("/", RequestOpType::Call)
101 .unwrap_err();
102 limiter
103 .check_full_path("/a", RequestOpType::Call)
104 .unwrap_err();
105
106 limiter
107 .check_full_path("/a/b/c", RequestOpType::Call)
108 .unwrap();
109 limiter
110 .check_full_path("/a/b/c/x", RequestOpType::Read)
111 .unwrap();
112
113 limiter
114 .check_full_path("/a/b/c", RequestOpType::Write)
115 .unwrap_err();
116 limiter
117 .check_full_path("/a/b/c/x", RequestOpType::Write)
118 .unwrap_err();
119 }
120}