openauth_core/options/
advanced.rs1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use crate::utils::ip::Ipv6Subnet;
6
7use super::cookies::CookieConfig;
8
9pub type BackgroundTaskFuture = Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
11
12pub trait BackgroundTaskRunner: Send + Sync + 'static {
13 fn spawn(&self, task: BackgroundTaskFuture);
14}
15
16#[derive(Clone, Default)]
17pub struct AdvancedOptions {
18 pub use_secure_cookies: Option<bool>,
19 pub cookie_prefix: Option<String>,
20 pub cross_subdomain_cookies: Option<CookieConfig>,
21 pub default_cookie_attributes: CookieAttributesOverride,
22 pub disable_csrf_check: bool,
23 pub disable_origin_check: bool,
24 pub skip_trailing_slashes: bool,
25 pub ip_address: IpAddressOptions,
26 pub background_tasks: Option<Arc<dyn BackgroundTaskRunner>>,
27}
28
29impl AdvancedOptions {
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn builder() -> Self {
35 Self::new()
36 }
37
38 #[must_use]
39 pub fn use_secure_cookies(mut self, enabled: bool) -> Self {
40 self.use_secure_cookies = Some(enabled);
41 self
42 }
43
44 #[must_use]
45 pub fn cookie_prefix(mut self, prefix: impl Into<String>) -> Self {
46 self.cookie_prefix = Some(prefix.into());
47 self
48 }
49
50 #[must_use]
51 pub fn cross_subdomain_cookies(mut self, config: CookieConfig) -> Self {
52 self.cross_subdomain_cookies = Some(config);
53 self
54 }
55
56 #[must_use]
57 pub fn default_cookie_attributes(mut self, attributes: CookieAttributesOverride) -> Self {
58 self.default_cookie_attributes = attributes;
59 self
60 }
61
62 #[must_use]
63 pub fn disable_csrf_check(mut self, disabled: bool) -> Self {
64 self.disable_csrf_check = disabled;
65 self
66 }
67
68 #[must_use]
69 pub fn disable_origin_check(mut self, disabled: bool) -> Self {
70 self.disable_origin_check = disabled;
71 self
72 }
73
74 #[must_use]
75 pub fn skip_trailing_slashes(mut self, enabled: bool) -> Self {
76 self.skip_trailing_slashes = enabled;
77 self
78 }
79
80 #[must_use]
81 pub fn ip_address(mut self, ip_address: IpAddressOptions) -> Self {
82 self.ip_address = ip_address;
83 self
84 }
85
86 #[must_use]
87 pub fn background_tasks(mut self, runner: Arc<dyn BackgroundTaskRunner>) -> Self {
88 self.background_tasks = Some(runner);
89 self
90 }
91}
92
93impl std::fmt::Debug for AdvancedOptions {
94 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 formatter
96 .debug_struct("AdvancedOptions")
97 .field("use_secure_cookies", &self.use_secure_cookies)
98 .field("cookie_prefix", &self.cookie_prefix)
99 .field("cross_subdomain_cookies", &self.cross_subdomain_cookies)
100 .field("default_cookie_attributes", &self.default_cookie_attributes)
101 .field("disable_csrf_check", &self.disable_csrf_check)
102 .field("disable_origin_check", &self.disable_origin_check)
103 .field("skip_trailing_slashes", &self.skip_trailing_slashes)
104 .field("ip_address", &self.ip_address)
105 .field(
106 "background_tasks",
107 &self.background_tasks.as_ref().map(|_| "<background-tasks>"),
108 )
109 .finish()
110 }
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct IpAddressOptions {
115 pub headers: Vec<String>,
116 pub disable_ip_tracking: bool,
117 pub ipv6_subnet: Ipv6Subnet,
118}
119
120impl Default for IpAddressOptions {
121 fn default() -> Self {
122 Self {
123 headers: Vec::new(),
124 disable_ip_tracking: false,
125 ipv6_subnet: Ipv6Subnet::Prefix64,
126 }
127 }
128}
129
130impl IpAddressOptions {
131 pub fn new() -> Self {
132 Self::default()
133 }
134
135 pub fn builder() -> Self {
136 Self::new()
137 }
138
139 #[must_use]
140 pub fn header(mut self, header: impl Into<String>) -> Self {
141 self.headers.push(header.into());
142 self
143 }
144
145 #[must_use]
146 pub fn headers<I, S>(mut self, headers: I) -> Self
147 where
148 I: IntoIterator<Item = S>,
149 S: Into<String>,
150 {
151 self.headers = headers.into_iter().map(Into::into).collect();
152 self
153 }
154
155 #[must_use]
156 pub fn disable_ip_tracking(mut self, disabled: bool) -> Self {
157 self.disable_ip_tracking = disabled;
158 self
159 }
160
161 #[must_use]
162 pub fn ipv6_subnet(mut self, subnet: Ipv6Subnet) -> Self {
163 self.ipv6_subnet = subnet;
164 self
165 }
166}
167
168#[derive(Debug, Clone, Default, PartialEq, Eq)]
170pub struct CookieAttributesOverride {
171 pub domain: Option<String>,
172 pub path: Option<String>,
173 pub secure: Option<bool>,
174 pub http_only: Option<bool>,
175 pub same_site: Option<String>,
176 pub max_age: Option<u64>,
177 pub partitioned: Option<bool>,
178}
179
180impl CookieAttributesOverride {
181 pub fn new() -> Self {
182 Self::default()
183 }
184
185 pub fn builder() -> Self {
186 Self::new()
187 }
188
189 #[must_use]
190 pub fn domain(mut self, domain: impl Into<String>) -> Self {
191 self.domain = Some(domain.into());
192 self
193 }
194
195 #[must_use]
196 pub fn path(mut self, path: impl Into<String>) -> Self {
197 self.path = Some(path.into());
198 self
199 }
200
201 #[must_use]
202 pub fn secure(mut self, secure: bool) -> Self {
203 self.secure = Some(secure);
204 self
205 }
206
207 #[must_use]
208 pub fn http_only(mut self, http_only: bool) -> Self {
209 self.http_only = Some(http_only);
210 self
211 }
212
213 #[must_use]
214 pub fn same_site(mut self, same_site: impl Into<String>) -> Self {
215 self.same_site = Some(same_site.into());
216 self
217 }
218
219 #[must_use]
220 pub fn max_age(mut self, max_age: u64) -> Self {
221 self.max_age = Some(max_age);
222 self
223 }
224
225 #[must_use]
226 pub fn partitioned(mut self, partitioned: bool) -> Self {
227 self.partitioned = Some(partitioned);
228 self
229 }
230}