tower_oauth2_resource_server/
jwt_extract.rs

1use http::HeaderMap;
2
3use crate::error::AuthError;
4
5pub trait JwtExtractor {
6    fn extract_jwt(&self, headers: &HeaderMap) -> Result<String, AuthError>;
7}
8
9pub struct BearerTokenJwtExtractor;
10
11impl JwtExtractor for BearerTokenJwtExtractor {
12    fn extract_jwt(&self, headers: &HeaderMap) -> Result<String, AuthError> {
13        Ok(headers
14            .get(http::header::AUTHORIZATION)
15            .ok_or(AuthError::MissingAuthorizationHeader)?
16            .to_str()
17            .map_err(|_| AuthError::InvalidAuthorizationHeader)?
18            .strip_prefix("Bearer ")
19            .ok_or(AuthError::InvalidAuthorizationHeader)?
20            .to_owned())
21    }
22}
23
24#[cfg(test)]
25mod tests {
26    use http::HeaderValue;
27
28    use super::*;
29
30    #[test]
31    fn test_missing_authorization() {
32        let headers = HeaderMap::new();
33        let result = BearerTokenJwtExtractor {}.extract_jwt(&headers);
34
35        assert!(result.is_err());
36        assert_eq!(result.unwrap_err(), AuthError::MissingAuthorizationHeader);
37    }
38
39    #[test]
40    fn test_missing_bearer_prefix() {
41        let mut headers = HeaderMap::new();
42        headers.insert(
43            "Authorization",
44            HeaderValue::from_str("Boarer XXX").unwrap(),
45        );
46        let result = BearerTokenJwtExtractor {}.extract_jwt(&headers);
47
48        assert!(result.is_err());
49        assert_eq!(result.unwrap_err(), AuthError::InvalidAuthorizationHeader);
50    }
51
52    #[test]
53    fn test_ok() {
54        let mut headers = HeaderMap::new();
55        headers.insert(
56            "Authorization",
57            HeaderValue::from_str("Bearer XXX").unwrap(),
58        );
59        let result = BearerTokenJwtExtractor {}.extract_jwt(&headers);
60
61        assert!(result.is_ok());
62    }
63}