1use std::fmt;
4
5use cookie::{Cookie, CookieJar, Key};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
24#[non_exhaustive]
25pub enum SameSite {
26 Strict,
27 Lax,
28 None,
29}
30
31impl SameSite {
32 #[allow(dead_code)]
33 pub(crate) fn from_cookie_same_site(value: cookie::SameSite) -> SameSite {
34 match value {
35 cookie::SameSite::Strict => SameSite::Strict,
36 cookie::SameSite::Lax => SameSite::Lax,
37 cookie::SameSite::None => SameSite::None,
38 }
39 }
40
41 #[allow(dead_code)]
42 pub(crate) fn into_cookie_same_site(self) -> cookie::SameSite {
43 match self {
44 SameSite::Strict => cookie::SameSite::Strict,
45 SameSite::Lax => cookie::SameSite::Lax,
46 SameSite::None => cookie::SameSite::None,
47 }
48 }
49}
50
51impl fmt::Display for SameSite {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 match self {
54 SameSite::Strict => f.write_str("Strict"),
55 SameSite::Lax => f.write_str("Lax"),
56 SameSite::None => f.write_str("None"),
57 }
58 }
59}
60
61#[doc(hidden)]
63pub trait CookieSecurity: Clone + private::Sealed {
64 fn get<'c>(&self, jar: &'c CookieJar, name: &str) -> Option<Cookie<'c>>;
65 fn add(&self, jar: &mut CookieJar, cookie: Cookie<'static>);
66 fn remove(&self, jar: &mut CookieJar, cookie: Cookie<'static>);
67 fn into_key(self) -> Key;
68}
69
70#[doc(hidden)]
71#[derive(Clone, Debug)]
72pub struct SignedCookie {
73 key: Key,
74}
75
76#[doc(hidden)]
77#[derive(Clone, Debug)]
78pub struct PrivateCookie {
79 key: Key,
80}
81
82#[doc(hidden)]
83#[non_exhaustive]
84#[derive(Clone, Debug)]
85pub struct PlainCookie;
86
87impl SignedCookie {
88 pub(crate) fn new(key: Key) -> Self {
89 Self { key }
90 }
91}
92
93impl PrivateCookie {
94 pub(crate) fn new(key: Key) -> Self {
95 Self { key }
96 }
97}
98
99impl CookieSecurity for SignedCookie {
100 #[inline]
101 fn get<'c>(&self, jar: &'c CookieJar, name: &str) -> Option<Cookie<'c>> {
102 jar.signed(&self.key).get(name)
103 }
104
105 #[inline]
106 fn add(&self, jar: &mut CookieJar, cookie: Cookie<'static>) {
107 jar.signed_mut(&self.key).add(cookie)
108 }
109
110 #[inline]
111 fn remove(&self, jar: &mut CookieJar, cookie: Cookie<'static>) {
112 jar.signed_mut(&self.key).remove(cookie)
113 }
114
115 #[inline]
116 fn into_key(self) -> Key {
117 self.key
118 }
119}
120impl private::Sealed for SignedCookie {}
121
122impl CookieSecurity for PrivateCookie {
123 #[inline]
124 fn get<'c>(&self, jar: &'c CookieJar, name: &str) -> Option<Cookie<'c>> {
125 jar.private(&self.key).get(name)
126 }
127
128 #[inline]
129 fn add(&self, jar: &mut CookieJar, cookie: Cookie<'static>) {
130 jar.private_mut(&self.key).add(cookie)
131 }
132
133 #[inline]
134 fn remove(&self, jar: &mut CookieJar, cookie: Cookie<'static>) {
135 jar.private_mut(&self.key).remove(cookie)
136 }
137
138 #[inline]
139 fn into_key(self) -> Key {
140 self.key
141 }
142}
143impl private::Sealed for PrivateCookie {}
144
145impl CookieSecurity for PlainCookie {
146 #[inline]
147 fn get<'c>(&self, jar: &'c CookieJar, name: &str) -> Option<Cookie<'c>> {
148 jar.get(name).cloned()
149 }
150
151 #[inline]
152 fn add(&self, jar: &mut CookieJar, cookie: Cookie<'static>) {
153 jar.add(cookie)
154 }
155
156 #[inline]
157 fn remove(&self, jar: &mut CookieJar, cookie: Cookie<'static>) {
158 jar.remove(cookie)
159 }
160
161 #[inline]
162 #[track_caller]
163 fn into_key(self) -> Key {
164 unimplemented!("use `SessionLayer::new()` to sign or encrypt cookies")
165 }
166}
167impl private::Sealed for PlainCookie {}
168
169mod private {
170 pub trait Sealed {}
171}