1use std::sync::Arc;
9
10use async_trait::async_trait;
11use openapp_sdk_common::ApiKey;
12
13use crate::error::SdkError;
14
15#[derive(Debug, Clone)]
17pub struct AuthToken {
18 pub authorization: String,
20}
21
22#[async_trait]
24pub trait TokenProvider: Send + Sync + std::fmt::Debug {
25 async fn token(&self) -> Result<AuthToken, SdkError>;
28}
29
30pub type SharedTokenProvider = Arc<dyn TokenProvider>;
32
33#[derive(Debug, Clone)]
35pub struct StaticApiKey {
36 key: ApiKey,
37}
38
39impl StaticApiKey {
40 #[must_use]
42 pub fn new(key: ApiKey) -> Self {
43 Self { key }
44 }
45
46 pub fn from_raw(token: impl Into<String>) -> Result<Self, SdkError> {
48 Ok(Self::new(ApiKey::parse(token)?))
49 }
50
51 #[must_use]
53 pub fn api_key(&self) -> &ApiKey {
54 &self.key
55 }
56}
57
58#[async_trait]
59impl TokenProvider for StaticApiKey {
60 async fn token(&self) -> Result<AuthToken, SdkError> {
61 Ok(AuthToken {
62 authorization: format!("Bearer {}", self.key.as_bearer()),
63 })
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[tokio::test]
72 async fn static_provider_emits_bearer() {
73 let provider =
74 StaticApiKey::from_raw("https://api.openapp.house/api/v1_openapp_SECRET").unwrap();
75 let token = provider.token().await.unwrap();
76 assert_eq!(
77 token.authorization,
78 "Bearer https://api.openapp.house/api/v1_openapp_SECRET"
79 );
80 }
81}