docbox_search/typesense/
api_key.rs1use super::TypesenseSearchError;
2use docbox_secrets::{Secret, SecretManager};
3use serde::{Deserialize, Serialize};
4use std::fmt::Debug;
5use tokio::sync::Mutex;
6
7pub enum TypesenseApiKeyProvider {
9 ApiKey(TypesenseApiKey),
10 Secret(TypesenseApiKeySecret),
11}
12
13impl ApiKeyProvider for TypesenseApiKeyProvider {
14 async fn get_api_key(&self) -> Result<String, TypesenseSearchError> {
15 match self {
16 TypesenseApiKeyProvider::ApiKey(value) => value.get_api_key().await,
17 TypesenseApiKeyProvider::Secret(value) => value.get_api_key().await,
18 }
19 }
20}
21
22pub(crate) trait ApiKeyProvider {
24 async fn get_api_key(&self) -> Result<String, TypesenseSearchError>;
25}
26
27pub struct TypesenseApiKeySecret {
29 secrets: SecretManager,
31
32 secret_name: String,
34
35 secret_value: Mutex<Option<String>>,
37}
38
39impl TypesenseApiKeySecret {
40 pub fn new(secrets: SecretManager, secret_name: String) -> Self {
41 Self {
42 secrets,
43 secret_name,
44 secret_value: Default::default(),
45 }
46 }
47}
48
49impl ApiKeyProvider for TypesenseApiKeySecret {
50 async fn get_api_key(&self) -> Result<String, TypesenseSearchError> {
51 let secret_value = &mut *self.secret_value.lock().await;
52 if let Some(value) = secret_value.as_ref() {
53 return Ok(value.clone());
54 }
55
56 match self.secrets.get_secret(&self.secret_name).await {
57 Ok(Some(Secret::String(value))) => Ok(value),
58
59 Ok(Some(Secret::Binary(_))) => {
60 tracing::error!("expected string secret for typesense api key but got binary");
61 Err(TypesenseSearchError::GetSecret)
62 }
63
64 Ok(None) => {
65 tracing::error!(secret_name = ?self.secret_name, "secret not found");
66 Err(TypesenseSearchError::GetSecret)
67 }
68
69 Err(error) => {
70 tracing::error!(?error, "failed to get api key secret");
71 Err(TypesenseSearchError::GetSecret)
72 }
73 }
74 }
75}
76
77#[derive(Clone, Deserialize, Serialize)]
79#[serde(transparent)]
80pub struct TypesenseApiKey(String);
81
82impl TypesenseApiKey {
83 pub fn new(value: String) -> Self {
84 Self(value)
85 }
86}
87
88impl Debug for TypesenseApiKey {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 f.write_str("< API KEY >")
92 }
93}
94
95impl ApiKeyProvider for TypesenseApiKey {
96 async fn get_api_key(&self) -> Result<String, TypesenseSearchError> {
97 Ok(self.0.clone())
98 }
99}