credence_lib/configuration/
protect.rs

1use super::super::resolve::*;
2
3use {::axum::http::HeaderMap, bytestring::*, compris::resolve::*, kutil_cli::debug::*, kutil_http::*};
4
5//
6// Protect
7//
8
9/// Protect.
10#[derive(Clone, Debug, Debuggable, Default, Resolve)]
11pub struct Protect {
12    /// Regex.
13    ///
14    /// See [implementation syntax](https://docs.rs/regex/latest/regex/#syntax).
15    #[resolve(required)]
16    #[debuggable(option, as(display), style(string))]
17    pub regex: Option<ResolveRegex>,
18
19    /// Optional realm.
20    ///
21    /// Note that modern browsers do not display the realm.
22    #[resolve]
23    #[debuggable(option, style(string))]
24    pub realm: Option<ByteString>,
25
26    /// Username.
27    #[resolve(required)]
28    #[debuggable(style(string))]
29    pub username: ByteString,
30
31    /// Password.
32    #[resolve(required)]
33    #[debuggable(style(string))]
34    pub password: ByteString,
35}
36
37impl Protect {
38    /// True if protected.
39    pub fn protect(&self, uri_path: &str) -> bool {
40        if let Some(regex) = &self.regex {
41            if regex.value.is_match(uri_path) {
42                return true;
43            }
44        }
45
46        false
47    }
48
49    /// If the request is authorized returns [None](Option::None).
50    ///
51    /// Otherwise returns a `WWW-Authenticate` header value.
52    pub fn authorized(&self, headers: &HeaderMap) -> Option<ByteString> {
53        if let Some((username, password)) = headers.authorization_basic() {
54            if (self.username == username) && (self.password == password) {
55                match &self.realm {
56                    Some(realm) => tracing::debug!("authorized: {}", realm),
57                    None => tracing::debug!("authorized"),
58                }
59                return None;
60            }
61        }
62
63        let authenticate = match &self.realm {
64            Some(realm) => {
65                // Note that modern browsers do not display the realm
66                tracing::debug!("unauthorized: {}", realm);
67                &format!("Basic realm=\"{}\", charset=\"UTF-8\"", realm)
68            }
69
70            None => {
71                tracing::debug!("unauthorized");
72                "Basic charset=\"UTF-8\""
73            }
74        };
75
76        Some(authenticate.into())
77    }
78}