feat: validate application_id

This commit is contained in:
Sebastian Pravda 2022-11-04 17:19:13 +01:00
parent f2fadfdfe4
commit ed783859b7
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
2 changed files with 42 additions and 1 deletions

View file

@ -1,8 +1,10 @@
pub enum ServiceError {
InvalidApplicationId,
InvalidCredentials,
Forbidden,
ExpiredSession,
JwtError,
UserAlreadyExists,
UserNotFound,
DbError,
UserNotFoundByJwtId,
@ -12,10 +14,12 @@ pub enum ServiceError {
impl ServiceError {
fn code_and_message(&self) -> (u16, String) {
match self {
ServiceError::InvalidApplicationId => (400, "Invalid application id".to_string()),
ServiceError::InvalidCredentials => (401, "Invalid credentials".to_string()),
ServiceError::Forbidden => (403, "Forbidden".to_string()),
ServiceError::ExpiredSession => (401, "Session expired, please login again".to_string()),
ServiceError::JwtError => (500, "Error while encoding JWT".to_string()),
ServiceError::UserAlreadyExists => (409, "User already exists".to_string()),
ServiceError::UserNotFound => (404, "User not found".to_string()),
ServiceError::DbError => (500, "Database error".to_string()),
ServiceError::UserNotFoundByJwtId => (500, "User not found, please contact technical support".to_string()),

View file

@ -1,19 +1,36 @@
use entity::candidate;
use sea_orm::{DbConn, prelude::Uuid};
use crate::{Mutation, crypto::{hash_password, self}, error::{ServiceError}};
use crate::{Mutation, crypto::{hash_password, self}, error::{ServiceError}, Query};
use super::session_service::SessionService;
const CODES: [&str; 3] = ["101", "102", "103"];
pub struct CandidateService;
impl CandidateService {
/// Creates a new candidate with:
/// Encrypted personal identification number
/// Hashed password
/// Encrypted private key
/// Public key
pub async fn create(
db: &DbConn,
application_id: i32,
plain_text_password: &String,
personal_id_number: String
) -> Result<candidate::Model, ServiceError>{
// Check if application id starts with 101, 102 or 103
if !CandidateService::is_application_id_valid(application_id) {
return Err(ServiceError::InvalidApplicationId)
}
// Check if user with that application id already exists
if Query::find_candidate_by_id(db, application_id).await.unwrap().is_some() {
return Err(ServiceError::UserAlreadyExists)
}
// TODO: unwrap pro testing..
let hashed_password = hash_password(plain_text_password.to_string()).await.unwrap();
let (pubkey, priv_key_plain_text) = crypto::create_identity();
@ -50,6 +67,15 @@ impl CandidateService {
) -> Result<candidate::Model, ServiceError> {
SessionService::auth_user_session(db, session_uuid).await
}
fn is_application_id_valid(application_id: i32) -> bool {
let s = &application_id.to_string();
if s.len() <= 3 { // TODO: does the code have to be exactly 6 digits?
return false;
}
let code = &s[0..3];
CODES.contains(&code)
}
}
@ -59,6 +85,17 @@ mod tests {
use crate::{crypto, services::candidate_service::CandidateService};
#[tokio::test]
async fn test_application_id_validation() {
assert!(CandidateService::is_application_id_valid(101_101));
assert!(CandidateService::is_application_id_valid(102_107));
assert!(CandidateService::is_application_id_valid(103_109));
assert!(!CandidateService::is_application_id_valid(104_109));
assert!(!CandidateService::is_application_id_valid(100_109));
assert!(!CandidateService::is_application_id_valid(201_109));
assert!(!CandidateService::is_application_id_valid(101));
}
#[cfg(test)]
async fn get_memory_sqlite_connection() -> DbConn {
use entity::candidate;