shaperail_runtime/auth/
api_key.rs1use std::collections::HashMap;
2
3use super::extractor::AuthenticatedUser;
4
5#[derive(Debug, Clone)]
10pub struct ApiKeyStore {
11 keys: HashMap<String, AuthenticatedUser>,
12}
13
14impl ApiKeyStore {
15 pub fn new() -> Self {
17 Self {
18 keys: HashMap::new(),
19 }
20 }
21
22 pub fn insert(&mut self, key: String, user_id: String, role: String) {
24 self.keys
25 .insert(key, AuthenticatedUser { id: user_id, role });
26 }
27
28 pub fn lookup(&self, key: &str) -> Option<AuthenticatedUser> {
30 self.keys.get(key).cloned()
31 }
32
33 pub fn len(&self) -> usize {
35 self.keys.len()
36 }
37
38 pub fn is_empty(&self) -> bool {
40 self.keys.is_empty()
41 }
42}
43
44impl Default for ApiKeyStore {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn insert_and_lookup() {
56 let mut store = ApiKeyStore::new();
57 store.insert(
58 "sk-test-123".to_string(),
59 "user-1".to_string(),
60 "admin".to_string(),
61 );
62 let user = store.lookup("sk-test-123");
63 assert!(user.is_some());
64 let user = user.unwrap();
65 assert_eq!(user.id, "user-1");
66 assert_eq!(user.role, "admin");
67 }
68
69 #[test]
70 fn lookup_missing_returns_none() {
71 let store = ApiKeyStore::new();
72 assert!(store.lookup("nonexistent").is_none());
73 }
74
75 #[test]
76 fn len_and_is_empty() {
77 let mut store = ApiKeyStore::new();
78 assert!(store.is_empty());
79 assert_eq!(store.len(), 0);
80
81 store.insert("k1".to_string(), "u1".to_string(), "admin".to_string());
82 assert!(!store.is_empty());
83 assert_eq!(store.len(), 1);
84 }
85}