kanidmd_core/https/views/
cookies.rs
1use crate::https::ServerState;
4use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite};
5use compact_jwt::{Jws, JwsSigner};
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8
9fn new_cookie<'a>(state: &'_ ServerState, ck_id: &'a str, value: String) -> Cookie<'a> {
10 let mut token_cookie = Cookie::new(ck_id, value);
11 token_cookie.set_secure(state.secure_cookies);
12 token_cookie.set_same_site(SameSite::Lax);
13 token_cookie.set_http_only(true);
15 token_cookie.set_domain(state.domain.clone());
19 token_cookie.set_path("/");
20 token_cookie
21}
22
23#[instrument(name = "views::cookies::destroy", level = "debug", skip(jar, state))]
24pub fn destroy(jar: CookieJar, ck_id: &str, state: &ServerState) -> CookieJar {
25 if let Some(ck) = jar.get(ck_id) {
26 let mut removal_cookie = ck.clone();
27 removal_cookie.make_removal();
28
29 removal_cookie.set_domain(state.domain.clone());
31
32 removal_cookie.set_path("/");
35
36 jar.add(removal_cookie)
37 } else {
38 jar
39 }
40}
41
42pub fn make_unsigned<'a>(state: &'_ ServerState, ck_id: &'a str, value: String) -> Cookie<'a> {
43 new_cookie(state, ck_id, value)
44}
45
46pub fn make_signed<'a, T: Serialize>(
47 state: &'_ ServerState,
48 ck_id: &'a str,
49 value: &'_ T,
50) -> Option<Cookie<'a>> {
51 let kref = &state.jws_signer;
52
53 let jws = Jws::into_json(value)
54 .map_err(|e| {
55 error!(?e);
56 })
57 .ok()?;
58
59 let token = kref
61 .sign(&jws)
62 .map(|jwss| jwss.to_string())
63 .map_err(|e| {
64 error!(?e);
65 })
66 .ok()?;
67
68 Some(new_cookie(state, ck_id, token))
69}
70
71pub fn get_signed<T: DeserializeOwned>(
72 state: &ServerState,
73 jar: &CookieJar,
74 ck_id: &str,
75) -> Option<T> {
76 jar.get(ck_id)
77 .map(|c| c.value())
78 .and_then(|s| state.deserialise_from_str::<T>(s))
79}
80
81pub fn get_unsigned<'a>(jar: &'a CookieJar, ck_id: &'_ str) -> Option<&'a str> {
82 jar.get(ck_id).map(|c| c.value())
83}