cli_engine/auth/
credential.rs1use chrono::{DateTime, Duration, Utc};
2use serde::{Deserialize, Serialize};
3
4pub const CACHE_TTL: Duration = Duration::minutes(30);
6
7#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
12pub struct Credential {
13 #[serde(default)]
15 pub token: String,
16 #[serde(default)]
18 pub expires_at: String,
19 #[serde(default, skip_serializing_if = "String::is_empty")]
21 pub cached_at: String,
22 #[serde(default, skip_serializing_if = "String::is_empty")]
24 pub provider: String,
25 #[serde(default, skip_serializing_if = "String::is_empty")]
27 pub env: String,
28 #[serde(default, skip_serializing_if = "String::is_empty")]
30 pub realm: String,
31 #[serde(default, skip_serializing_if = "String::is_empty")]
33 pub identity: String,
34 #[serde(default, skip_serializing_if = "String::is_empty")]
36 pub sub: String,
37 #[serde(default, skip_serializing_if = "String::is_empty")]
39 pub account_type: String,
40}
41
42impl Credential {
43 #[must_use]
45 pub fn effective_expiry(&self) -> String {
46 if let Ok(cached_at) = DateTime::parse_from_rfc3339(&self.cached_at) {
47 return (cached_at.with_timezone(&Utc) + CACHE_TTL)
48 .to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
49 }
50 self.expires_at.clone()
51 }
52
53 #[must_use]
58 pub fn is_expired(&self) -> bool {
59 if let Ok(cached_at) = DateTime::parse_from_rfc3339(&self.cached_at) {
60 return Utc::now() > cached_at.with_timezone(&Utc) + CACHE_TTL;
61 }
62 if self.expires_at.is_empty() {
63 return false;
64 }
65 match DateTime::parse_from_rfc3339(&self.expires_at) {
66 Ok(expires_at) => Utc::now() > expires_at.with_timezone(&Utc),
67 Err(_) => true,
68 }
69 }
70}