alloy_transport/
common.rs1use base64::{engine::general_purpose, Engine};
2use std::{fmt, net::SocketAddr};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
8pub enum Authorization {
9 Basic(String),
11 Bearer(String),
13 Raw(String),
15}
16
17impl Authorization {
18 pub fn extract_from_url(url: &url::Url) -> Option<Self> {
20 let username = url.username();
21 let password = url.password().unwrap_or_default();
22
23 if username.contains("localhost") || username.parse::<SocketAddr>().is_ok() {
25 return None;
26 }
27
28 (!username.is_empty() || !password.is_empty()).then(|| Self::basic(username, password))
29 }
30
31 pub fn authority(auth: impl AsRef<str>) -> Self {
33 let auth_secret = general_purpose::STANDARD.encode(auth.as_ref());
34 Self::Basic(auth_secret)
35 }
36
37 pub fn basic(username: impl AsRef<str>, password: impl AsRef<str>) -> Self {
39 let username = username.as_ref();
40 let password = password.as_ref();
41 Self::authority(format!("{username}:{password}"))
42 }
43
44 pub fn bearer(token: impl Into<String>) -> Self {
46 Self::Bearer(token.into())
47 }
48
49 pub fn raw(token: impl Into<String>) -> Self {
51 Self::Raw(token.into())
52 }
53}
54
55impl fmt::Display for Authorization {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 match self {
58 Self::Basic(auth) => write!(f, "Basic {auth}"),
59 Self::Bearer(auth) => write!(f, "Bearer {auth}"),
60 Self::Raw(auth) => write!(f, "{auth}"),
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use url::Url;
69
70 #[test]
71 fn test_extract_from_url_with_basic_auth() {
72 let url = Url::parse("http://username:password@domain.com").unwrap();
73 let auth = Authorization::extract_from_url(&url).unwrap();
74
75 assert_eq!(
77 auth,
78 Authorization::Basic(general_purpose::STANDARD.encode("username:password"))
79 );
80 }
81
82 #[test]
83 fn test_extract_from_url_no_auth() {
84 let url = Url::parse("http://domain.com").unwrap();
85 assert!(Authorization::extract_from_url(&url).is_none());
86 }
87
88 #[test]
89 fn test_extract_from_url_with_localhost() {
90 let url = Url::parse("http://localhost:password@domain.com").unwrap();
91 assert!(Authorization::extract_from_url(&url).is_none());
92 }
93
94 #[test]
95 fn test_extract_from_url_with_socket_address() {
96 let url = Url::parse("http://127.0.0.1:8080").unwrap();
97 assert!(Authorization::extract_from_url(&url).is_none());
98 }
99
100 #[test]
101 fn test_authority() {
102 let auth = Authorization::authority("user:pass");
103 assert_eq!(auth, Authorization::Basic(general_purpose::STANDARD.encode("user:pass")));
104 }
105
106 #[test]
107 fn test_basic() {
108 let auth = Authorization::basic("user", "pass");
109 assert_eq!(auth, Authorization::Basic(general_purpose::STANDARD.encode("user:pass")));
110 }
111
112 #[test]
113 fn test_raw() {
114 let auth = Authorization::raw("raw_token");
115 assert_eq!(auth, Authorization::Raw("raw_token".to_string()));
116 }
117}