volga_oauth_client/config.rs
1//! Client configuration
2//!
3//! [`ClientConfig`] carries the transport-level policy shared by all client
4//! operations (discovery, token requests, registration): HTTPS enforcement,
5//! timeouts and redirect limits. The defaults are safe for production use.
6
7use std::time::Duration;
8
9/// Default total timeout for a single client request
10pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
11
12/// Default maximum number of redirects followed per request
13pub const DEFAULT_MAX_REDIRECTS: u8 = 5;
14
15/// Transport-level configuration for OAuth client operations
16///
17/// # Example
18/// ```
19/// use std::time::Duration;
20/// use volga_oauth_client::ClientConfig;
21///
22/// let config = ClientConfig::new()
23/// .with_timeout(Duration::from_secs(5))
24/// .with_max_redirects(0);
25///
26/// assert!(config.enforce_https());
27/// ```
28#[derive(Clone, Debug, PartialEq, Eq)]
29pub struct ClientConfig {
30 enforce_https: bool,
31 timeout: Duration,
32 max_redirects: u8,
33}
34
35impl Default for ClientConfig {
36 #[inline]
37 fn default() -> Self {
38 Self {
39 enforce_https: true,
40 timeout: DEFAULT_TIMEOUT,
41 max_redirects: DEFAULT_MAX_REDIRECTS,
42 }
43 }
44}
45
46impl ClientConfig {
47 /// Creates a configuration with the default policy: HTTPS enforced,
48 /// [`DEFAULT_TIMEOUT`] and [`DEFAULT_MAX_REDIRECTS`]
49 #[inline]
50 pub fn new() -> Self {
51 Self::default()
52 }
53
54 /// Controls whether plain `http://` URLs are rejected
55 ///
56 /// Enabled by default. Disable only for local development against a
57 /// plaintext authorization server; requests to `http://` endpoints
58 /// otherwise fail with
59 /// [`ClientError::InsecureUrl`](crate::ClientError::InsecureUrl).
60 #[inline]
61 pub fn require_https(mut self, required: bool) -> Self {
62 self.enforce_https = required;
63 self
64 }
65
66 /// Sets the total timeout for a single request
67 #[inline]
68 pub fn with_timeout(mut self, timeout: Duration) -> Self {
69 self.timeout = timeout;
70 self
71 }
72
73 /// Sets the maximum number of redirects followed per request;
74 /// `0` disables redirects entirely
75 #[inline]
76 pub fn with_max_redirects(mut self, max_redirects: u8) -> Self {
77 self.max_redirects = max_redirects;
78 self
79 }
80
81 /// Returns whether plain `http://` URLs are rejected
82 #[inline]
83 pub fn enforce_https(&self) -> bool {
84 self.enforce_https
85 }
86
87 /// Returns the total timeout for a single request
88 #[inline]
89 pub fn timeout(&self) -> Duration {
90 self.timeout
91 }
92
93 /// Returns the maximum number of redirects followed per request
94 #[inline]
95 pub fn max_redirects(&self) -> u8 {
96 self.max_redirects
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn it_defaults_to_safe_policy() {
106 let config = ClientConfig::new();
107 assert!(config.enforce_https());
108 assert_eq!(config.timeout(), DEFAULT_TIMEOUT);
109 assert_eq!(config.max_redirects(), DEFAULT_MAX_REDIRECTS);
110 }
111
112 #[test]
113 fn it_builds_custom_policy() {
114 let config = ClientConfig::new()
115 .require_https(false)
116 .with_timeout(Duration::from_secs(5))
117 .with_max_redirects(0);
118 assert!(!config.enforce_https());
119 assert_eq!(config.timeout(), Duration::from_secs(5));
120 assert_eq!(config.max_redirects(), 0);
121 }
122}