mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-16 13:01:13 +00:00
refactor: remove jwt completely
This commit is contained in:
parent
030cd53350
commit
7fdb0de11b
6 changed files with 2 additions and 189 deletions
|
|
@ -1,7 +1,6 @@
|
|||
mod mutation;
|
||||
mod query;
|
||||
pub mod crypto;
|
||||
pub mod token;
|
||||
pub mod services;
|
||||
pub mod error;
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AdminToken {
|
||||
// issued at
|
||||
pub iat: i64,
|
||||
// expiration
|
||||
pub exp: i64,
|
||||
}
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
temp
|
||||
Loading…
Reference in a new issue