Skip to content

Commit

Permalink
Merge pull request #2 from Engineers-Cradle/feat/jwks
Browse files Browse the repository at this point in the history
feat: migrated from min_jwt -> jwtk + added jwks for public verfication
  • Loading branch information
BRAVO68WEB authored Sep 12, 2024
2 parents b3bd43d + d6c8de0 commit f5b57d6
Show file tree
Hide file tree
Showing 8 changed files with 750 additions and 252 deletions.
625 changes: 599 additions & 26 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion crates/http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ rusqlite = { version = "0.32.0", features = ["bundled"] }
chrono = { version = "0.4.34", features = ["serde", "clock"] }
min_jwt = { version = "0.10.0", features = [ "p256", "serde", "serde_json"] }
p256 = { version = "0.13.0", features = [ "ecdsa"] }
rand = "0.8"
rand = "0.8"
jwtk = "0.3.0"
36 changes: 24 additions & 12 deletions crates/http/src/controller/data.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::env::get_env;
use crate::libs::db::{self, Node, NodeRegistration};
use crate::libs::http::AppState;
use crate::libs::jwt::{generate_jwt, verify_jwt};
use crate::libs::jwt::{self, generate_jwt};
use actix_web::{get, post, web, HttpRequest};
use serde::Deserialize;

Expand All @@ -20,10 +20,6 @@ struct NodeVerify {
token: String,
}

#[derive(Deserialize, serde::Serialize)]
struct VerifyResult {
success: bool,
}

