use crate::extension::CaptchaUtil;
use crate::AbstractCaptcha;
use async_trait::async_trait;
use axum::response::Response;
use log::warn;
use std::fmt::Debug;
use tower_sessions::Session;
const CAPTCHA_KEY: &'static str = "ez-captcha";
#[async_trait]
pub trait CaptchaAxumTowerSessionExt {
type Error: Debug + Send + Sync + 'static;
async fn out(&mut self, session: &Session) -> Result<Response, Self::Error>;
}
#[async_trait]
pub trait CaptchaAxumTowerSessionStaticExt {
async fn ver(code: &str, session: &Session) -> bool {
match session.get::<String>(CAPTCHA_KEY).await {
Ok(Some(ans)) => ans.to_ascii_lowercase() == code.to_ascii_lowercase(),
_ => false,
}
}
async fn clear(session: &Session) {
if session.remove::<String>(CAPTCHA_KEY).await.is_err() {
warn!("Exception occurs during clearing the session.")
}
}
}
#[async_trait]
impl<T: AbstractCaptcha + Send> CaptchaAxumTowerSessionExt for CaptchaUtil<T> {
type Error = anyhow::Error;
async fn out(&mut self, session: &Session) -> Result<Response, Self::Error> {
let mut data = vec![];
self.captcha_instance.out(&mut data)?;
let ans: String = self.captcha_instance.get_chars().iter().collect();
session.insert(CAPTCHA_KEY, ans).await?;
let resp = Response::builder()
.header("Content-Type", self.captcha_instance.get_content_type())
.body(data.into())?;
Ok(resp)
}
}
#[async_trait]
impl CaptchaAxumTowerSessionStaticExt for CaptchaUtil {}