1use alloc::{
2 collections::{BTreeMap, BTreeSet},
3 string::{String, ToString},
4 vec::Vec,
5};
6use synchronization::{blocking_mutex::raw::CriticalSectionRawMutex, rwlock::RwLock};
7
8use super::*;
9
10struct InternalUser {
11 pub name: String,
12 pub primary_group: GroupIdentifier,
13}
14
15struct InternalGroup {
16 pub name: String,
17 pub users: BTreeSet<UserIdentifier>,
18}
19
20struct InternalManager {
21 pub users: BTreeMap<UserIdentifier, InternalUser>,
22 pub groups: BTreeMap<GroupIdentifier, InternalGroup>,
23}
24
25pub struct Manager(RwLock<CriticalSectionRawMutex, InternalManager>);
26
27impl Default for Manager {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl Manager {
34 pub fn new() -> Self {
35 let mut groups = BTreeMap::new();
36 groups.insert(
37 GroupIdentifier::ROOT,
38 InternalGroup {
39 name: "root".to_string(),
40 users: BTreeSet::new(),
41 },
42 );
43
44 let mut users = BTreeMap::new();
45 users.insert(
46 UserIdentifier::ROOT,
47 InternalUser {
48 name: "root".to_string(),
49 primary_group: GroupIdentifier::ROOT,
50 },
51 );
52
53 Self(RwLock::new(InternalManager { users, groups }))
54 }
55
56 pub async fn get_new_group_identifier(&self) -> Result<GroupIdentifier> {
57 let inner = self.0.read().await;
58
59 let mut identifier = GroupIdentifier::MINIMUM;
60
61 while inner.groups.contains_key(&identifier) {
62 identifier += 1;
63
64 if identifier == GroupIdentifier::MAXIMUM {
65 return Err(Error::TooManyGroups);
66 }
67 }
68
69 Ok(identifier)
70 }
71
72 pub async fn get_new_user_identifier(&self) -> Result<UserIdentifier> {
73 let inner = self.0.read().await;
74
75 let mut identifier = UserIdentifier::MINIMUM;
76
77 while inner.users.contains_key(&identifier) {
78 identifier += 1;
79
80 if identifier == UserIdentifier::MAXIMUM {
81 return Err(Error::TooManyUsers);
82 }
83 }
84
85 Ok(identifier)
86 }
87
88 pub async fn add_user(
89 &self,
90 identifier: UserIdentifier,
91 name: &str,
92 primary_group: GroupIdentifier,
93 ) -> Result<()> {
94 let mut inner = self.0.write().await;
95
96 if inner.users.contains_key(&identifier) {
98 return Err(Error::DuplicateUserIdentifier);
99 }
100
101 if inner.users.values().any(|user| user.name == name) {
103 return Err(Error::DuplicateUserName);
104 }
105
106 let user = InternalUser {
108 name: name.to_string(),
109 primary_group,
110 };
111
112 if inner.users.insert(identifier, user).is_some() {
113 return Err(Error::DuplicateUserIdentifier); }
115
116 inner
119 .groups
120 .get_mut(&primary_group)
121 .ok_or(Error::InvalidGroupIdentifier)?
122 .users
123 .insert(identifier);
124
125 Ok(())
126 }
127
128 pub async fn add_group(
129 &self,
130 identifier: GroupIdentifier,
131 name: &str,
132 users: &[UserIdentifier],
133 ) -> Result<()> {
134 let mut inner = self.0.write().await;
135
136 if inner.groups.contains_key(&identifier) {
138 return Err(Error::DuplicateGroupIdentifier);
139 }
140
141 if inner.groups.values().any(|group| group.name == name) {
143 return Err(Error::DuplicateGroupName);
144 }
145
146 let group = InternalGroup {
147 name: name.to_string(),
148 users: BTreeSet::from_iter(users.iter().cloned()),
149 };
150
151 if inner.groups.insert(identifier, group).is_some() {
152 return Err(Error::DuplicateGroupIdentifier); }
154
155 Ok(())
156 }
157
158 pub fn is_root(identifier: UserIdentifier) -> bool {
159 UserIdentifier::ROOT == identifier
160 }
161
162 pub async fn is_in_group(
163 &self,
164 user_identifier: UserIdentifier,
165 group_identifier: GroupIdentifier,
166 ) -> bool {
167 let inner = self.0.read().await;
168
169 if let Some(group) = inner.groups.get(&group_identifier)
170 && group.users.contains(&user_identifier)
171 {
172 return true;
173 }
174
175 false
176 }
177
178 pub async fn get_user_groups(
179 &self,
180 identifier: UserIdentifier,
181 ) -> Result<BTreeSet<GroupIdentifier>> {
182 let inner = self.0.read().await;
183
184 let mut user_groups: BTreeSet<GroupIdentifier> = BTreeSet::new();
185
186 user_groups.extend(
187 inner
188 .groups
189 .iter()
190 .filter(|(_, group)| group.users.contains(&identifier))
191 .map(|(identifier, _)| *identifier),
192 );
193
194 Ok(user_groups)
195 }
196
197 pub async fn exists_group(&self, identifier: GroupIdentifier) -> Result<bool> {
198 Ok(self.0.read().await.groups.contains_key(&identifier))
199 }
200
201 pub async fn exists_user(&self, identifier: UserIdentifier) -> Result<bool> {
202 Ok(self.0.read().await.users.contains_key(&identifier))
203 }
204
205 pub async fn add_to_group(
206 &self,
207 user_identifier: UserIdentifier,
208 group_identifier: GroupIdentifier,
209 ) -> Result<()> {
210 if !self.exists_group(group_identifier).await? {
211 return Err(Error::InvalidGroupIdentifier);
212 }
213 let mut inner = self.0.write().await;
214 if !inner
215 .groups
216 .get_mut(&group_identifier)
217 .ok_or(Error::InvalidGroupIdentifier)?
218 .users
219 .insert(user_identifier)
220 {
221 return Err(Error::DuplicateGroupIdentifier);
222 }
223 Ok(())
224 }
225
226 pub async fn get_group_name(&self, identifier: GroupIdentifier) -> Result<String> {
227 Ok(self
228 .0
229 .read()
230 .await
231 .groups
232 .get(&identifier)
233 .ok_or(Error::InvalidGroupIdentifier)?
234 .name
235 .clone())
236 }
237
238 pub async fn get_user_identifier(&self, name: &str) -> Result<UserIdentifier> {
239 Ok(*self
240 .0
241 .read()
242 .await
243 .users
244 .iter()
245 .find(|(_, user)| user.name == name)
246 .ok_or(Error::InvalidUserIdentifier)?
247 .0)
248 }
249
250 pub async fn get_group_users(
251 &self,
252 identifier: GroupIdentifier,
253 ) -> Result<Vec<UserIdentifier>> {
254 Ok(self
255 .0
256 .read()
257 .await
258 .groups
259 .get(&identifier)
260 .ok_or(Error::InvalidGroupIdentifier)?
261 .users
262 .clone()
263 .into_iter()
264 .collect())
265 }
266
267 pub async fn get_user_name(&self, identifier: UserIdentifier) -> Result<String> {
268 Ok(self
269 .0
270 .read()
271 .await
272 .users
273 .get(&identifier)
274 .ok_or(Error::InvalidUserIdentifier)?
275 .name
276 .clone())
277 }
278
279 pub async fn get_user_primary_group(
280 &self,
281 identifier: UserIdentifier,
282 ) -> Result<GroupIdentifier> {
283 Ok(self
284 .0
285 .read()
286 .await
287 .users
288 .get(&identifier)
289 .ok_or(Error::InvalidUserIdentifier)?
290 .primary_group)
291 }
292
293 pub fn check_credentials(&self, _user_name: &str, _password: &str) -> bool {
294 true
295 }
296}
297
298#[cfg(test)]
299mod tests {
300 extern crate std;
301
302 use super::*;
303
304 use task::test;
305
306 #[test]
307 async fn create_user() {
308 let manager = Manager::new();
309 let user_name = "Alice";
310 let identifier = UserIdentifier::new(1000);
311 manager
312 .add_user(identifier, user_name, GroupIdentifier::ROOT)
313 .await
314 .unwrap();
315 assert!(manager.exists_user(identifier).await.unwrap());
316 }
317
318 #[test]
319 async fn create_user_with_restored_primary_group_membership() {
320 let manager = Manager::new();
321 let user = UserIdentifier::new(42);
322 let group = GroupIdentifier::new(1000);
323 manager.add_group(group, "saved", &[user]).await.unwrap();
324 assert_eq!(manager.add_user(user, "bob", group).await, Ok(()));
325 assert_eq!(manager.get_user_name(user).await.unwrap(), "bob");
326 assert_eq!(manager.get_group_users(group).await.unwrap(), [user]);
327 assert_eq!(
328 manager.add_user(user, "bob", group).await,
329 Err(Error::DuplicateUserIdentifier)
330 );
331 }
332
333 #[test]
334 async fn create_user_duplicate() {
335 let user_name_1 = "Alice";
336 let user_name_2 = "Bob";
337
338 let identifier_1 = UserIdentifier::new(1000);
339 let identifier_2 = UserIdentifier::new(1001);
340
341 let manager = Manager::new();
343
344 manager
345 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
346 .await
347 .unwrap();
348
349 let result = manager
350 .add_user(identifier_1, user_name_2, GroupIdentifier::ROOT)
351 .await;
352 assert_eq!(result, Err(Error::DuplicateUserIdentifier));
353
354 let manager = Manager::new();
356
357 manager
358 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
359 .await
360 .unwrap();
361
362 let result = manager
363 .add_user(identifier_2, user_name_1, GroupIdentifier::ROOT)
364 .await;
365 assert_eq!(result, Err(Error::DuplicateUserName));
366
367 let manager = Manager::new();
369
370 manager
371 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
372 .await
373 .unwrap();
374
375 manager
376 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
377 .await
378 .unwrap_err();
379 }
380
381 #[test]
382 async fn create_group() {
383 let manager = Manager::new();
384 let group_name = "Developers";
385 let group_id = GroupIdentifier::new(1000);
386 let result = manager.add_group(group_id, group_name, &[]).await;
387 assert!(result.is_ok());
388 assert!(manager.exists_group(group_id).await.unwrap());
389 }
390
391 #[test]
392 async fn create_group_duplicate() {
393 let group_name_1 = "Developers";
394 let group_name_2 = "Testers";
395
396 let group_id_1 = GroupIdentifier::new(1000);
397 let group_id_2 = GroupIdentifier::new(1001);
398
399 let manager = Manager::new();
401
402 manager
403 .add_group(group_id_1, group_name_1, &[])
404 .await
405 .unwrap();
406
407 let result = manager.add_group(group_id_1, group_name_2, &[]).await;
408 assert_eq!(result, Err(Error::DuplicateGroupIdentifier));
409
410 let manager = Manager::new();
412
413 manager
414 .add_group(group_id_1, group_name_1, &[])
415 .await
416 .unwrap();
417
418 let result = manager.add_group(group_id_2, group_name_1, &[]).await;
419 assert_eq!(result, Err(Error::DuplicateGroupName));
420
421 let manager = Manager::new();
423
424 manager
425 .add_group(group_id_1, group_name_1, &[])
426 .await
427 .unwrap();
428
429 manager
430 .add_group(group_id_1, group_name_1, &[])
431 .await
432 .unwrap_err();
433 }
434
435 #[test]
436 async fn is_root() {
437 let root_id = UserIdentifier::ROOT;
438 assert!(Manager::is_root(root_id));
439 }
440
441 #[test]
442 async fn is_in_group() {
443 let manager = Manager::new();
444 let user_name = "Bob";
445 let identifier = UserIdentifier::new(1000);
446 manager
447 .add_user(identifier, user_name, GroupIdentifier::ROOT)
448 .await
449 .unwrap();
450 let group_name = "Admins";
451 let group_id = GroupIdentifier::new(1000);
452
453 manager.add_group(group_id, group_name, &[]).await.unwrap();
454 manager.add_to_group(identifier, group_id).await.unwrap();
455 assert!(manager.is_in_group(identifier, group_id).await);
456 }
457
458 #[test]
459 async fn get_user_groups() {
460 let manager = Manager::new();
461
462 let user_name = "Charlie";
463 let identifier = UserIdentifier::new(1000);
464 manager
465 .add_user(identifier, user_name, GroupIdentifier::ROOT)
466 .await
467 .unwrap();
468 let group_name1 = "TeamA";
469 let group_id1 = GroupIdentifier::new(1000);
470
471 manager
472 .add_group(group_id1, group_name1, &[])
473 .await
474 .unwrap();
475 let group_name2 = "TeamB";
476 let group_id2 = GroupIdentifier::new(1001);
477
478 manager
479 .add_group(group_id2, group_name2, &[])
480 .await
481 .unwrap();
482 manager.add_to_group(identifier, group_id1).await.unwrap();
483 manager.add_to_group(identifier, group_id2).await.unwrap();
484 let groups = manager.get_user_groups(identifier).await.unwrap();
485
486 assert_eq!(groups.len(), 3);
487 assert!(
488 groups.contains(&group_id1)
489 && groups.contains(&group_id2)
490 && groups.contains(&GroupIdentifier::ROOT)
491 );
492 }
493
494 #[test]
495 async fn get_group_name() {
496 let manager = Manager::new();
497 let group_name = "QA";
498 let group_id = GroupIdentifier::new(1000);
499 manager.add_group(group_id, group_name, &[]).await.unwrap();
500 let retrieved_name = manager.get_group_name(group_id).await.unwrap();
501 assert_eq!(group_name, retrieved_name);
502 }
503
504 #[test]
505 async fn get_group_users() {
506 let manager = Manager::new();
507 let user_name = "Dave";
508 let identifier = UserIdentifier::new(1000);
509 manager
510 .add_user(identifier, user_name, GroupIdentifier::ROOT)
511 .await
512 .unwrap();
513 let group_name = "Engineers";
514 let group_id = GroupIdentifier::new(1000);
515 manager.add_group(group_id, group_name, &[]).await.unwrap();
516 manager.add_to_group(identifier, group_id).await.unwrap();
517 let users = manager.get_group_users(group_id).await.unwrap();
518 assert_eq!(users.len(), 1);
519 assert!(users.contains(&identifier));
520 }
521
522 #[test]
523 async fn get_user_name() {
524 let manager = Manager::new();
525 let user_name = "Eve";
526 let identifier = UserIdentifier::new(1000);
527 manager
528 .add_user(identifier, user_name, GroupIdentifier::ROOT)
529 .await
530 .unwrap();
531 let retrieved_name = manager.get_user_name(identifier).await.unwrap();
532 assert_eq!(user_name, retrieved_name);
533 }
534
535 #[test]
536 async fn check_credentials() {
537 let manager = Manager::new();
538 let user_name = "Frank";
539 let password = "password123";
540 assert!(manager.check_credentials(user_name, password));
541 }
542}