mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-05-09 05:21:23 +02:00
Change OAuth2 expiration handling to use i64 for timestamps
This commit is contained in:
parent
c47afbf4f5
commit
8db5c43134
2 changed files with 8 additions and 14 deletions
|
|
@ -106,7 +106,7 @@ static CAN_BACKUP: LazyLock<bool> =
|
|||
static CAN_BACKUP: LazyLock<bool> = LazyLock::new(|| false);
|
||||
|
||||
// OAuth2 state storage for CSRF protection (state -> expiration timestamp)
|
||||
static OAUTH2_STATES: LazyLock<RwLock<HashMap<String, u64>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||
static OAUTH2_STATES: LazyLock<RwLock<HashMap<String, i64>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||
|
||||
#[get("/")]
|
||||
fn admin_disabled() -> &'static str {
|
||||
|
|
@ -372,9 +372,7 @@ fn oauth2_authorize(_token: AdminToken) -> Result<Redirect, Error> {
|
|||
let state = crate::crypto::encode_random_bytes::<32>(&BASE64URL_NOPAD);
|
||||
|
||||
// Store state with expiration (10 minutes from now)
|
||||
// Multiple calls to Utc::now().timestamp() can return a negative value if the system time is set before the UNIX epoch.
|
||||
// While extremely rare in practice, we handle this by using unwrap_or_default() to prevent huge values when casting to u64.
|
||||
let now = u64::try_from(Utc::now().timestamp()).unwrap_or_default();
|
||||
let now = Utc::now().timestamp();
|
||||
let expiration = now + 600;
|
||||
|
||||
OAUTH2_STATES.write().unwrap().insert(state.clone(), expiration);
|
||||
|
|
@ -433,7 +431,7 @@ async fn oauth2_callback(
|
|||
// Validate state token
|
||||
let valid_state = {
|
||||
let states = OAUTH2_STATES.read().unwrap();
|
||||
let now = u64::try_from(Utc::now().timestamp()).unwrap_or_default();
|
||||
let now = Utc::now().timestamp();
|
||||
states.get(&state).is_some_and(|&exp| exp > now)
|
||||
};
|
||||
|
||||
|
|
|
|||
14
src/mail.rs
14
src/mail.rs
|
|
@ -31,7 +31,7 @@ use crate::http_client::make_http_request;
|
|||
pub struct OAuth2Token {
|
||||
access_token: String,
|
||||
refresh_token: Option<String>,
|
||||
expires_at: Option<u64>,
|
||||
expires_at: Option<i64>,
|
||||
token_type: String,
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ pub struct OAuth2Token {
|
|||
struct TokenRefreshResponse {
|
||||
access_token: String,
|
||||
refresh_token: Option<String>,
|
||||
expires_in: Option<u64>,
|
||||
expires_in: Option<i64>,
|
||||
token_type: String,
|
||||
}
|
||||
|
||||
|
|
@ -78,11 +78,7 @@ pub async fn refresh_oauth2_token() -> Result<OAuth2Token, Error> {
|
|||
Err(e) => err!(format!("OAuth2 Token Parse Error: {e}")),
|
||||
};
|
||||
|
||||
let expires_at = token_response.expires_in.map(|expires_in| {
|
||||
// Multiple calls to Utc::now().timestamp() can return a negative value if the system time is set before the UNIX epoch.
|
||||
// While extremely rare in practice, we handle this by using unwrap_or_default() to prevent huge values when casting to u64.
|
||||
u64::try_from(Utc::now().timestamp()).unwrap_or_default() + expires_in
|
||||
});
|
||||
let expires_at = token_response.expires_in.map(|expires_in| Utc::now().timestamp() + expires_in);
|
||||
|
||||
let new_token = OAuth2Token {
|
||||
access_token: token_response.access_token,
|
||||
|
|
@ -106,7 +102,7 @@ async fn get_valid_oauth2_token() -> Result<OAuth2Token, Error> {
|
|||
if let Some(token) = token_cache.as_ref() {
|
||||
// Check if token is still valid (with 5 min buffer)
|
||||
if let Some(expires_at) = token.expires_at {
|
||||
let now = u64::try_from(Utc::now().timestamp()).unwrap_or_default();
|
||||
let now = Utc::now().timestamp();
|
||||
if now + 300 < expires_at {
|
||||
return Ok(token.clone());
|
||||
}
|
||||
|
|
@ -120,7 +116,7 @@ async fn get_valid_oauth2_token() -> Result<OAuth2Token, Error> {
|
|||
// Double check
|
||||
if let Some(token) = token_cache.as_ref() {
|
||||
if let Some(expires_at) = token.expires_at {
|
||||
let now = u64::try_from(Utc::now().timestamp()).unwrap_or_default();
|
||||
let now = Utc::now().timestamp();
|
||||
if now + 300 < expires_at {
|
||||
return Ok(token.clone());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue