use async_trait::async_trait;
use crate::error::SaTokenResult;
#[async_trait]
pub trait SloNotifier: Send + Sync {
async fn notify_logout(&self, logout_url: &str, login_id: &str) -> SaTokenResult<()>;
}
pub struct NoopSloNotifier;
#[async_trait]
impl SloNotifier for NoopSloNotifier {
async fn notify_logout(&self, _logout_url: &str, _login_id: &str) -> SaTokenResult<()> {
Ok(())
}
}
impl std::fmt::Debug for NoopSloNotifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("NoopSloNotifier { .. }")
}
}
#[cfg(feature = "sso-http")]
pub struct HttpSloNotifier {
client: reqwest::Client,
}
#[cfg(feature = "sso-http")]
impl HttpSloNotifier {
pub fn new() -> Self {
Self {
client: reqwest::Client::new(),
}
}
}
#[cfg(feature = "sso-http")]
impl Default for HttpSloNotifier {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "sso-http")]
#[async_trait]
impl SloNotifier for HttpSloNotifier {
async fn notify_logout(&self, logout_url: &str, login_id: &str) -> SaTokenResult<()> {
let resp = self
.client
.post(logout_url)
.form(&[("loginId", login_id)])
.send()
.await
.map_err(|e| {
crate::error::SaTokenError::StorageError(format!("SLO notify failed: {e}"))
})?;
if resp.status().is_success() {
Ok(())
} else {
Err(crate::error::SaTokenError::StorageError(format!(
"SLO notify HTTP {}",
resp.status()
)))
}
}
}