systemprompt_users/services/
admin_service.rs1use systemprompt_identifiers::UserId;
7
8use crate::UserService;
9use crate::error::Result;
10use crate::models::{User, UserRole};
11
12#[derive(Debug)]
13pub struct UserAdminService {
14 user_service: UserService,
15}
16
17impl UserAdminService {
18 pub const fn new(user_service: UserService) -> Self {
19 Self { user_service }
20 }
21
22 pub async fn find_user(&self, identifier: &str) -> Result<Option<User>> {
23 if let Ok(user_id) = UserId::try_new(identifier)
24 && let Some(user) = self.user_service.find_by_id(&user_id).await?
25 {
26 return Ok(Some(user));
27 }
28
29 if identifier.contains('@') {
30 return self.user_service.find_by_email(identifier).await;
31 }
32
33 self.user_service.find_by_name(identifier).await
34 }
35
36 pub async fn promote_to_admin(&self, user_identifier: &str) -> Result<PromoteResult> {
37 let user = self.find_user(user_identifier).await?;
38 let admin_role = UserRole::Admin.as_str().to_owned();
39 let user_role = UserRole::User.as_str().to_owned();
40
41 match user {
42 Some(u) => {
43 let current_roles = u.roles.clone();
44
45 if current_roles.contains(&admin_role) {
46 return Ok(PromoteResult::AlreadyAdmin(u));
47 }
48
49 let mut new_roles = current_roles;
50 if !new_roles.contains(&admin_role) {
51 new_roles.push(admin_role);
52 }
53 if !new_roles.contains(&user_role) {
54 new_roles.push(user_role);
55 }
56
57 let updated = self.user_service.assign_roles(&u.id, &new_roles).await?;
58 Ok(PromoteResult::Promoted(updated, new_roles))
59 },
60 None => Ok(PromoteResult::UserNotFound),
61 }
62 }
63
64 pub async fn demote_from_admin(&self, user_identifier: &str) -> Result<DemoteResult> {
65 let user = self.find_user(user_identifier).await?;
66 let admin_role = UserRole::Admin.as_str();
67 let user_role = UserRole::User.as_str().to_owned();
68
69 match user {
70 Some(u) => {
71 let current_roles = u.roles.clone();
72
73 if !current_roles.contains(&admin_role.to_owned()) {
74 return Ok(DemoteResult::NotAdmin(u));
75 }
76
77 let new_roles: Vec<String> = current_roles
78 .into_iter()
79 .filter(|r| r != admin_role)
80 .collect();
81
82 let mut final_roles = new_roles;
83 if !final_roles.contains(&user_role) {
84 final_roles.push(user_role);
85 }
86
87 let updated = self.user_service.assign_roles(&u.id, &final_roles).await?;
88 Ok(DemoteResult::Demoted(updated, final_roles))
89 },
90 None => Ok(DemoteResult::UserNotFound),
91 }
92 }
93}
94
95#[derive(Debug)]
96pub enum PromoteResult {
97 Promoted(User, Vec<String>),
98 AlreadyAdmin(User),
99 UserNotFound,
100}
101
102#[derive(Debug)]
103pub enum DemoteResult {
104 Demoted(User, Vec<String>),
105 NotAdmin(User),
106 UserNotFound,
107}