about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2022-02-21 21:42:21 +0300
committerVika <vika@fireburn.ru>2022-02-21 21:42:21 +0300
commiteb6d5015eec34a1a65fb2d4d54b5201d4aef2728 (patch)
tree0dcbfd2551a442eb937c84756d43f19791146dee
parentf0a2630afcb23008627b1211abc6e1bb449d994d (diff)
indieauth/require_token(): reject with 401 when no header
-rw-r--r--src/indieauth.rs36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/indieauth.rs b/src/indieauth.rs
index 305452a..8f3ef8f 100644
--- a/src/indieauth.rs
+++ b/src/indieauth.rs
@@ -1,6 +1,6 @@
 use url::Url;
 use serde::{Serialize, Deserialize};
-use warp::{Filter, Rejection};
+use warp::{Filter, Rejection, reject::MissingHeader};
 
 #[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
 pub struct User {
@@ -101,8 +101,18 @@ pub fn require_token(token_endpoint: String, http: HttpClient) -> impl Filter<Ex
     warp::any()
         .map(move || token_endpoint_uri.clone())
         .and(warp::any().map(move || http.clone()))
-        .and(warp::header::<String>("Authorization"))
         .and_then(|token_endpoint, http: HttpClient, token| async move {
+        .and(warp::header::<String>("Authorization").recover(|err: Rejection| async move {
+            if err.find::<MissingHeader>().is_some() {
+                Err(IndieAuthError {
+                    source: None,
+                    msg: "No Authorization header provided.".to_string(),
+                    kind: ErrorKind::NotAuthorized
+                }.into())
+            } else {
+                Err(err)
+            }
+        }).unify())
             let request = hyper::Request::builder()
                 .method(hyper::Method::GET)
                 .uri(token_endpoint)
@@ -265,6 +275,28 @@ mod tests {
     }
 
     #[tokio::test]
+    async fn test_require_token_no_token() {
+        let server = MockServer::start_async().await;
+        let mock = server.mock_async(|when, then| {
+            when.path("/should_never_be_called");
+
+            then.status(500);
+        }).await;
+        let filter = require_token(server.url("/should_never_be_called"), get_http_client());
+
+        let res = warp::test::request()
+            .path("/")
+            .filter(&filter)
+            .await
+            .unwrap_err();
+
+        let err: &IndieAuthError = res.find().unwrap();
+        assert_eq!(err.kind, super::ErrorKind::NotAuthorized);
+
+        mock.assert_hits_async(0).await;
+    }
+
+    #[tokio::test]
     async fn test_require_token_400_error_unauthorized() {
         let server = MockServer::start_async().await;
         server.mock_async(|when, then| {