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
179 if let Some(group) = inner.groups.get(&group_identifier)
180 && group.users.contains(&user_identifier)
181 {
182 return true;
183 }
184
185 false
186 }
187
188 pub async fn get_user_groups(
189 &self,
190 identifier: UserIdentifier,
191 ) -> Result<BTreeSet<GroupIdentifier>> {
192 let inner = self.0.read().await;
193
194 let mut user_groups: BTreeSet<GroupIdentifier> = BTreeSet::new();
195
196 user_groups.extend(
197 inner
198 .groups
199 .iter()
200 .filter(|(_, group)| group.users.contains(&identifier))
201 .map(|(identifier, _)| *identifier),
202 );
203
204 Ok(user_groups)
205 }
206
207 pub async fn exists_group(&self, identifier: GroupIdentifier) -> Result<bool> {
208 Ok(self.0.read().await.groups.contains_key(&identifier))
209 }
210
211 pub async fn exists_user(&self, identifier: UserIdentifier) -> Result<bool> {
212 Ok(self.0.read().await.users.contains_key(&identifier))
213 }
214
215 pub async fn add_to_group(
216 &self,
217 user_identifier: UserIdentifier,
218 group_identifier: GroupIdentifier,
219 ) -> Result<()> {
220 if !self.exists_group(group_identifier).await? {
221 return Err(Error::InvalidGroupIdentifier);
222 }
223 let mut inner = self.0.write().await;
224 if !inner
225 .groups
226 .get_mut(&group_identifier)
227 .ok_or(Error::InvalidGroupIdentifier)?
228 .users
229 .insert(user_identifier)
230 {
231 return Err(Error::DuplicateGroupIdentifier);
232 }
233 Ok(())
234 }
235
236 pub async fn get_group_name(&self, identifier: GroupIdentifier) -> Result<String> {
237 Ok(self
238 .0
239 .read()
240 .await
241 .groups
242 .get(&identifier)
243 .ok_or(Error::InvalidGroupIdentifier)?
244 .name
245 .clone())
246 }
247
248 pub async fn get_user_identifier(&self, name: &str) -> Result<UserIdentifier> {
249 Ok(*self
250 .0
251 .read()
252 .await
253 .users
254 .iter()
255 .find(|(_, user)| user.name == name)
256 .ok_or(Error::InvalidUserIdentifier)?
257 .0)
258 }
259
260 pub async fn get_group_users(
261 &self,
262 identifier: GroupIdentifier,
263 ) -> Result<Vec<UserIdentifier>> {
264 Ok(self
265 .0
266 .read()
267 .await
268 .groups
269 .get(&identifier)
270 .ok_or(Error::InvalidGroupIdentifier)?
271 .users
272 .clone()
273 .into_iter()
274 .collect())
275 }
276
277 pub async fn get_user_name(&self, identifier: UserIdentifier) -> Result<String> {
278 Ok(self
279 .0
280 .read()
281 .await
282 .users
283 .get(&identifier)
284 .ok_or(Error::InvalidUserIdentifier)?
285 .name
286 .clone())
287 }
288
289 pub async fn get_user_primary_group(
290 &self,
291 identifier: UserIdentifier,
292 ) -> Result<GroupIdentifier> {
293 Ok(self
294 .0
295 .read()
296 .await
297 .users
298 .get(&identifier)
299 .ok_or(Error::InvalidUserIdentifier)?
300 .primary_group)
301 }
302
303 pub fn check_credentials(&self, _user_name: &str, _password: &str) -> bool {
304 true
305 }
306}
307
308#[cfg(test)]
309mod tests {
310 extern crate std;
311
312 use super::*;
313
314 use task::test;
315
316 #[test]
317 async fn create_user() {
318 let manager = Manager::new();
319 let user_name = "Alice";
320 let identifier = UserIdentifier::new(1000);
321 manager
322 .add_user(identifier, user_name, GroupIdentifier::ROOT)
323 .await
324 .unwrap();
325 assert!(manager.exists_user(identifier).await.unwrap());
326 }
327
328 #[test]
329 async fn create_user_duplicate() {
330 let user_name_1 = "Alice";
331 let user_name_2 = "Bob";
332
333 let identifier_1 = UserIdentifier::new(1000);
334 let identifier_2 = UserIdentifier::new(1001);
335
336 let manager = Manager::new();
338
339 manager
340 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
341 .await
342 .unwrap();
343
344 let result = manager
345 .add_user(identifier_1, user_name_2, GroupIdentifier::ROOT)
346 .await;
347 assert_eq!(result, Err(Error::DuplicateUserIdentifier));
348
349 let manager = Manager::new();
351
352 manager
353 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
354 .await
355 .unwrap();
356
357 let result = manager
358 .add_user(identifier_2, user_name_1, GroupIdentifier::ROOT)
359 .await;
360 assert_eq!(result, Err(Error::DuplicateUserName));
361
362 let manager = Manager::new();
364
365 manager
366 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
367 .await
368 .unwrap();
369
370 manager
371 .add_user(identifier_1, user_name_1, GroupIdentifier::ROOT)
372 .await
373 .unwrap_err();
374 }
375
376 #[test]
377 async fn create_group() {
378 let manager = Manager::new();
379 let group_name = "Developers";
380 let group_id = GroupIdentifier::new(1000);
381 let result = manager.add_group(group_id, group_name, &[]).await;
382 assert!(result.is_ok());
383 assert!(manager.exists_group(group_id).await.unwrap());
384 }
385
386 #[test]
387 async fn create_group_duplicate() {
388 let group_name_1 = "Developers";
389 let group_name_2 = "Testers";
390
391 let group_id_1 = GroupIdentifier::new(1000);
392 let group_id_2 = GroupIdentifier::new(1001);
393
394 let manager = Manager::new();
396
397 manager
398 .add_group(group_id_1, group_name_1, &[])
399 .await
400 .unwrap();
401
402 let result = manager.add_group(group_id_1, group_name_2, &[]).await;
403 assert_eq!(result, Err(Error::DuplicateGroupIdentifier));
404
405 let manager = Manager::new();
407
408 manager
409 .add_group(group_id_1, group_name_1, &[])
410 .await
411 .unwrap();
412
413 let result = manager.add_group(group_id_2, group_name_1, &[]).await;
414 assert_eq!(result, Err(Error::DuplicateGroupName));
415
416 let manager = Manager::new();
418
419 manager
420 .add_group(group_id_1, group_name_1, &[])
421 .await
422 .unwrap();
423
424 manager
425 .add_group(group_id_1, group_name_1, &[])
426 .await
427 .unwrap_err();
428 }
429
430 #[test]
431 async fn is_root() {
432 let root_id = UserIdentifier::ROOT;
433 assert!(Manager::is_root(root_id));
434 }
435
436 #[test]
437 async fn is_in_group() {
438 let manager = Manager::new();
439 let user_name = "Bob";
440 let identifier = UserIdentifier::new(1000);
441 manager
442 .add_user(identifier, user_name, GroupIdentifier::ROOT)
443 .await
444 .unwrap();
445 let group_name = "Admins";
446 let group_id = GroupIdentifier::new(1000);
447
448 manager.add_group(group_id, group_name, &[]).await.unwrap();
449 manager.add_to_group(identifier, group_id).await.unwrap();
450 assert!(manager.is_in_group(identifier, group_id).await);
451 }
452
453 #[test]
454 async fn get_user_groups() {
455 let manager = Manager::new();
456
457 let user_name = "Charlie";
458 let identifier = UserIdentifier::new(1000);
459 manager
460 .add_user(identifier, user_name, GroupIdentifier::ROOT)
461 .await
462 .unwrap();
463 let group_name1 = "TeamA";
464 let group_id1 = GroupIdentifier::new(1000);
465
466 manager
467 .add_group(group_id1, group_name1, &[])
468 .await
469 .unwrap();
470 let group_name2 = "TeamB";
471 let group_id2 = GroupIdentifier::new(1001);
472
473 manager
474 .add_group(group_id2, group_name2, &[])
475 .await
476 .unwrap();
477 manager.add_to_group(identifier, group_id1).await.unwrap();
478 manager.add_to_group(identifier, group_id2).await.unwrap();
479 let groups = manager.get_user_groups(identifier).await.unwrap();
480
481 assert_eq!(groups.len(), 3);
482 assert!(
483 groups.contains(&group_id1)
484 && groups.contains(&group_id2)
485 && groups.contains(&GroupIdentifier::ROOT)
486 );
487 }
488
489 #[test]
490 async fn get_group_name() {
491 let manager = Manager::new();
492 let group_name = "QA";
493 let group_id = GroupIdentifier::new(1000);
494 manager.add_group(group_id, group_name, &[]).await.unwrap();
495 let retrieved_name = manager.get_group_name(group_id).await.unwrap();
496 assert_eq!(group_name, retrieved_name);
497 }
498
499 #[test]
500 async fn get_group_users() {
501 let manager = Manager::new();
502 let user_name = "Dave";
503 let identifier = UserIdentifier::new(1000);
504 manager
505 .add_user(identifier, user_name, GroupIdentifier::ROOT)
506 .await
507 .unwrap();
508 let group_name = "Engineers";
509 let group_id = GroupIdentifier::new(1000);
510 manager.add_group(group_id, group_name, &[]).await.unwrap();
511 manager.add_to_group(identifier, group_id).await.unwrap();
512 let users = manager.get_group_users(group_id).await.unwrap();
513 assert_eq!(users.len(), 1);
514 assert!(users.contains(&identifier));
515 }
516
517 #[test]
518 async fn get_user_name() {
519 let manager = Manager::new();
520 let user_name = "Eve";
521 let identifier = UserIdentifier::new(1000);
522 manager
523 .add_user(identifier, user_name, GroupIdentifier::ROOT)
524 .await
525 .unwrap();
526 let retrieved_name = manager.get_user_name(identifier).await.unwrap();
527 assert_eq!(user_name, retrieved_name);
528 }
529
530 #[test]
531 async fn check_credentials() {
532 let manager = Manager::new();
533 let user_name = "Frank";
534 let password = "password123";
535 assert!(manager.check_credentials(user_name, password));
536 }
537}