Skip to content

Commit

Permalink
heimdall-v2: add state module and JWT settings
Browse files Browse the repository at this point in the history
  • Loading branch information
styvane committed Aug 31, 2023
1 parent f578d0e commit e235aee
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 10 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion services/heimdallr-v2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ anyhow = "1.0"
axum = { version = "0.6.20", features = ["headers"] }
axum-server = "0.5.1"
serde = { version = "1.0", features = ["derive"] }
serde-aux = "4.2.0"
serde-aux = "4.2.0"
serde_json = "1.0.79"
jsonwebtoken = { version = "8.1.0", features = ["use_pem"] }
secrecy = { version = "0.8.0", features = ["serde"] }
19 changes: 14 additions & 5 deletions services/heimdallr-v2/src/bootstrap.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! This module defines the application type and operations.
use axum::Router;
use secrecy::Secret;
use std::net::TcpListener;

use crate::{error::Result, settings::Settings};
use crate::error::Result;
use crate::settings::Settings;
use crate::state::AppState;

/// The application type for starting the server.
#[derive(Debug)]
Expand All @@ -17,10 +20,15 @@ pub struct Application {
impl Application {
/// Creates new application.
pub async fn new(settings: Settings) -> Result<Self> {
let router = new_router()?;
let app_settings = &settings.application;
let Settings {
application: app_settings,
jwt: jwt_settings,
} = settings;
let addr = format!("{}:{}", app_settings.host, app_settings.port);
let listener = TcpListener::bind(addr)?;

let router = new_router(jwt_settings.pub_key)?;

Ok(Application { listener, router })
}

Expand All @@ -35,7 +43,8 @@ impl Application {
}

/// Create and configure new router.
pub fn new_router() -> Result<Router> {
let router = Router::new();
pub fn new_router(jwt_pub_key: Secret<String>) -> Result<Router> {
let app_state = AppState::new(jwt_pub_key)?;
let router = Router::new().with_state(app_state);
Ok(router)
}
1 change: 1 addition & 0 deletions services/heimdallr-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
pub mod bootstrap;
pub mod error;
pub mod settings;
mod state;
19 changes: 15 additions & 4 deletions services/heimdallr-v2/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
//! Application configuration data structure
use config::Config;
use serde::{Deserialize, Serialize};
use secrecy::Secret;
use serde::Deserialize;
use serde_aux::field_attributes::deserialize_number_from_string;

use crate::error::Error;

#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Deserialize)]
/// Settings is the application configuration type.
pub struct Settings {
/// The application settings.
pub application: AppSettings,

/// JWT configurations
pub jwt: JwtSettings,
}

/// The application level configuration data.
#[derive(Clone, Debug, Serialize, Deserialize)]
/// The application level configuration settings.
#[derive(Clone, Debug, Deserialize)]
pub struct AppSettings {
/// Application port number.
#[serde(deserialize_with = "deserialize_number_from_string")]
Expand All @@ -24,6 +28,13 @@ pub struct AppSettings {
pub host: String,
}

/// The JWT configuration settings.
#[derive(Clone, Debug, Deserialize)]
pub struct JwtSettings {
/// This is the secret for encoding and decoding token.
pub(super) pub_key: Secret<String>,
}

impl Settings {
/// Loads the configuration data.
pub fn load() -> Result<Self, Error> {
Expand Down
44 changes: 44 additions & 0 deletions services/heimdallr-v2/src/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! # AppState
//!
//! This module defines the application state type.
use jsonwebtoken::DecodingKey;
use secrecy::{ExposeSecret, Secret};

use crate::error::{Error, Result};

/// Application state type.
#[derive(Clone)]
pub struct AppState {
/// JWT decoding key.
pub jwt_decoding_key: DecodingKey,
}

impl AppState {
/// Create new application state.
pub fn new(jwt: Secret<String>) -> Result<Self> {
let jwt_decoding_key =
DecodingKey::from_ec_pem(jwt.expose_secret().as_bytes()).map_err(Error::JwtError)?;
Ok(Self { jwt_decoding_key })
}
}

#[cfg(test)]
mod tests {
use super::*;
use secrecy::Secret;

#[test]
fn state() {
let secret = concat!(
"-----BEGIN PUBLIC KEY-----\n",
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMMkapa1mVNQtUdWP9B61OpMcuBHmw+\n",
"LwS66RkRJ3gYlrXCisZwWaNQo3nkNjRujIVVI9jEGCWYRdECga9lUjrg=\n",
"-----END PUBLIC KEY-----",
);

let secret = Secret::new(secret.into());
let state = AppState::new(secret);
assert!(state.is_ok())
}
}

0 comments on commit e235aee

Please sign in to comment.