1use std::fmt;
2use std::ops;
3
4use std::string::ToString;
5
6use lazy_static::lazy_static;
7
8#[derive(Clone, Copy, Debug, PartialEq)]
12pub struct Permission(u32);
13
14impl Permission {
15 pub const NONE: Permission = Permission(0b00000);
17
18 pub const READ: Permission = Permission(0b00001);
20
21 pub const WRITE: Permission = Permission(0b00010);
23
24 pub const CREATE: Permission = Permission(0b00100);
26
27 pub const DELETE: Permission = Permission(0b01000);
29
30 pub const ADMIN: Permission = Permission(0b10000);
32
33 pub const ALL: Permission = Permission(0b11111);
35
36 pub(crate) fn from_raw(bits: u32) -> Permission {
38 Permission(bits)
39 }
40
41 pub(crate) fn code(&self) -> u32 {
42 self.0
43 }
44
45 pub fn can(self, permissions: Permission) -> bool {
54 (self & permissions) == permissions
55 }
56}
57
58impl ops::BitAnd for Permission {
59 type Output = Self;
60
61 fn bitand(self, rhs: Self) -> Self {
62 Permission::from_raw(self.0 & rhs.0)
63 }
64}
65
66impl ops::BitOr for Permission {
67 type Output = Self;
68
69 fn bitor(self, rhs: Self) -> Self {
70 Permission::from_raw(self.0 | rhs.0)
71 }
72}
73
74impl fmt::Display for Permission {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 if *self == Permission::ALL {
77 write!(f, "ALL")
78 } else if *self == Permission::NONE {
79 write!(f, "NONE")
80 } else {
81 let mut first = true;
82 let mut tick = || {
83 if first {
84 first = false;
85 ""
86 } else {
87 "|"
88 }
89 };
90
91 if self.can(Permission::READ) {
92 write!(f, "{}READ", tick())?;
93 }
94 if self.can(Permission::WRITE) {
95 write!(f, "{}WRITE", tick())?;
96 }
97 if self.can(Permission::CREATE) {
98 write!(f, "{}CREATE", tick())?;
99 }
100 if self.can(Permission::DELETE) {
101 write!(f, "{}DELETE", tick())?;
102 }
103 if self.can(Permission::ADMIN) {
104 write!(f, "{}ADMIN", tick())?;
105 }
106 Ok(())
107 }
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn permission_bitor() {
117 let all = Permission::READ
118 | Permission::WRITE
119 | Permission::CREATE
120 | Permission::DELETE
121 | Permission::ADMIN;
122 assert_eq!(Permission::ALL, all);
123 }
124
125 #[test]
126 fn permission_can() {
127 assert!(Permission::ALL.can(Permission::WRITE));
128 assert!(!Permission::WRITE.can(Permission::READ));
129 }
130
131 #[test]
132 fn permission_format() {
133 assert_eq!("ALL", Permission::ALL.to_string());
134 assert_eq!("NONE", Permission::NONE.to_string());
135 assert_eq!(
136 "READ|WRITE",
137 (Permission::READ | Permission::WRITE).to_string()
138 );
139 assert_eq!(
140 "CREATE|DELETE",
141 (Permission::CREATE | Permission::DELETE).to_string()
142 );
143 assert_eq!("ADMIN", Permission::ADMIN.to_string());
144 }
145}
146
147#[derive(Clone, Debug, PartialEq)]
158pub struct Acl {
159 pub perms: Permission,
161 pub scheme: String,
164 pub id: String,
167}
168
169impl Acl {
170 pub fn new<T, U>(permissions: Permission, scheme: T, id: U) -> Acl
172 where
173 T: ToString,
174 U: ToString,
175 {
176 Acl {
177 perms: permissions,
178 scheme: scheme.to_string(),
179 id: id.to_string(),
180 }
181 }
182
183 pub fn creator_all() -> &'static Vec<Acl> {
185 &ACL_CREATOR_ALL
186 }
187
188 pub fn open_unsafe() -> &'static Vec<Acl> {
190 &ACL_OPEN_UNSAFE
191 }
192
193 pub fn read_unsafe() -> &'static Vec<Acl> {
195 &ACL_READ_UNSAFE
196 }
197}
198
199lazy_static! {
200 static ref ACL_CREATOR_ALL: Vec<Acl> = vec![Acl::new(Permission::ALL, "auth", "")];
201 static ref ACL_OPEN_UNSAFE: Vec<Acl> = vec![Acl::new(Permission::ALL, "world", "anyone")];
202 static ref ACL_READ_UNSAFE: Vec<Acl> = vec![Acl::new(Permission::READ, "world", "anyone")];
203}
204
205impl fmt::Display for Acl {
206 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207 write!(f, "({}:{}, {})", self.scheme, self.id, self.perms)
208 }
209}