use super::port::{PasAuthPort, PasFailure};
use crate::oauth::TokenResponse;
use crate::session_liveness::{EncryptedRefreshToken, TokenCipher};
#[derive(Debug)]
#[must_use]
#[non_exhaustive]
pub enum PasRefreshOutcome {
Refreshed { tokens: TokenResponse },
Rejected { status: u16, detail: String },
Transient { detail: String },
}
#[derive(Debug)]
pub struct CipherFailure;
pub async fn pas_refresh<P: PasAuthPort>(
cipher: &TokenCipher,
port: &P,
ct: &EncryptedRefreshToken,
) -> Result<PasRefreshOutcome, CipherFailure> {
let plaintext = cipher.decrypt(ct.as_str()).map_err(|_| CipherFailure)?;
Ok(match port.refresh(&plaintext).await {
Ok(tokens) => PasRefreshOutcome::Refreshed { tokens },
Err(PasFailure::Rejected { status, detail }) => {
PasRefreshOutcome::Rejected { status, detail }
}
Err(PasFailure::ServerError { detail, .. }) | Err(PasFailure::Transport { detail }) => {
PasRefreshOutcome::Transient { detail }
}
})
}