1use crate::embedded::{SecretsCore, SecretsError};
9use crate::spec_compat::SecretUri;
10use crate::types::Scope;
11use greentic_types::{ApiKeyRef, DistributorRef, RepoRef, TenantCtx};
12use tracing::info;
13
14pub fn repo_api_key_uri(tenant: &TenantCtx, repo_ref: &RepoRef) -> Result<SecretUri, SecretsError> {
16 let scope = scope_from_tenant(tenant)?;
17 let name = format!("repo__{}__api-key", repo_ref.as_str());
18 SecretUri::new(scope, "store", name).map_err(SecretsError::from)
19}
20
21pub fn distributor_api_key_uri(
23 tenant: &TenantCtx,
24 distributor_ref: &DistributorRef,
25) -> Result<SecretUri, SecretsError> {
26 let scope = scope_from_tenant(tenant)?;
27 let name = format!("{}__api-key", distributor_ref.as_str());
28 SecretUri::new(scope, "distributor", name).map_err(SecretsError::from)
29}
30
31pub fn billing_api_key_uri(
33 tenant: &TenantCtx,
34 billing_provider_id: &str,
35) -> Result<SecretUri, SecretsError> {
36 let scope = scope_from_tenant(tenant)?;
37 let name = format!("{billing_provider_id}__api-key");
38 SecretUri::new(scope, "billing", name).map_err(SecretsError::from)
39}
40
41pub async fn get_repo_api_key_ref(
43 core: &SecretsCore,
44 tenant: &TenantCtx,
45 repo_ref: &RepoRef,
46) -> Result<ApiKeyRef, SecretsError> {
47 let uri = repo_api_key_uri(tenant, repo_ref)?;
48 fetch_api_key_ref(core, tenant, "store", repo_ref.as_str(), &uri).await
49}
50
51pub async fn get_distributor_api_key_ref(
53 core: &SecretsCore,
54 tenant: &TenantCtx,
55 distributor_ref: &DistributorRef,
56) -> Result<ApiKeyRef, SecretsError> {
57 let uri = distributor_api_key_uri(tenant, distributor_ref)?;
58 fetch_api_key_ref(core, tenant, "distributor", distributor_ref.as_str(), &uri).await
59}
60
61pub async fn get_billing_provider_api_key_ref(
63 core: &SecretsCore,
64 tenant: &TenantCtx,
65 billing_provider_id: &str,
66) -> Result<ApiKeyRef, SecretsError> {
67 let uri = billing_api_key_uri(tenant, billing_provider_id)?;
68 fetch_api_key_ref(core, tenant, "billing", billing_provider_id, &uri).await
69}
70
71async fn fetch_api_key_ref(
72 core: &SecretsCore,
73 tenant: &TenantCtx,
74 category: &str,
75 subject: &str,
76 uri: &SecretUri,
77) -> Result<ApiKeyRef, SecretsError> {
78 let res = core.get_json::<ApiKeyRef>(&uri.to_string()).await;
79 match &res {
80 Ok(value) => info!(
81 tenant = %tenant.tenant_id,
82 team = ?tenant.team,
83 category,
84 subject,
85 api_key_ref = %value.0,
86 "retrieved api key reference",
87 ),
88 Err(err) => info!(
89 tenant = %tenant.tenant_id,
90 team = ?tenant.team,
91 category,
92 subject,
93 error = %err,
94 "failed to retrieve api key reference",
95 ),
96 }
97 res
98}
99
100fn scope_from_tenant(ctx: &TenantCtx) -> Result<Scope, SecretsError> {
101 let env = ctx.env.as_ref();
102 let tenant = ctx.tenant_id.as_ref();
103 let team = ctx
104 .team
105 .as_ref()
106 .or(ctx.team_id.as_ref())
107 .map(|team| team.as_ref().to_string());
108 Scope::new(env, tenant, team).map_err(SecretsError::from)
109}