raps_kernel/auth/
two_leg.rs1use anyhow::{Context, Result};
7use std::time::{Duration, Instant};
8
9use super::AuthClient;
10use super::types::{CachedToken, TokenResponse};
11
12impl AuthClient {
13 pub async fn get_token(&self) -> Result<String> {
15 {
17 let cache = self.cached_2leg_token.read().await;
18 if let Some(ref token) = *cache
19 && token.is_valid()
20 {
21 return Ok(token.access_token.clone());
22 }
23 }
24
25 let new_token = self.fetch_2leg_token().await?;
27
28 {
30 let mut cache = self.cached_2leg_token.write().await;
31 *cache = Some(CachedToken {
32 access_token: new_token.access_token.clone(),
33 expires_at: Instant::now() + Duration::from_secs(new_token.expires_in),
34 });
35 }
36
37 Ok(new_token.access_token)
38 }
39
40 async fn fetch_2leg_token(&self) -> Result<TokenResponse> {
42 self.config.require_credentials()?;
43
44 let url = self.config.auth_url();
45
46 let params = [
47 ("grant_type", "client_credentials"),
48 (
49 "scope",
50 "data:read data:write data:create bucket:read bucket:create bucket:delete code:all",
51 ),
52 ];
53
54 let _auth_start = std::time::Instant::now();
55 let response = self
56 .http_client
57 .post(&url)
58 .basic_auth(&self.config.client_id, Some(&self.config.client_secret))
59 .form(¶ms)
60 .send()
61 .await
62 .context("Failed to send authentication request")?;
63 crate::profiler::record_http_request(_auth_start.elapsed());
64
65 if !response.status().is_success() {
66 let status = response.status();
67 let error_text = response.text().await.unwrap_or_default();
68 anyhow::bail!(
69 "Authentication failed with status {}: {}",
70 status,
71 crate::logging::redact_secrets(&error_text)
72 );
73 }
74
75 let token_response: TokenResponse = response
76 .json()
77 .await
78 .context("Failed to parse token response")?;
79
80 Ok(token_response)
81 }
82
83 pub async fn test_auth(&self) -> Result<()> {
85 self.get_token().await?;
86 Ok(())
87 }
88
89 #[allow(dead_code)]
91 pub async fn clear_cache(&self) {
92 let mut cache = self.cached_2leg_token.write().await;
93 *cache = None;
94 }
95}