From b49ca4d0ded65179a10c9924114381d9026c0e26 Mon Sep 17 00:00:00 2001
From: Santo Cariotti <santo@dcariotti.me>
Date: Tue, 23 Aug 2022 18:28:05 +0200
Subject: Decode token

---
 server/src/errors.rs      |  2 ++
 server/src/models/auth.rs | 28 +++++++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/server/src/errors.rs b/server/src/errors.rs
index d991132..304d744 100644
--- a/server/src/errors.rs
+++ b/server/src/errors.rs
@@ -11,6 +11,7 @@ pub enum AppError {
     BadRequest(String),
     NotFound,
     TokenCreation,
+    InvalidToken,
 }
 
 impl IntoResponse for AppError {
@@ -30,6 +31,7 @@ impl IntoResponse for AppError {
                 StatusCode::INTERNAL_SERVER_ERROR,
                 "Token creation error".to_string(),
             ),
+            AppError::InvalidToken => (StatusCode::BAD_REQUEST, "Invalid token".to_string()),
         };
 
         let body = Json(json!({
diff --git a/server/src/models/auth.rs b/server/src/models/auth.rs
index 03b198b..573f5d1 100644
--- a/server/src/models/auth.rs
+++ b/server/src/models/auth.rs
@@ -1,6 +1,11 @@
 use crate::errors::AppError;
+use axum::{
+    async_trait,
+    extract::{FromRequest, RequestParts, TypedHeader},
+    headers::{authorization::Bearer, Authorization},
+};
 use chrono::{Duration, Local};
-use jsonwebtoken::{encode, DecodingKey, EncodingKey, Header, Validation};
+use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
 use once_cell::sync::Lazy;
 use serde::{Deserialize, Serialize};
 
@@ -61,3 +66,24 @@ impl AuthBody {
         }
     }
 }
+
+#[async_trait]
+impl<B> FromRequest<B> for Claims
+where
+    B: Send,
+{
+    type Rejection = AppError;
+
+    async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
+        // Extract the token from the authorization header
+        let TypedHeader(Authorization(bearer)) =
+            TypedHeader::<Authorization<Bearer>>::from_request(req)
+                .await
+                .map_err(|_| AppError::InvalidToken)?;
+        // Decode the user data
+        let token_data = decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default())
+            .map_err(|_| AppError::InvalidToken)?;
+
+        Ok(token_data.claims)
+    }
+}
-- 
cgit v1.2.3-18-g5258