Skip to content

Commit 96459ed

Browse files
committed
Bearer token support #632
1 parent 43a726b commit 96459ed

File tree

1 file changed

+75
-39
lines changed

1 file changed

+75
-39
lines changed

server/src/helpers.rs

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ pub fn get_auth_headers(
1818
map: &HeaderMap,
1919
requested_subject: String,
2020
) -> AtomicServerResult<Option<AuthValues>> {
21+
if let Some(bearer) = map.get("authorization") {
22+
let bearer = bearer
23+
.to_str()
24+
.map_err(|_e| "Only string headers allowed in authorization header")?
25+
.trim_start_matches("Bearer ");
26+
let auth_vals = get_auth_from_base64(bearer, &requested_subject)?;
27+
return Ok(Some(auth_vals));
28+
}
29+
2130
let public_key = map.get("x-atomic-public-key");
2231
let signature = map.get("x-atomic-signature");
2332
let timestamp = map.get("x-atomic-timestamp");
@@ -77,50 +86,61 @@ pub fn get_auth_from_cookie(
7786
AtomicError::unauthorized("No valid session cookies found. ".into()).into();
7887

7988
for enc in encoded_session_cookies {
80-
let session = base64::decode(enc).map_err(|_| {
81-
AtomicError::unauthorized(
82-
"Malformed authentication resource in cookie - unable to decode base64".to_string(),
83-
)
84-
})?;
89+
match get_auth_from_base64(&enc, requested_subject) {
90+
Ok(auth_vals) => return Ok(Some(auth_vals)),
91+
Err(e) => {
92+
if e.message.contains(WRONG_SUBJECT_ERR) && check_multiple {
93+
// if the subject is wrong, we can try the next one
94+
err = e;
95+
continue;
96+
} else {
97+
return Err(e);
98+
}
99+
}
100+
}
101+
}
85102

86-
let session_str = std::str::from_utf8(&session).map_err(|_| AtomicServerError {
87-
message: "Malformed authentication resource in cookie - unable to parse from utf_8"
88-
.to_string(),
103+
Err(err)
104+
}
105+
106+
static WRONG_SUBJECT_ERR: &str = "Wrong requested subject in auth token";
107+
108+
fn get_auth_from_base64(base64: &str, requested_subject: &str) -> AtomicServerResult<AuthValues> {
109+
let session = base64::decode(base64).map_err(|_| {
110+
AtomicError::unauthorized(
111+
"Malformed authentication resource - unable to decode base64".to_string(),
112+
)
113+
})?;
114+
115+
let session_str = std::str::from_utf8(&session).map_err(|_| AtomicServerError {
116+
message: "Malformed authentication resource - unable to parse from utf_8".to_string(),
117+
error_type: AppErrorType::Unauthorized,
118+
error_resource: None,
119+
})?;
120+
let auth_values: AuthValues =
121+
serde_json::from_str(session_str).map_err(|e| AtomicServerError {
122+
message: format!(
123+
"Malformed authentication resource when parsing AuthValues JSON: {}",
124+
e
125+
),
89126
error_type: AppErrorType::Unauthorized,
90127
error_resource: None,
91128
})?;
92-
let auth_values: AuthValues =
93-
serde_json::from_str(session_str).map_err(|e| AtomicServerError {
94-
message: format!(
95-
"Malformed authentication resource when parsing AuthValues JSON: {}",
96-
e
97-
),
98-
error_type: AppErrorType::Unauthorized,
99-
error_resource: None,
100-
})?;
101-
102-
let subject_invalid = auth_values.requested_subject.ne(requested_subject)
103-
&& auth_values.requested_subject.ne(&origin(requested_subject));
104-
105-
if subject_invalid {
106-
// if the subject is invalid, there are two things that could be going on.
107-
// 1. The requested resource is wrong
108-
// 2. The user is trying to access a resource from a different origin
109-
110-
err = AtomicError::unauthorized(format!(
111-
"Wrong requested subject in cookie, expected {} was {}",
112-
requested_subject, auth_values.requested_subject
113-
))
114-
.into();
115-
if check_multiple {
116-
continue;
117-
} else {
118-
return Err(err);
119-
}
120-
}
121-
return Ok(Some(auth_values));
129+
let subject_invalid = auth_values.requested_subject.ne(requested_subject)
130+
&& auth_values.requested_subject.ne(&origin(requested_subject));
131+
if subject_invalid {
132+
// if the subject is invalid, there are two things that could be going on.
133+
// 1. The requested resource is wrong
134+
// 2. The user is trying to access a resource from a different origin
135+
136+
let err = AtomicError::unauthorized(format!(
137+
"{}, expected {} was {}",
138+
WRONG_SUBJECT_ERR, requested_subject, auth_values.requested_subject
139+
))
140+
.into();
141+
return Err(err);
122142
}
123-
Err(err)
143+
Ok(auth_values)
124144
}
125145

126146
pub fn get_auth(
@@ -255,4 +275,20 @@ mod test {
255275

256276
assert_eq!(out.requested_subject, subject);
257277
}
278+
279+
#[test]
280+
fn bearer() {
281+
let token = "eyJodHRwczovL2F0b21pY2RhdGEuZGV2L3Byb3BlcnRpZXMvYXV0aC9hZ2VudCI6Imh0dHBzOi8vYXRvbWljZGF0YS5kZXYvYWdlbnRzL1FtZnBSSUJuMkpZRWF0VDBNalNrTU5vQkp6c3R6MTlvcnduVDVvVDJyY1E9IiwiaHR0cHM6Ly9hdG9taWNkYXRhLmRldi9wcm9wZXJ0aWVzL2F1dGgvcmVxdWVzdGVkU3ViamVjdCI6Imh0dHBzOi8vYXRvbWljZGF0YS5kZXYiLCJodHRwczovL2F0b21pY2RhdGEuZGV2L3Byb3BlcnRpZXMvYXV0aC9wdWJsaWNLZXkiOiJRbWZwUklCbjJKWUVhdFQwTWpTa01Ob0JKenN0ejE5b3J3blQ1b1QycmNRPSIsImh0dHBzOi8vYXRvbWljZGF0YS5kZXYvcHJvcGVydGllcy9hdXRoL3RpbWVzdGFtcCI6MTY3NjI4MjU4NDg0NCwiaHR0cHM6Ly9hdG9taWNkYXRhLmRldi9wcm9wZXJ0aWVzL2F1dGgvc2lnbmF0dXJlIjoia1NvLzZQeUdkcnhnbFJFUFdVeUJRVEZxb3RMcmV4L040czRZRFV2d0N0aTl5NEpxWnkwaG92aUtCNkRtMDFCTEdKUU41b3hRdWdveXphSDVIcmVLRHc9PSJ9";
282+
let mut headermap = HeaderMap::new();
283+
headermap.insert(
284+
"authorization".try_into().unwrap(),
285+
HeaderValue::from_str(token).unwrap(),
286+
);
287+
let subject = "https://atomicdata.dev";
288+
let out = get_auth_headers(&headermap, subject.into())
289+
.expect("Should not return err")
290+
.expect("Should contain cookie");
291+
292+
assert_eq!(out.requested_subject, subject);
293+
}
258294
}

0 commit comments

Comments
 (0)