litellm_rs/core/keys/
database_repository.rs1use super::db_mapping::{from_domain_api_key, to_domain_api_key};
4use super::db_update::apply_update_config;
5use super::repository::KeyRepository;
6use super::types::{KeyStatus, ManagedApiKey, UpdateKeyConfig, UsageRecord};
7use crate::storage::StorageLayer;
8use crate::utils::error::gateway_error::{GatewayError, Result};
9use async_trait::async_trait;
10use std::sync::Arc;
11use uuid::Uuid;
12
13#[derive(Debug, Clone)]
14pub struct DatabaseKeyRepository {
15 storage: Arc<StorageLayer>,
16}
17
18impl DatabaseKeyRepository {
19 pub fn new(storage: Arc<StorageLayer>) -> Self {
20 Self { storage }
21 }
22}
23
24#[async_trait]
25impl KeyRepository for DatabaseKeyRepository {
26 async fn create(&self, key: ManagedApiKey) -> Result<ManagedApiKey> {
27 let domain_key = to_domain_api_key(&key)?;
28 let stored = self.storage.db().create_api_key(&domain_key).await?;
29 Ok(from_domain_api_key(&stored))
30 }
31
32 async fn find_by_id(&self, id: Uuid) -> Result<Option<ManagedApiKey>> {
33 let key = self.storage.db().find_api_key_by_id(id).await?;
34 Ok(key.map(|k| from_domain_api_key(&k)))
35 }
36
37 async fn find_by_hash(&self, key_hash: &str) -> Result<Option<ManagedApiKey>> {
38 let key = self.storage.db().find_api_key_by_hash(key_hash).await?;
39 Ok(key.map(|k| from_domain_api_key(&k)))
40 }
41
42 async fn update(&self, id: Uuid, config: UpdateKeyConfig) -> Result<ManagedApiKey> {
43 let mut domain_key = self
44 .storage
45 .db()
46 .find_api_key_by_id(id)
47 .await?
48 .ok_or_else(|| GatewayError::not_found("API key not found"))?;
49
50 apply_update_config(&mut domain_key, config)?;
51 let updated = self.storage.db().update_api_key(&domain_key).await?;
52 Ok(from_domain_api_key(&updated))
53 }
54
55 async fn update_status(&self, id: Uuid, status: KeyStatus) -> Result<()> {
56 match status {
57 KeyStatus::Active => self.storage.db().set_api_key_active(id, true).await,
58 KeyStatus::Revoked => self.storage.db().set_api_key_active(id, false).await,
59 KeyStatus::Expired => Err(GatewayError::validation(
60 "Cannot set key status to expired manually",
61 )),
62 }
63 }
64
65 async fn update_last_used(&self, id: Uuid) -> Result<()> {
66 self.storage.db().update_api_key_last_used(id).await
67 }
68
69 async fn update_usage(&self, id: Uuid, record: UsageRecord) -> Result<()> {
70 self.storage
71 .db()
72 .update_api_key_usage(
73 id,
74 record.requests,
75 record.tokens,
76 record.cost,
77 record.unpriced,
78 record.pricing_policy.as_deref(),
79 )
80 .await
81 }
82
83 async fn list_by_user(&self, user_id: Uuid) -> Result<Vec<ManagedApiKey>> {
84 let keys = self.storage.db().list_api_keys_by_user(user_id).await?;
85 Ok(keys.into_iter().map(|k| from_domain_api_key(&k)).collect())
86 }
87
88 async fn list_by_team(&self, team_id: Uuid) -> Result<Vec<ManagedApiKey>> {
89 let keys = self.storage.db().list_api_keys_by_team(team_id).await?;
90 Ok(keys.into_iter().map(|k| from_domain_api_key(&k)).collect())
91 }
92
93 async fn list_all(
94 &self,
95 status: Option<KeyStatus>,
96 limit: Option<usize>,
97 offset: Option<usize>,
98 ) -> Result<Vec<ManagedApiKey>> {
99 let keys = self
100 .storage
101 .db()
102 .list_api_keys(status, limit, offset)
103 .await?;
104 Ok(keys.into_iter().map(|k| from_domain_api_key(&k)).collect())
105 }
106
107 async fn delete(&self, id: Uuid) -> Result<()> {
108 self.storage.db().delete_api_key(id).await
109 }
110
111 async fn delete_expired(&self) -> Result<u64> {
112 self.storage.db().delete_expired_api_keys().await
113 }
114
115 async fn count(&self, status: Option<KeyStatus>) -> Result<u64> {
116 self.storage.db().count_api_keys(status).await
117 }
118}