Skip to content

Commit

Permalink
heimdallr-v2: implement Claim extractor
Browse files Browse the repository at this point in the history
  • Loading branch information
styvane committed Aug 31, 2023
1 parent e235aee commit 6e7090d
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 2 deletions.
1 change: 0 additions & 1 deletion drasil-hugin/src/protocol/smartcontract/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub(crate) mod nft_marketplace;
pub(crate) mod worldmobile;
49 changes: 48 additions & 1 deletion services/heimdallr-v2/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
//! This module defines the error types.
use std::io;
use std::{fmt, io};

use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use serde_json::json;
use thiserror;

/// Result an alias for the `Result` type with `self::Error` as error
Expand All @@ -17,4 +21,47 @@ pub enum Error {
/// Improperly configuration errors
#[error(transparent)]
ConfigError(#[from] config::ConfigError),

/// This is JWT related errors.
#[error(transparent)]
JwtError(#[from] jsonwebtoken::errors::Error),
}

/// Authentication errors type.
#[derive(Debug, thiserror::Error)]
pub enum AuthError {
/// This is the error when the credentials do not match.
WrongCredentials,

/// This is the error when the credential is missing.
MissingCredentials,

/// This is the error when the credential is invalid.
InvalidToken,
}

impl IntoResponse for AuthError {
fn into_response(self) -> Response {
let (status, error_message) = match self {
AuthError::WrongCredentials => (StatusCode::UNAUTHORIZED, "wrong credentials"),
AuthError::MissingCredentials => (StatusCode::BAD_REQUEST, "missing credentials"),
AuthError::InvalidToken => (StatusCode::BAD_REQUEST, "invalid token"),
};
let body = Json(json!({
"error": error_message,
}));
(status, body).into_response()
}
}

impl fmt::Display for AuthError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::InvalidToken => "invalid token",
Self::MissingCredentials => "missing token",
Self::WrongCredentials => "wrong credential",
};

write!(f, "{s}")
}
}
2 changes: 2 additions & 0 deletions services/heimdallr-v2/src/extractor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//! Extractors module.
mod claims;
55 changes: 55 additions & 0 deletions services/heimdallr-v2/src/extractor/claims.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Claim extractor
//!
//! This module implements the claim extractor from a bearer token.
use axum::extract::{FromRef, FromRequestParts};
use axum::headers::authorization::{Authorization, Bearer};
use axum::http::request::Parts;
use axum::{async_trait, RequestPartsExt, TypedHeader};
use jsonwebtoken::{decode, Validation};
use serde::{Deserialize, Serialize};

use crate::error::AuthError;
use crate::state::AppState;

/// Claims represents the claims data from JWT
#[derive(Debug, Deserialize, Serialize)]
#[allow(clippy::missing_docs_in_private_items)]
pub struct Claims {
sub: String,
exp: usize,
}

impl Claims {
/// Return the customer ID in this claim.
pub fn get_customer_id(&self) -> Result<u64, AuthError> {
self.sub.parse().map_err(|_| AuthError::WrongCredentials)
}
}

#[async_trait]
impl<S> FromRequestParts<S> for Claims
where
AppState: FromRef<S>,
S: Send + Sync,
{
type Rejection = AuthError;

async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
// Extract the token from the authorization header
let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>()
.await
.map_err(|_| AuthError::MissingCredentials)?;
// Decode the user data

let app_state = AppState::from_ref(state);
let token_data = decode::<Claims>(
bearer.token(),
&app_state.jwt_decoding_key,
&Validation::default(),
)
.map_err(|_| AuthError::InvalidToken)?;

Ok(token_data.claims)
}
}
1 change: 1 addition & 0 deletions services/heimdallr-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@

pub mod bootstrap;
pub mod error;
mod extractor;
pub mod settings;
mod state;

0 comments on commit 6e7090d

Please sign in to comment.