salvo_csrf/
session_store.rs1use salvo_core::{Depot, Error, Request, Response};
2use salvo_session::SessionDepotExt;
3
4use super::{CsrfCipher, CsrfStore};
5
6#[derive(Debug)]
8pub struct SessionStore {
9 name: String,
10}
11impl Default for SessionStore {
12 fn default() -> Self {
13 Self::new()
14 }
15}
16
17impl SessionStore {
18 #[must_use]
20 pub fn new() -> Self {
21 Self {
22 name: "salvo.csrf".into(),
23 }
24 }
25}
26
27impl CsrfStore for SessionStore {
28 type Error = Error;
29 async fn load<C: CsrfCipher>(&self, _req: &mut Request, depot: &mut Depot, _cipher: &C) -> Option<(String, String)> {
30 depot
31 .session()
32 .and_then(|s| s.get::<String>(&self.name))
33 .and_then(|s| s.split_once('.').map(|(t, p)| (t.into(), p.into())))
34 }
35 async fn save(
36 &self,
37 _req: &mut Request,
38 depot: &mut Depot,
39 _res: &mut Response,
40 token: &str,
41 proof: &str,
42 ) -> Result<(), Self::Error> {
43 let Some(session) = depot.session_mut() else {
44 return Err(Error::other(
45 "session is not available in depot; add SessionHandler before Csrf<_, SessionStore>",
46 ));
47 };
48 session.insert(&self.name, format!("{token}.{proof}"))?;
49 Ok(())
50 }
51}