add a message module holding struct to manager json response body + fix tests

This commit is contained in:
landrigun 2023-02-16 11:29:21 +00:00
parent f108c592a9
commit 734ec7901d
7 changed files with 66 additions and 51 deletions

View File

@ -5,37 +5,9 @@ use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use tokio::fs;
use crate::message::JWTMessage;
use crate::stores::Credentials;
#[derive(Serialize)]
/// JWTMessage aims to have a generic struct to build HTTP response message with JWT
pub struct JWTMessage {
#[serde(skip_serializing_if = "String::is_empty")]
access_token: String,
#[serde(skip_serializing_if = "String::is_empty")]
refresh_token: String,
#[serde(skip_serializing_if = "String::is_empty")]
pubkey: String,
}
impl JWTMessage {
pub fn with_access(access_token: String) -> Self {
JWTMessage {
access_token: access_token,
refresh_token: "".to_string(),
pubkey: "".to_string(),
}
}
pub fn with_pubkey(pubkey: String) -> Self {
JWTMessage {
access_token: "".to_string(),
refresh_token: "".to_string(),
pubkey: base64::encode(pubkey),
}
}
}
#[derive(Serialize, Deserialize)]
struct JWTCustomClaims {
email: String,

View File

@ -1,5 +1,4 @@
//! jwt module aims to read `.pem` files, sign/validate the token and have useful functions to
//! manage HTTP response message
//! jwt module aims to read `.pem` files, sign/validate the token
mod jwt;
pub use jwt::{JWTMessage, JWTSigner};
pub use jwt::JWTSigner;

View File

@ -1,5 +1,6 @@
mod config;
mod jwt;
mod message;
mod router;
mod stores;

48
src/message/message.rs Normal file
View File

@ -0,0 +1,48 @@
use serde::Serialize;
#[derive(Serialize)]
/// JWTMessage aims to have a generic struct to build HTTP response message with JWT
pub struct JWTMessage {
#[serde(skip_serializing_if = "String::is_empty")]
access_token: String,
#[serde(skip_serializing_if = "String::is_empty")]
refresh_token: String,
#[serde(skip_serializing_if = "String::is_empty")]
pubkey: String,
}
impl JWTMessage {
pub fn with_access(access_token: String) -> Self {
JWTMessage {
access_token: access_token,
refresh_token: "".to_string(),
pubkey: "".to_string(),
}
}
pub fn with_pubkey(pubkey: String) -> Self {
JWTMessage {
access_token: "".to_string(),
refresh_token: "".to_string(),
pubkey: base64::encode(pubkey),
}
}
}
#[derive(Serialize, Default)]
/// ValidationMessage aims to build a JSON HTTP response body for JWT validation
pub struct ValidationMessage {
valid: bool,
#[serde(skip_serializing_if = "String::is_empty")]
reason: String,
}
impl ValidationMessage {
pub fn set_valid(&mut self, valid: bool) {
self.valid = valid;
}
pub fn set_reason(&mut self, reason: &str) {
self.reason = reason.to_string();
}
}

4
src/message/mod.rs Normal file
View File

@ -0,0 +1,4 @@
//! message lib holds all structs to manager auth JSON response body
mod message;
pub use message::{JWTMessage, ValidationMessage};

View File

@ -3,10 +3,10 @@
use http::{HTTPRequest, HTTPResponse, JSONMessage};
use json::JsonValue;
use serde::Serialize;
use crate::config::Config;
use crate::jwt::{JWTMessage, JWTSigner};
use crate::jwt::JWTSigner;
use crate::message::{JWTMessage, ValidationMessage};
use crate::stores::{Credentials, FileStore, Store};
// TODO: must be mapped with corresponding handler
@ -14,14 +14,6 @@ const GET_ROUTE: &'static str = "/get/";
const VALIDATE_ROUTE: &'static str = "/validate/";
const PUBKEY_ROUTE: &'static str = "/pubkey/";
#[derive(Serialize, Default)]
/// ValidationMessage aims to build a JSON HTTP response body for JWT validation
struct ValidationMessage {
is_valid: bool,
#[serde(skip_serializing_if = "String::is_empty")]
reason: String,
}
async fn handle_get(request: HTTPRequest<'_>, config: Config, method: &str) -> HTTPResponse {
if method.trim().to_lowercase() != "post" {
return HTTPResponse::as_400();
@ -75,11 +67,10 @@ async fn handle_validate(request: HTTPRequest<'_>, config: Config, method: &str)
match request.get_body_value("token") {
Some(t) => t,
None => {
let mut message = JSONMessage::default();
message.put("valid", "false");
message.put("reason", "no token provided in the request body");
let json = message.try_into().unwrap();
let mut message = ValidationMessage::default();
message.set_reason("no token provided in the request body");
let json = json::parse(&serde_json::to_string(&message).unwrap()).unwrap();
return HTTPResponse::as_200(Some(json));
}
}
@ -99,10 +90,10 @@ async fn handle_validate(request: HTTPRequest<'_>, config: Config, method: &str)
let mut message = ValidationMessage::default();
match jwt_signer.validate(&token) {
Ok(()) => {
message.is_valid = true;
message.set_valid(true);
}
Err(e) => {
message.reason = e;
message.set_reason(&e);
}
}

View File

@ -48,14 +48,14 @@ class TestResponse(TestCase):
)
self.assertEqual(resp.status_code, 200, "bad status code returned")
self.assertIsNotNone(resp.json(), "response data can't be empty")
self.assertEqual(resp.json()["valid"], "false", "bad status returned")
self.assertEqual(resp.json()["valid"], False, "bad status returned")
self.assertEqual(resp.json()["reason"], "no token provided in the request body")
def test_validate_target_empty_token(self):
resp = requests.post(URL + "/validate/", json={"tutu": "tutu", "token": ""})
self.assertEqual(resp.status_code, 200, "bad status code returned")
self.assertIsNotNone(resp.json(), "response data can't be empty")
self.assertEqual(resp.json()["valid"], "false", "bad status returned")
self.assertEqual(resp.json()["valid"], False, "bad status returned")
self.assertEqual(
resp.json()["reason"],
"token validation failed details=JWT compact encoding error",
@ -67,7 +67,7 @@ class TestResponse(TestCase):
resp = requests.post(URL + "/validate/", json={"token": token})
self.assertEqual(resp.status_code, 200, "bad status code returned")
self.assertIsNotNone(resp.json(), "response data can't be empty")
self.assertEqual(resp.json()["valid"], "true", "bad status returned")
self.assertEqual(resp.json()["valid"], True, "bad status returned")
# TODO: must be updated after implementing `/refresh/` url handler
def test_refresh_target(self):