refactor: remove jwt completely

This commit is contained in:
Sebastian Pravda 2022-10-29 12:31:39 +02:00
parent 030cd53350
commit 7fdb0de11b
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
6 changed files with 2 additions and 189 deletions

View file

@ -1,7 +1,6 @@
mod mutation;
mod query;
pub mod crypto;
pub mod token;
pub mod services;
pub mod error;

View file

@ -2,33 +2,11 @@ use chrono::Duration;
use entity::candidate;
use sea_orm::{DatabaseConnection, prelude::Uuid, ModelTrait};
use crate::{crypto::{self}, Query, token::{generate_candidate_token, candidate_token::CandidateToken}, error::{ServiceError, USER_NOT_FOUND_ERROR, INVALID_CREDENTIALS_ERROR, DB_ERROR, USER_NOT_FOUND_BY_JWT_ID, USER_NOT_FOUND_BY_SESSION_ID}, Mutation};
use crate::{crypto::{self}, Query, error::{ServiceError, USER_NOT_FOUND_ERROR, INVALID_CREDENTIALS_ERROR, DB_ERROR, USER_NOT_FOUND_BY_JWT_ID, USER_NOT_FOUND_BY_SESSION_ID}, Mutation};
pub struct CandidateService;
impl CandidateService {
#[deprecated(note = "Use session login instead")]
pub async fn login(db: &DatabaseConnection, id: i32, password: String) -> Result<String, ServiceError> {
let candidate = match Query::find_candidate_by_id(db, id).await {
Ok(candidate) => match candidate {
Some(candidate) => candidate,
None => return Err(USER_NOT_FOUND_ERROR)
},
Err(_) => {return Err(DB_ERROR)}
};
let valid = crypto::verify_password(&password,&candidate.code )
.expect("Invalid password");
if !valid {
return Err(INVALID_CREDENTIALS_ERROR)
}
let jwt = generate_candidate_token(candidate); // TODO better error handling
Ok(jwt)
}
pub async fn new_session(db: &DatabaseConnection, user_id: i32, password: String) -> Result<String, ServiceError> {
let candidate = match Query::find_candidate_by_id(db, user_id).await {
Ok(candidate) => match candidate {
@ -61,18 +39,6 @@ impl CandidateService {
Ok(session.id.to_string())
}
pub async fn authenticate_candidate(db: &DatabaseConnection, token: CandidateToken) -> Result<candidate::Model, ServiceError> {
let candidate = match Query::find_candidate_by_id(db, token.application_id).await {
Ok(candidate) => match candidate {
Some(candidate) => candidate,
None => return Err(USER_NOT_FOUND_BY_JWT_ID)
},
Err(_) => {return Err(DB_ERROR)}
};
Ok(candidate)
}
pub async fn auth_user_session(db: &DatabaseConnection, uuid: Uuid) -> Result<candidate::Model, ServiceError> {
let session = match Query::find_session_by_uuid(db, uuid).await {
Ok(session) => match session {
@ -111,7 +77,7 @@ mod tests {
use sea_orm::{DbConn, Database, sea_query::TableCreateStatement, DbBackend, Schema, ConnectionTrait, prelude::Uuid};
use serde_json::json;
use crate::{crypto, Mutation, services::candidate_service::CandidateService, token};
use crate::{crypto, Mutation, services::candidate_service::CandidateService};
#[cfg(test)]
async fn get_memory_sqlite_connection() -> DbConn {
@ -142,24 +108,6 @@ mod tests {
assert_ne!(candidate.code, "Tajny_kod".to_string());
assert!(crypto::verify_password("Tajny_kod", &*candidate.code).ok().unwrap());
}
#[tokio::test]
async fn test_candidate_jwt() {
let db = &get_memory_sqlite_connection().await;
let form = serde_json::from_value(json!({
"application": 5555555,
})).unwrap();
let candidate = Mutation::create_candidate(&db, form, &"Tajny_kod".to_string()).await.unwrap();
let jwt = CandidateService::login(db, 5555555, "Tajny_kod".to_string()).await.ok().unwrap();
let claims = token::decode_candidate_token(jwt).ok().unwrap().claims;
assert_eq!(claims.application_id, candidate.application);
}
#[tokio::test]
async fn test_candidate_session_correct_password() {

View file

@ -1,9 +0,0 @@
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct AdminToken {
// issued at
pub iat: i64,
// expiration
pub exp: i64,
}

View file

@ -1,26 +0,0 @@
use chrono::Utc;
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct CandidateToken {
// issued at
pub iat: i64,
// expiration
pub exp: i64,
pub application_id: i32,
pub name: String,
pub surname: String,
}
impl CandidateToken {
pub fn generate(application_id: i32, name: String, surname: String) -> Self {
let now = Utc::now().timestamp();
CandidateToken {
iat: now,
exp: now + 60 * 60, // 1 hour for now
application_id,
name,
surname,
}
}
}

View file

@ -1,98 +0,0 @@
pub mod admin_token;
pub mod candidate_token;
use chrono::Utc;
use entity::{admin, candidate};
use jsonwebtoken::errors::Result;
use jsonwebtoken::TokenData;
use jsonwebtoken::{DecodingKey, EncodingKey};
use jsonwebtoken::{Header, Validation};
use admin_token::AdminToken;
use candidate_token::CandidateToken;
use serde::Deserialize;
const ONE_WEEK: i64 = 60 * 60 * 24 * 7;
pub fn generate_candidate_token(candidate: candidate::Model) -> String {
let now = Utc::now().timestamp();
let payload = CandidateToken {
iat: now,
exp: now + ONE_WEEK,
application_id: candidate.application,
name: candidate.name.unwrap_or_else(|| "".into()),
surname: candidate.surname.unwrap_or_else(|| "".into()),
};
jsonwebtoken::encode(
&Header::default(),
&payload,
&EncodingKey::from_secret(include_bytes!("secret.key")),
)
.unwrap()
}
pub fn generate_admin_token(_admin: admin::Model) -> String {
let now = Utc::now().timestamp();
let payload = AdminToken {
iat: now,
exp: now + ONE_WEEK,
};
jsonwebtoken::encode(
&Header::default(),
&payload,
&EncodingKey::from_secret(include_bytes!("secret.key")),
)
.unwrap()
}
pub fn decode_token<T: for<'a> Deserialize<'a>>(token: String) -> Result<TokenData<T>> {
jsonwebtoken::decode::<T>(
&token,
&DecodingKey::from_secret(include_bytes!("secret.key")),
&Validation::default(),
)
}
pub fn decode_candidate_token(token: String) -> Result<TokenData<CandidateToken>> {
decode_token(token)
}
pub fn decode_admin_token(token: String) -> Result<TokenData<AdminToken>> {
decode_token(token)
}
#[test]
fn test_encode_decode_token() {
let candidate_model = candidate::Model {
application: 101204,
code: "random_code".to_string(),
birth_surname: None,
birthplace: None,
birthdate: None,
address: None,
telephone: None,
citizenship: None,
sex: None,
study: None,
personal_identification_number: None,
personal_identification_number_hash: None,
public_key: "None".to_owned(),
private_key: "None".to_owned(),
created_at: Utc::now().naive_local(),
updated_at: Utc::now().naive_local(),
name: Some("Uplnej".to_string()),
surname: Some("Magor".to_string()),
email: Some("email.uchazece@centrum.cz".to_string()),
};
let jwt = generate_candidate_token(candidate_model.clone());
let decoded = decode_candidate_token(jwt).unwrap();
let token_claims = decoded.claims;
assert_eq!(candidate_model.name.unwrap(), token_claims.name);
assert_eq!(candidate_model.surname.unwrap(), token_claims.surname);
}

View file

@ -1 +0,0 @@
temp