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