#[derive(Deserialize, serde::Serialize)]
struct ListNodesResult {
Expand Down Expand Up @@ -123,7 +119,7 @@ async fn verify_node(
req: HttpRequest,
body: web::Json<NodeVerify>,
data: web::Data<AppState>,
) -> actix_web::web::Json<VerifyResult> {
) -> actix_web::web::Json<jwt::VerifyNDecodedResult> {
let register_token: Option<&str> = get_register_token(&req);

let register_token: String = match register_token {
Expand All @@ -132,23 +128,39 @@ async fn verify_node(
};

if register_token == "" {
return actix_web::web::Json(VerifyResult { success: false });
return actix_web::web::Json(jwt::VerifyNDecodedResult {
success: false,
app_node: None,
node_id: None,
});
}

if register_token != get_env().registration_token {
return actix_web::web::Json(VerifyResult { success: false });
return actix_web::web::Json(jwt::VerifyNDecodedResult {
success: false,
app_node: None,
node_id: None,
});
}

let token = body.token.clone();

if token == "" {
return actix_web::web::Json(VerifyResult { success: false });
return actix_web::web::Json(jwt::VerifyNDecodedResult {
success:false,
node_id: None,
app_node: None,
});
}

let jwt_result = verify_jwt(&token, &data.public_key);
let public_key = jwt::generate_public_key(data.private_key.clone());

let jwt_result = jwt::verify_jwt(&token, public_key);

actix_web::web::Json(VerifyResult {
success: jwt_result,
actix_web::web::Json(jwt::VerifyNDecodedResult {
success: jwt_result.success,
app_node: jwt_result.app_node,
node_id: jwt_result.node_id,
})
}

Expand Down
21 changes: 21 additions & 0 deletions crates/http/src/controller/root.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use actix_web::{get, web};
use serde::Serialize;
use crate::libs::{http::AppState, jwt::generate_jwks};
use jwtk;


#[derive(Serialize)]
pub struct Status {
Expand All @@ -13,6 +16,24 @@ async fn health() -> web::Json<Status> {
})
}

#[derive(Serialize)]
pub struct Jwks {
keys: Vec<jwtk::jwk::Jwk>,
}

#[get("/jwks.json")]
async fn jwks(
data: web::Data<AppState>,
) -> web::Json<Jwks> {
let private_key = data.private_key.clone();
let jwks: jwtk::jwk::Jwk = generate_jwks(private_key);

web::Json(Jwks {
keys: vec![jwks],
})
}

pub fn init_root_routes(config: &mut web::ServiceConfig) {
config.service(health);
config.service(jwks);
}
88 changes: 1 addition & 87 deletions crates/http/src/libs/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,90 +73,4 @@ pub async fn get_all_nodes(connection: &mut redis::aio::MultiplexedConnection) -
}

NodeList { nodes: Some(nodes) }
}

// Get Node by Name
pub async fn get_node_by_name(
connection: &mut redis::aio::MultiplexedConnection,
app_node: &str,
) -> Node {
let hash_key: String = "node_".to_owned() + &app_node;
let id: String = connection.hget(&hash_key, "id").await.unwrap();
let app_node: String = connection.hget(&hash_key, "app_node").await.unwrap();
let last_token_issue_at: String = connection
.hget(&hash_key, "last_token_issue_at")
.await
.unwrap();
let last_ping_on: String = connection.hget(&hash_key, "last_ping_on").await.unwrap();

Node {
id: id,
app_node: app_node,
last_token_issue_at: last_token_issue_at,
last_ping_on: last_ping_on,
}
}

// Update last_token_issue_at Node by Name
pub async fn update_last_token_issue_at_node_by_name(
connection: &mut redis::aio::MultiplexedConnection,
app_node: &str,
last_token_issue_at: &str,
) -> Node {
let hash_key: String = "node_".to_owned() + &app_node;
let _: () = connection
.hset(&hash_key, "last_token_issue_at", last_token_issue_at)
.await
.unwrap();

let id: String = connection.hget(&hash_key, "id").await.unwrap();
let app_node: String = connection.hget(&hash_key, "app_node").await.unwrap();
let last_token_issue_at: String = connection
.hget(&hash_key, "last_token_issue_at")
.await
.unwrap();
let last_ping_on: String = connection.hget(&hash_key, "last_ping_on").await.unwrap();

Node {
id: id,
app_node: app_node,
last_token_issue_at: last_token_issue_at,
last_ping_on: last_ping_on,
}
}

// Update last_ping_on Node by Name
pub async fn update_last_ping_on_node_by_name(
connection: &mut redis::aio::MultiplexedConnection,
app_node: &str,
last_ping_on: &str,
) -> Node {
let hash_key: String = "node_".to_owned() + &app_node;
let _: () = connection
.hset(&hash_key, "last_ping_on", last_ping_on)
.await
.unwrap();

let id: String = connection.hget(&hash_key, "id").await.unwrap();
let app_node: String = connection.hget(&hash_key, "app_node").await.unwrap();
let last_token_issue_at: String = connection
.hget(&hash_key, "last_token_issue_at")
.await
.unwrap();
let last_ping_on: String = connection.hget(&hash_key, "last_ping_on").await.unwrap();

Node {
id: id,
app_node: app_node,
last_token_issue_at: last_token_issue_at,
last_ping_on: last_ping_on,
}
}

pub async fn delete_node_by_name(
connection: &mut redis::aio::MultiplexedConnection,
app_node: &str,
) {
let hash_key: String = "node_".to_owned() + &app_node;
let _: () = connection.del(&hash_key).await.unwrap();
}
}
9 changes: 3 additions & 6 deletions crates/http/src/libs/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ use crate::libs::jwt;
use actix_web::{web, App, HttpServer};
use env_logger::Env;
use listenfd::ListenFd;
use p256::ecdsa;
use tracing_actix_web::TracingLogger;

#[derive(Clone)]
pub struct AppState {
pub redis_client: redis::Client,
pub private_key: ecdsa::SigningKey,
pub public_key: ecdsa::VerifyingKey,
pub private_key: jwtk::ecdsa::EcdsaPrivateKey,
}

#[actix_web::main]
Expand All @@ -22,11 +20,10 @@ pub async fn start_web_server() -> std::io::Result<()> {
let redis_client: redis::Client =
crate::libs::redis::connection_to_redis(&env_config.redis_url).await;

let key_pair = jwt::generate_keys();
let private_key = jwt::generate_private_key();
let app_state: AppState = AppState {
redis_client: redis_client,
private_key: key_pair.0,
public_key: key_pair.1,
private_key: private_key,
};

env_logger::init_from_env(Env::default().default_filter_or(env_config.log_level));
Expand Down
Loading

0 comments on commit f5b57d6

Please sign in to comment.