pdk_jwt_lib/provider/
token_provider.rs1use crate::error::jwt_error::JWTError;
20use pdk_core::classy::hl::HeadersHandler;
21
22const AUTHORIZATION_HEADER: &str = "Authorization";
23const BEARER_START: &str = "Bearer ";
24const BEARER_START_LENGTH: usize = BEARER_START.len();
25
26pub struct TokenProvider {}
28
29impl TokenProvider {
30 pub fn bearer(handler: &dyn HeadersHandler) -> Result<String, JWTError> {
31 handler
32 .header(AUTHORIZATION_HEADER)
33 .ok_or(JWTError::AuthorizationHeaderNotPresent)
34 .and_then(|auth_header| {
35 if auth_header.starts_with(BEARER_START) {
36 let token = &auth_header[BEARER_START_LENGTH..];
37
38 if token.starts_with(' ') {
39 Err(JWTError::BearerMalformed)
40 } else {
41 Ok(String::from(token))
42 }
43 } else {
44 Err(JWTError::BearerNotPresent)
45 }
46 })
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 mod bearer_provider_test_cases {
53 use super::super::TokenProvider;
54 use crate::error::jwt_error::JWTError;
55 use mockall::mock;
56 use test_case::test_case;
57
58 mock! {
59 pub HeadersHandler {}
60 impl pdk_core::classy::hl::HeadersHandler for HeadersHandler{
61 fn headers(&self) -> Vec<(String, String)>;
62 fn header(&self, name: &str) -> Option<String>;
63 fn add_header(&self, name: &str, value: &str);
64 fn set_header(&self, name: &str, value: &str);
65 fn set_headers<'a>(&self, headers: Vec<(&'a str, &'a str)>);
66 fn remove_header(&self, name: &str);
67 }
68 }
69
70 fn bearer_provision_test(
71 handler_response: Option<String>,
72 expectation: Result<String, JWTError>,
73 ) {
74 let mut handler = MockHeadersHandler::new();
75
76 handler
77 .expect_header()
78 .times(1)
79 .return_const(handler_response);
80
81 assert_eq!(TokenProvider::bearer(&handler), expectation);
82 }
83
84 #[test]
85 fn when_authorization_header_present_should_return_that_value() {
86 bearer_provision_test(
87 Some(String::from(
88 "Bearer I am a value for the authorization bearer header",
89 )),
90 Ok(String::from(
91 "I am a value for the authorization bearer header",
92 )),
93 );
94 }
95
96 #[test]
97 fn when_authorization_header_not_present_should_return_an_error() {
98 bearer_provision_test(None, Err(JWTError::AuthorizationHeaderNotPresent));
99 }
100
101 #[test_case("I am a value for the authorization header but not bearer"; "Bearer must be present")]
102 #[test_case(" Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"; "Bearer can not have spaces before")]
103 #[test_case("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 Bearer"; "Bearer can not be at the end")]
104 #[test_case("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"; "Bearer can not be in the middle")]
105 #[test_case("eyJ0eXAiOiJKV1QiLCBearereyJhbGciOiJIUzI1NiJ9"; "Bearer can not be inside of the token")]
106 #[test_case("BearereyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"; "Bearer must be separated from token")]
107 #[test_case("bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"; "B in Bearer must be uppercase")]
108 #[test_case("BEARER eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"; "Bearer must be capitalized")]
109 fn bearer_header_should_be_well_formed(header: &str) {
110 bearer_provision_test(Some(String::from(header)), Err(JWTError::BearerNotPresent));
111 }
112
113 #[test]
114 fn bearer_keyword_should_be_followed_by_just_one_space() {
115 bearer_provision_test(
116 Some(String::from("Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9")),
117 Err(JWTError::BearerMalformed),
118 );
119 }
120 }
121}