new laptop setup
This commit is contained in:
Executable
+104
@@ -0,0 +1,104 @@
|
||||
extern crate hmac;
|
||||
extern crate jwt;
|
||||
extern crate sha2;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use actix_web::HttpRequest;
|
||||
use hmac::{Hmac, Mac};
|
||||
use jwt::{Header, SignWithKey, Token, VerifyWithKey};
|
||||
use sha2::Sha256;
|
||||
|
||||
pub struct JwtToken {
|
||||
pub user_id: i32,
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
impl JwtToken {
|
||||
pub fn encode(user_id: i32) -> String {
|
||||
let key: HmacSha256 = HmacSha256::new_from_slice(b"secret").unwrap();
|
||||
let mut claims = BTreeMap::new();
|
||||
claims.insert("user_id", user_id);
|
||||
claims.sign_with_key(&key).unwrap()
|
||||
}
|
||||
|
||||
pub fn decode(encoded_token: String) -> Result<JwtToken, &'static str> {
|
||||
let key: HmacSha256 = HmacSha256::new_from_slice(b"secret").unwrap();
|
||||
let token_str: &str = encoded_token.as_str();
|
||||
let token: Result<Token<Header, BTreeMap<String, i32>, jwt::Verified>, jwt::Error> =
|
||||
VerifyWithKey::verify_with_key(token_str, &key);
|
||||
|
||||
match token {
|
||||
Ok(token) => {
|
||||
let _header = token.header();
|
||||
let claims = token.claims();
|
||||
Ok(JwtToken {
|
||||
user_id: claims["user_id"],
|
||||
body: encoded_token,
|
||||
})
|
||||
}
|
||||
Err(_err) => Err("could not decode token"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_from_request(request: HttpRequest) -> Result<JwtToken, &'static str> {
|
||||
match request.headers().get("user-token") {
|
||||
Some(token) => JwtToken::decode(String::from(token.to_str().unwrap())),
|
||||
None => Err("There is no token"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod jwt_test {
|
||||
use actix_web::{http::header, test};
|
||||
|
||||
use super::JwtToken;
|
||||
|
||||
#[test]
|
||||
async fn encode_decode() {
|
||||
let encoded_token: String = JwtToken::encode(32);
|
||||
let decoded_token: JwtToken = JwtToken::decode(encoded_token).unwrap();
|
||||
assert_eq!(32, decoded_token.user_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn decode_incorrect_token() {
|
||||
let encoded_token: String = String::from("test");
|
||||
|
||||
match JwtToken::decode(encoded_token) {
|
||||
Err(message) => assert_eq!(message, "could not decode token"),
|
||||
_ => panic!("Incorrect token should not be able to decode."),
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn decode_from_request_with_correct_token() {
|
||||
let encoded_token: String = JwtToken::encode(32);
|
||||
let request = test::TestRequest::default()
|
||||
.insert_header(header::ContentType::json())
|
||||
.insert_header(("user-token", encoded_token))
|
||||
.to_http_request();
|
||||
let out_come = JwtToken::decode_from_request(request);
|
||||
|
||||
match out_come {
|
||||
Ok(token) => assert_eq!(32, token.user_id),
|
||||
_ => panic!("Token is not returned with it should be."),
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn decode_from_request_with_no_token() {
|
||||
let request = test::TestRequest::default()
|
||||
.insert_header(("test", "test"))
|
||||
.to_http_request();
|
||||
let out_come = JwtToken::decode_from_request(request);
|
||||
|
||||
match out_come {
|
||||
Err(message) => assert_eq!("There is no token", message),
|
||||
_ => panic!("Token should not be returned when it is not present in the header."),
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
use actix_web::dev::ServiceRequest;
|
||||
pub mod jwt;
|
||||
pub mod processes;
|
||||
use crate::auth::processes::check_password;
|
||||
use crate::auth::processes::extract_header_token;
|
||||
|
||||
pub fn process_token(request: &ServiceRequest) -> Result<String, &'static str> {
|
||||
match extract_header_token(request) {
|
||||
Ok(token) => check_password(token),
|
||||
Err(message) => Err(message),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod mod_test {
|
||||
|
||||
use actix_web::test::TestRequest;
|
||||
|
||||
use super::{jwt::JwtToken, process_token};
|
||||
|
||||
#[test]
|
||||
fn process_token_test() {
|
||||
let token = JwtToken::encode(32);
|
||||
let request = TestRequest::delete()
|
||||
.insert_header(("user-token", token))
|
||||
.to_srv_request();
|
||||
|
||||
match process_token(&request) {
|
||||
Ok(message) => assert_eq!("passed", message),
|
||||
Err(_) => panic!("process token failed"),
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn process_token_not_existing() {
|
||||
let request = TestRequest::default().to_srv_request();
|
||||
|
||||
match process_token(&request) {
|
||||
Err(error) => assert_eq!("there is no token", error),
|
||||
_ => panic!("Not existing token should not be processes"),
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn process_wrong_token() {
|
||||
let request = TestRequest::default()
|
||||
.insert_header(("user-token", "bla"))
|
||||
.to_srv_request();
|
||||
|
||||
match process_token(&request) {
|
||||
Err(error) => assert_eq!("could not decode token", error),
|
||||
_ => panic!("Not existing token should not be processes"),
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
|
||||
use super::jwt;
|
||||
use actix_web::dev::ServiceRequest;
|
||||
|
||||
pub fn check_password(password: String) -> Result<String, &'static str> {
|
||||
match jwt::JwtToken::decode(password) {
|
||||
Ok(_token) => Ok(String::from("passed")),
|
||||
Err(message) => Err(message),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_header_token(request: &ServiceRequest) -> Result<String, &'static str> {
|
||||
match request.headers().get("user-token") {
|
||||
Some(token) => match token.to_str() {
|
||||
Ok(processed_password) => Ok(String::from(processed_password)),
|
||||
Err(_processed_password) => Err("there was an error processing token"),
|
||||
},
|
||||
None => Err("there is no token"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod processes_test {
|
||||
use actix_web::test::TestRequest;
|
||||
|
||||
use crate::auth::jwt::JwtToken;
|
||||
|
||||
use super::check_password;
|
||||
|
||||
#[test]
|
||||
fn check_correct_password() {
|
||||
let password_string: String = JwtToken::encode(32);
|
||||
|
||||
let result = check_password(password_string);
|
||||
|
||||
match result {
|
||||
Ok(check) => assert_eq!("passed", check),
|
||||
_ => panic!("Check correct password failed."),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn incorrect_check_password() {
|
||||
let password: String = String::from("test");
|
||||
|
||||
match check_password(password) {
|
||||
Err(message) => assert_eq!("could not decode token", message),
|
||||
_ => panic!("check password should not be able to be decoded"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn successful_extract_header_token() {
|
||||
let request = TestRequest::default()
|
||||
.insert_header(("user-token", "token"))
|
||||
.to_srv_request();
|
||||
|
||||
match super::extract_header_token(&request) {
|
||||
Ok(processed_password) => assert_eq!("token", processed_password),
|
||||
_ => panic!("failed extract_header_token"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_extract_header_token() {
|
||||
let request = TestRequest::default()
|
||||
.insert_header(("wrong", "bla"))
|
||||
.to_srv_request();
|
||||
|
||||
match super::extract_header_token(&request) {
|
||||
Err(processed_password) => assert_eq!("there is no token", processed_password),
|
||||
_ => panic!("Extract header token should fail when not provided."),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user