cyfs_lib/acl/
action.rs

1use cyfs_base::*;
2
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Eq, PartialEq)]
6pub enum AclDirection {
7    Any = 0,
8
9    In = 1,
10    Out = 2,
11}
12
13impl AclDirection {
14    pub fn as_str(&self) -> &str {
15        match *self {
16            Self::Any => "*",
17            Self::In => "in",
18            Self::Out => "out",
19        }
20    }
21}
22
23impl FromStr for AclDirection {
24    type Err = BuckyError;
25
26    fn from_str(s: &str) -> Result<Self, Self::Err> {
27        let ret = match s {
28            "*" => Self::Any,
29            "in" => Self::In,
30            "out" => Self::Out,
31
32            _ => {
33                let msg = format!("unknown acl direction: {}", s);
34                error!("{}", msg);
35                return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
36            }
37        };
38
39        Ok(ret)
40    }
41}
42
43impl ToString for AclDirection {
44    fn to_string(&self) -> String {
45        self.as_str().to_owned()
46    }
47}
48
49#[derive(Debug, Clone, Eq, PartialEq)]
50pub enum AclOperationCategory {
51    Both,
52    Read,
53    Write,
54}
55
56#[derive(Debug, Clone, Eq, PartialEq)]
57pub enum AclOperation {
58    Any = 0,
59
60    GetObject = 1,
61    PutObject = 2,
62    PostObject = 3,
63    SelectObject = 4,
64    DeleteObject = 5,
65
66    SignObject = 6,
67    VerifyObject = 7,
68
69    PutData = 8,
70    GetData = 9,
71    DeleteData = 10,
72    QueryFile = 11,
73
74    // root-state
75    ReadRootState = 15,
76    WriteRootState = 16,
77
78    // non/ndn的一些通用操作
79    Get = 20,
80    Put = 21,
81    Delete = 22,
82
83    Read = 23,
84    Write = 24,
85
86    // sign+verify
87    Crypto = 25,
88}
89
90impl AclOperation {
91    pub fn category(&self) -> AclOperationCategory {
92        match *self {
93            Self::Any => AclOperationCategory::Both,
94
95            Self::GetObject
96            | Self::SelectObject
97            | Self::VerifyObject
98            | Self::GetData
99            | Self::ReadRootState
100            | Self::Get
101            | Self::Read
102            | Self::QueryFile => AclOperationCategory::Read,
103
104            Self::PutObject
105            | Self::PostObject
106            | Self::DeleteObject
107            | Self::SignObject
108            | Self::PutData
109            | Self::DeleteData
110            | Self::WriteRootState
111            | Self::Put
112            | Self::Delete
113            | Self::Write
114            | Self::Crypto => AclOperationCategory::Write,
115        }
116    }
117
118    pub fn as_str(&self) -> &str {
119        match *self {
120            Self::Any => "*",
121            Self::GetObject => "get-object",
122            Self::PutObject => "put-object",
123            Self::PostObject => "post-object",
124            Self::SelectObject => "select-object",
125            Self::DeleteObject => "delete-object",
126
127            Self::SignObject => "sign-object",
128            Self::VerifyObject => "verify-object",
129
130            Self::PutData => "put-data",
131            Self::GetData => "get-data",
132            Self::DeleteData => "delete-data",
133            Self::QueryFile => "query-file",
134
135            Self::WriteRootState => "write-root-state",
136            Self::ReadRootState => "read-root-state",
137
138            Self::Get => "get",
139            Self::Put => "put",
140            Self::Delete => "delete",
141
142            Self::Read => "read",
143            Self::Write => "write",
144
145            Self::Crypto => "crypto",
146        }
147    }
148
149    pub fn is_get(&self) -> bool {
150        match *self {
151            Self::GetObject | Self::GetData | Self::Get | Self::Any => true,
152            _ => false,
153        }
154    }
155
156    pub fn is_put(&self) -> bool {
157        match *self {
158            Self::PutObject | Self::PutData | Self::Put | Self::Any => true,
159            _ => false,
160        }
161    }
162
163    pub fn is_delete(&self) -> bool {
164        match *self {
165            Self::DeleteObject | Self::DeleteData | Self::Delete | Self::Any => true,
166            _ => false,
167        }
168    }
169
170    pub fn is_crypto(&self) -> bool {
171        match *self {
172            Self::SignObject | Self::VerifyObject => true,
173            _ => false,
174        }
175    }
176
177    pub fn is_read(&self) -> bool {
178        match self.category() {
179            AclOperationCategory::Read | AclOperationCategory::Both => true,
180            _ => false,
181        }
182    }
183
184    pub fn is_write(&self) -> bool {
185        match self.category() {
186            AclOperationCategory::Write | AclOperationCategory::Both => true,
187            _ => false,
188        }
189    }
190}
191
192impl FromStr for AclOperation {
193    type Err = BuckyError;
194
195    fn from_str(s: &str) -> Result<Self, Self::Err> {
196        let ret = match s {
197            "*" => Self::Any,
198            "get-object" => Self::GetObject,
199            "put-object" => Self::PutObject,
200            "post-object" => Self::PostObject,
201            "select-object" => Self::SelectObject,
202            "delete-object" => Self::DeleteObject,
203
204            "sign-object" => Self::SignObject,
205            "verify-object" => Self::VerifyObject,
206            "crypto" => Self::Crypto,
207
208            "put-data" => Self::PutData,
209            "get-data" => Self::GetData,
210            "delete-data" => Self::DeleteData,
211            "query-file" => Self::QueryFile,
212
213            "read-root-state" => Self::ReadRootState,
214            "write-root-state" => Self::WriteRootState,
215
216            "put" => Self::Put,
217            "get" => Self::Get,
218            "delete" => Self::Delete,
219
220            "read" => Self::Read,
221            "write" => Self::Write,
222
223            _ => {
224                let msg = format!("unknown acl operation: {}", s);
225                error!("{}", msg);
226                return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
227            }
228        };
229
230        Ok(ret)
231    }
232}
233
234impl ToString for AclOperation {
235    fn to_string(&self) -> String {
236        self.as_str().to_owned()
237    }
238}
239
240#[derive(Debug, Clone)]
241pub struct AclAction {
242    pub direction: AclDirection,
243    pub operation: AclOperation,
244}
245
246impl Default for AclAction {
247    fn default() -> Self {
248        Self {
249            direction: AclDirection::Any,
250            operation: AclOperation::Any,
251        }
252    }
253}
254
255impl AclAction {
256    pub fn new(direction: AclDirection, operation: AclOperation) -> Self {
257        Self {
258            direction,
259            operation,
260        }
261    }
262
263    pub fn is_match(&self, req: &Self) -> bool {
264        assert_ne!(req.direction, AclDirection::Any);
265        assert_ne!(req.operation, AclOperation::Any);
266
267        match &self.direction {
268            AclDirection::Any => {}
269            _ => {
270                if self.direction != req.direction {
271                    return false;
272                }
273            }
274        }
275
276        if self.operation == req.operation {
277            return true;
278        }
279
280        // 一些通用操作判断
281        match &self.operation {
282            AclOperation::Any => true,
283            AclOperation::Get => req.operation.is_get(),
284            AclOperation::Put => req.operation.is_put(),
285            AclOperation::Delete => req.operation.is_delete(),
286            AclOperation::Read => req.operation.is_read(),
287            AclOperation::Write => req.operation.is_write(),
288            AclOperation::Crypto => req.operation.is_crypto(),
289            _ => false,
290        }
291    }
292
293    pub fn parse(s: &str) -> BuckyResult<Self> {
294        let ret = if s == "*" {
295            Self {
296                direction: AclDirection::Any,
297                operation: AclOperation::Any,
298            }
299        } else {
300            // 必须由至少两段组成 *-operation/direction-*/direction-operation
301            let parts: Vec<&str> = s.split('-').collect();
302            if parts.len() < 2 {
303                let msg = format!("invalid action format: {}", s);
304                error!("{}", msg);
305                return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
306            }
307
308            let direction = AclDirection::from_str(parts[0])?;
309            let operation = AclOperation::from_str(&parts[1..].join("-"))?;
310
311            Self {
312                direction,
313                operation,
314            }
315        };
316
317        Ok(ret)
318    }
319}