add a message module holding struct to manager json response body + fix tests
This commit is contained in:
parent
f108c592a9
commit
734ec7901d
@ -5,37 +5,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
|
use crate::message::JWTMessage;
|
||||||
use crate::stores::Credentials;
|
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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct JWTCustomClaims {
|
struct JWTCustomClaims {
|
||||||
email: String,
|
email: String,
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
//! jwt module aims to read `.pem` files, sign/validate the token and have useful functions to
|
//! jwt module aims to read `.pem` files, sign/validate the token
|
||||||
//! manage HTTP response message
|
|
||||||
mod jwt;
|
mod jwt;
|
||||||
|
|
||||||
pub use jwt::{JWTMessage, JWTSigner};
|
pub use jwt::JWTSigner;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
mod config;
|
mod config;
|
||||||
mod jwt;
|
mod jwt;
|
||||||
|
mod message;
|
||||||
mod router;
|
mod router;
|
||||||
mod stores;
|
mod stores;
|
||||||
|
|
||||||
|
|||||||
48
src/message/message.rs
Normal file
48
src/message/message.rs
Normal 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
4
src/message/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
//! message lib holds all structs to manager auth JSON response body
|
||||||
|
mod message;
|
||||||
|
|
||||||
|
pub use message::{JWTMessage, ValidationMessage};
|
||||||
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
use http::{HTTPRequest, HTTPResponse, JSONMessage};
|
use http::{HTTPRequest, HTTPResponse, JSONMessage};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::jwt::{JWTMessage, JWTSigner};
|
use crate::jwt::JWTSigner;
|
||||||
|
use crate::message::{JWTMessage, ValidationMessage};
|
||||||
use crate::stores::{Credentials, FileStore, Store};
|
use crate::stores::{Credentials, FileStore, Store};
|
||||||
|
|
||||||
// TODO: must be mapped with corresponding handler
|
// TODO: must be mapped with corresponding handler
|
||||||
@ -14,14 +14,6 @@ const GET_ROUTE: &'static str = "/get/";
|
|||||||
const VALIDATE_ROUTE: &'static str = "/validate/";
|
const VALIDATE_ROUTE: &'static str = "/validate/";
|
||||||
const PUBKEY_ROUTE: &'static str = "/pubkey/";
|
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 {
|
async fn handle_get(request: HTTPRequest<'_>, config: Config, method: &str) -> HTTPResponse {
|
||||||
if method.trim().to_lowercase() != "post" {
|
if method.trim().to_lowercase() != "post" {
|
||||||
return HTTPResponse::as_400();
|
return HTTPResponse::as_400();
|
||||||
@ -75,11 +67,10 @@ async fn handle_validate(request: HTTPRequest<'_>, config: Config, method: &str)
|
|||||||
match request.get_body_value("token") {
|
match request.get_body_value("token") {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => {
|
None => {
|
||||||
let mut message = JSONMessage::default();
|
let mut message = ValidationMessage::default();
|
||||||
message.put("valid", "false");
|
message.set_reason("no token provided in the request body");
|
||||||
message.put("reason", "no token provided in the request body");
|
|
||||||
let json = message.try_into().unwrap();
|
|
||||||
|
|
||||||
|
let json = json::parse(&serde_json::to_string(&message).unwrap()).unwrap();
|
||||||
return HTTPResponse::as_200(Some(json));
|
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();
|
let mut message = ValidationMessage::default();
|
||||||
match jwt_signer.validate(&token) {
|
match jwt_signer.validate(&token) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
message.is_valid = true;
|
message.set_valid(true);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
message.reason = e;
|
message.set_reason(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,14 +48,14 @@ class TestResponse(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
||||||
self.assertIsNotNone(resp.json(), "response data can't be empty")
|
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")
|
self.assertEqual(resp.json()["reason"], "no token provided in the request body")
|
||||||
|
|
||||||
def test_validate_target_empty_token(self):
|
def test_validate_target_empty_token(self):
|
||||||
resp = requests.post(URL + "/validate/", json={"tutu": "tutu", "token": ""})
|
resp = requests.post(URL + "/validate/", json={"tutu": "tutu", "token": ""})
|
||||||
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
||||||
self.assertIsNotNone(resp.json(), "response data can't be empty")
|
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(
|
self.assertEqual(
|
||||||
resp.json()["reason"],
|
resp.json()["reason"],
|
||||||
"token validation failed details=JWT compact encoding error",
|
"token validation failed details=JWT compact encoding error",
|
||||||
@ -67,7 +67,7 @@ class TestResponse(TestCase):
|
|||||||
resp = requests.post(URL + "/validate/", json={"token": token})
|
resp = requests.post(URL + "/validate/", json={"token": token})
|
||||||
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
||||||
self.assertIsNotNone(resp.json(), "response data can't be empty")
|
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
|
# TODO: must be updated after implementing `/refresh/` url handler
|
||||||
def test_refresh_target(self):
|
def test_refresh_target(self):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user