kanidmd_core/https/views/
cookies.rsuse crate::https::ServerState;
use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite};
use compact_jwt::{Jws, JwsSigner};
use serde::de::DeserializeOwned;
use serde::Serialize;
fn new_cookie<'a>(state: &'_ ServerState, ck_id: &'a str, value: String) -> Cookie<'a> {
let mut token_cookie = Cookie::new(ck_id, value);
token_cookie.set_secure(state.secure_cookies);
token_cookie.set_same_site(SameSite::Lax);
token_cookie.set_http_only(true);
token_cookie.set_domain(state.domain.clone());
token_cookie.set_path("/");
token_cookie
}
#[instrument(name = "views::cookies::destroy", level = "debug", skip(jar, state))]
pub fn destroy(jar: CookieJar, ck_id: &str, state: &ServerState) -> CookieJar {
if let Some(ck) = jar.get(ck_id) {
let mut removal_cookie = ck.clone();
removal_cookie.make_removal();
removal_cookie.set_domain(state.domain.clone());
removal_cookie.set_path("/");
jar.add(removal_cookie)
} else {
jar
}
}
pub fn make_unsigned<'a>(state: &'_ ServerState, ck_id: &'a str, value: String) -> Cookie<'a> {
new_cookie(state, ck_id, value)
}
pub fn make_signed<'a, T: Serialize>(
state: &'_ ServerState,
ck_id: &'a str,
value: &'_ T,
) -> Option<Cookie<'a>> {
let kref = &state.jws_signer;
let jws = Jws::into_json(value)
.map_err(|e| {
error!(?e);
})
.ok()?;
let token = kref
.sign(&jws)
.map(|jwss| jwss.to_string())
.map_err(|e| {
error!(?e);
})
.ok()?;
Some(new_cookie(state, ck_id, token))
}
pub fn get_signed<T: DeserializeOwned>(
state: &ServerState,
jar: &CookieJar,
ck_id: &str,
) -> Option<T> {
jar.get(ck_id)
.map(|c| c.value())
.and_then(|s| state.deserialise_from_str::<T>(s))
}
pub fn get_unsigned<'a>(jar: &'a CookieJar, ck_id: &'_ str) -> Option<&'a str> {
jar.get(ck_id).map(|c| c.value())
}