authx_plugins/admin/
mod.rs1mod service;
2
3pub use service::{AdminService, BanStatus};
4
5#[cfg(test)]
6mod tests {
7 use super::service::{AdminService, BanStatus};
8 use authx_core::{events::EventBus, models::CreateUser};
9 use authx_storage::{memory::MemoryStore, ports::UserRepository};
10 use uuid::Uuid;
11
12 fn setup() -> (MemoryStore, EventBus) {
13 (MemoryStore::new(), EventBus::new())
14 }
15
16 async fn make_user(store: &MemoryStore, email: &str) -> Uuid {
17 UserRepository::create(
18 store,
19 CreateUser {
20 email: email.into(),
21 username: None,
22 metadata: None,
23 },
24 )
25 .await
26 .unwrap()
27 .id
28 }
29
30 #[tokio::test]
31 async fn ban_and_check_status() {
32 let (store, events) = setup();
33 let admin_id = make_user(&store, "admin@x.com").await;
34 let user_id = make_user(&store, "user@x.com").await;
35 let svc = AdminService::new(store.clone(), events, 3600);
36 svc.ban_user(admin_id, user_id, "test ban").await.unwrap();
37 assert_eq!(svc.ban_status(user_id).await.unwrap(), BanStatus::Banned);
38 }
39
40 #[tokio::test]
41 async fn unban_restores_active_status() {
42 let (store, events) = setup();
43 let admin_id = make_user(&store, "admin@x.com").await;
44 let user_id = make_user(&store, "user@x.com").await;
45 let svc = AdminService::new(store.clone(), events, 3600);
46 svc.ban_user(admin_id, user_id, "temp ban").await.unwrap();
47 svc.unban_user(admin_id, user_id).await.unwrap();
48 assert_eq!(svc.ban_status(user_id).await.unwrap(), BanStatus::Active);
49 }
50
51 #[tokio::test]
52 async fn ban_revokes_all_sessions() {
53 use authx_core::models::CreateSession;
54 use authx_storage::ports::SessionRepository;
55 use chrono::Utc;
56
57 let (store, events) = setup();
58 let admin_id = make_user(&store, "admin@x.com").await;
59 let user_id = make_user(&store, "user@x.com").await;
60
61 SessionRepository::create(
62 &store,
63 CreateSession {
64 user_id,
65 token_hash: "abc123".into(),
66 device_info: serde_json::Value::Null,
67 ip_address: "127.0.0.1".into(),
68 org_id: None,
69 expires_at: Utc::now() + chrono::Duration::hours(1),
70 },
71 )
72 .await
73 .unwrap();
74
75 let svc = AdminService::new(store.clone(), events, 3600);
76 svc.ban_user(admin_id, user_id, "session test")
77 .await
78 .unwrap();
79 let sessions = SessionRepository::find_by_user(&store, user_id)
80 .await
81 .unwrap();
82 assert!(sessions.is_empty());
83 }
84
85 #[tokio::test]
86 async fn impersonate_creates_tagged_session() {
87 let (store, events) = setup();
88 let admin_id = make_user(&store, "admin@x.com").await;
89 let target_id = make_user(&store, "target@x.com").await;
90 let svc = AdminService::new(store.clone(), events, 3600);
91 let (session, token) = svc
92 .impersonate(admin_id, target_id, "10.0.0.1")
93 .await
94 .unwrap();
95 assert_eq!(session.user_id, target_id);
96 assert!(session.ip_address.contains("impersonation"));
97 assert_eq!(token.len(), 64);
98 }
99
100 #[tokio::test]
101 async fn get_user_returns_user() {
102 let (store, events) = setup();
103 let user_id = make_user(&store, "getme@x.com").await;
104 let svc = AdminService::new(store.clone(), events, 3600);
105 let user = svc.get_user(user_id).await.unwrap();
106 assert_eq!(user.email, "getme@x.com");
107 }
108
109 #[tokio::test]
110 async fn get_user_fails_for_unknown() {
111 let (store, events) = setup();
112 let svc = AdminService::new(store, events, 3600);
113 assert!(svc.get_user(Uuid::new_v4()).await.is_err());
114 }
115
116 #[tokio::test]
117 async fn list_users_paginated() {
118 let (store, events) = setup();
119 for i in 0..5 {
120 make_user(&store, &format!("u{}@x.com", i)).await;
121 }
122 let svc = AdminService::new(store.clone(), events, 3600);
123 let page = svc.list_users(2, 2).await.unwrap();
124 assert_eq!(page.len(), 2);
125 }
126
127 #[tokio::test]
128 async fn create_user_admin() {
129 let (store, events) = setup();
130 let admin_id = make_user(&store, "admin@x.com").await;
131 let svc = AdminService::new(store.clone(), events, 3600);
132 let user = svc.create_user(admin_id, "new@x.com".into()).await.unwrap();
133 assert_eq!(user.email, "new@x.com");
134 }
135}