mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-03-22 09:49:20 -07:00
Add 30s cache to SSO exchange_refresh_token (#6866)
Co-authored-by: Timshel <timshel@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use std::{borrow::Cow, sync::LazyLock, time::Duration};
|
||||
|
||||
use mini_moka::sync::Cache;
|
||||
use openidconnect::{core::*, reqwest, *};
|
||||
use regex::Regex;
|
||||
use url::Url;
|
||||
@@ -13,9 +12,14 @@ use crate::{
|
||||
};
|
||||
|
||||
static CLIENT_CACHE_KEY: LazyLock<String> = LazyLock::new(|| "sso-client".to_string());
|
||||
static CLIENT_CACHE: LazyLock<Cache<String, Client>> = LazyLock::new(|| {
|
||||
Cache::builder().max_capacity(1).time_to_live(Duration::from_secs(CONFIG.sso_client_cache_expiration())).build()
|
||||
static CLIENT_CACHE: LazyLock<moka::sync::Cache<String, Client>> = LazyLock::new(|| {
|
||||
moka::sync::Cache::builder()
|
||||
.max_capacity(1)
|
||||
.time_to_live(Duration::from_secs(CONFIG.sso_client_cache_expiration()))
|
||||
.build()
|
||||
});
|
||||
static REFRESH_CACHE: LazyLock<moka::future::Cache<String, Result<RefreshTokenResponse, String>>> =
|
||||
LazyLock::new(|| moka::future::Cache::builder().max_capacity(1000).time_to_live(Duration::from_secs(30)).build());
|
||||
|
||||
/// OpenID Connect Core client.
|
||||
pub type CustomClient = openidconnect::Client<
|
||||
@@ -38,6 +42,8 @@ pub type CustomClient = openidconnect::Client<
|
||||
EndpointSet,
|
||||
>;
|
||||
|
||||
pub type RefreshTokenResponse = (Option<String>, String, Option<Duration>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Client {
|
||||
pub http_client: reqwest::Client,
|
||||
@@ -231,23 +237,29 @@ impl Client {
|
||||
verifier
|
||||
}
|
||||
|
||||
pub async fn exchange_refresh_token(
|
||||
refresh_token: String,
|
||||
) -> ApiResult<(Option<String>, String, Option<Duration>)> {
|
||||
pub async fn exchange_refresh_token(refresh_token: String) -> ApiResult<RefreshTokenResponse> {
|
||||
let client = Client::cached().await?;
|
||||
|
||||
REFRESH_CACHE
|
||||
.get_with(refresh_token.clone(), async move { client._exchange_refresh_token(refresh_token).await })
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
async fn _exchange_refresh_token(&self, refresh_token: String) -> Result<RefreshTokenResponse, String> {
|
||||
let rt = RefreshToken::new(refresh_token);
|
||||
|
||||
let client = Client::cached().await?;
|
||||
let token_response =
|
||||
match client.core_client.exchange_refresh_token(&rt).request_async(&client.http_client).await {
|
||||
Err(err) => err!(format!("Request to exchange_refresh_token endpoint failed: {:?}", err)),
|
||||
Ok(token_response) => token_response,
|
||||
};
|
||||
|
||||
Ok((
|
||||
token_response.refresh_token().map(|token| token.secret().clone()),
|
||||
token_response.access_token().secret().clone(),
|
||||
token_response.expires_in(),
|
||||
))
|
||||
match self.core_client.exchange_refresh_token(&rt).request_async(&self.http_client).await {
|
||||
Err(err) => {
|
||||
error!("Request to exchange_refresh_token endpoint failed: {err}");
|
||||
Err(format!("Request to exchange_refresh_token endpoint failed: {err}"))
|
||||
}
|
||||
Ok(token_response) => Ok((
|
||||
token_response.refresh_token().map(|token| token.secret().clone()),
|
||||
token_response.access_token().secret().clone(),
|
||||
token_response.expires_in(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user