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.insert(
25 key,
26 AuthenticatedUser {
27 id: user_id,
28 role,
29 tenant_id: None,
30 },
31 );
32 }
33
34 pub fn lookup(&self, key: &str) -> Option<AuthenticatedUser> {
36 self.keys.get(key).cloned()
37 }
38
39 pub fn len(&self) -> usize {
41 self.keys.len()
42 }
43
44 pub fn is_empty(&self) -> bool {
46 self.keys.is_empty()
47 }
48}
49
50impl Default for ApiKeyStore {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn insert_and_lookup() {
62 let mut store = ApiKeyStore::new();
63 store.insert(
64 "sk-test-123".to_string(),
65 "user-1".to_string(),
66 "admin".to_string(),
67 );
68 let user = store.lookup("sk-test-123");
69 assert!(user.is_some());
70 let user = user.unwrap();
71 assert_eq!(user.id, "user-1");
72 assert_eq!(user.role, "admin");
73 }
74
75 #[test]
76 fn lookup_missing_returns_none() {
77 let store = ApiKeyStore::new();
78 assert!(store.lookup("nonexistent").is_none());
79 }
80
81 #[test]
82 fn len_and_is_empty() {
83 let mut store = ApiKeyStore::new();
84 assert!(store.is_empty());
85 assert_eq!(store.len(), 0);
86
87 store.insert("k1".to_string(), "u1".to_string(), "admin".to_string());
88 assert!(!store.is_empty());
89 assert_eq!(store.len(), 1);
90 }
91}