github_mcp/http/
auth_extractor.rs1use axum::http::HeaderMap;
4
5use crate::auth::request_credentials::RequestCredentials;
6
7#[derive(Debug, PartialEq)]
8pub enum ExtractError {
9 Missing,
11 UnsupportedLocation(String),
15}
16
17pub fn extract_request_credentials(
22 headers: &HeaderMap,
23 header_location: &str,
24 header_name: &str,
25) -> Result<RequestCredentials, ExtractError> {
26 if header_location != "header" {
27 return Err(ExtractError::UnsupportedLocation(
28 header_location.to_string(),
29 ));
30 }
31
32 let value = headers
33 .get(header_name)
34 .and_then(|value| value.to_str().ok())
35 .filter(|value| !value.is_empty())
36 .ok_or(ExtractError::Missing)?;
37
38 Ok(RequestCredentials {
39 header_name: header_name.to_string(),
40 value: value.to_string(),
41 })
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn extracts_a_present_header() {
50 let mut headers = HeaderMap::new();
51 headers.insert("Authorization", "Bearer abc".parse().unwrap());
52 let creds = extract_request_credentials(&headers, "header", "Authorization").unwrap();
53 assert_eq!(creds.header_name, "Authorization");
54 assert_eq!(creds.value, "Bearer abc");
55 }
56
57 #[test]
58 fn errors_when_the_header_is_absent() {
59 let headers = HeaderMap::new();
60 assert_eq!(
61 extract_request_credentials(&headers, "header", "Authorization"),
62 Err(ExtractError::Missing)
63 );
64 }
65
66 #[test]
67 fn errors_when_the_header_is_present_but_empty() {
68 let mut headers = HeaderMap::new();
69 headers.insert("X-Api-Key", "".parse().unwrap());
70 assert_eq!(
71 extract_request_credentials(&headers, "header", "X-Api-Key"),
72 Err(ExtractError::Missing)
73 );
74 }
75
76 #[test]
77 fn rejects_query_and_cookie_locations() {
78 let headers = HeaderMap::new();
79 assert_eq!(
80 extract_request_credentials(&headers, "query", "api_key"),
81 Err(ExtractError::UnsupportedLocation("query".to_string()))
82 );
83 assert_eq!(
84 extract_request_credentials(&headers, "cookie", "session"),
85 Err(ExtractError::UnsupportedLocation("cookie".to_string()))
86 );
87 assert_eq!(
88 extract_request_credentials(&headers, "none", ""),
89 Err(ExtractError::UnsupportedLocation("none".to_string()))
90 );
91 }
92}