use actix_web::http::header::ContentType; use actix_web::{web, post, HttpResponse, Responder}; use chrono::Utc; use serde::{Serialize, Deserialize}; use uuid::Uuid; use validator::ValidateArgs; use crate::DbPool; use crate::request::request_data::{Login, Register}; use crate::request::error::ApiError; use crate::request::responses::LoginResponse; use crate::schema::user::Role; use crate::schema::{self}; use serde_json; use jsonwebtoken::{encode, EncodingKey, Header}; impl Into for Login { fn into(self) -> schema::user::LoginUser { schema::user::LoginUser { username: self.username, password: self.password } } } impl Into for Register { fn into(self) -> schema::user::Register { schema::user::Register { email: self.email, username: self.username, password: self.password } } } #[derive(Debug, Serialize, Deserialize)] struct Claims { exp: i64, uid: Uuid, role: Role, } #[post("/login")] pub async fn login(pool: web::Data, login_data: web::Json) -> Result { let data = login_data.into_inner(); let response = if let Some(user) = web::block(move || { let mut conn = pool.get().expect("couldn't get db connection from pool"); schema::login(&mut conn, data.into()) }) .await?? { let my_claims = Claims { exp: Utc::now().timestamp() + chrono::Duration::days(7).num_seconds(), uid: user.id, role: user.role, }; let secret = "secret"; let token = encode( &Header::default(), &my_claims, &EncodingKey::from_secret(secret.as_bytes()))?; LoginResponse::success(user.id, token) } else { LoginResponse::failure("User doesn't exist or password doesn't match".to_string()) }; Ok(HttpResponse::Ok() .content_type(ContentType::json()) .body(serde_json::to_string(&response)?) ) } #[post("/register")] pub async fn register(pool: web::Data, register_data: web::Json) -> Result { let data1 = register_data.clone(); let data2 = register_data.clone(); let register_request : schema::user::Register = data2.into(); let mut conn1 = pool.get().expect("couldn't get db connection from pool"); let mut conn2 = pool.get().expect("couldn't get db connection from pool"); let _validation_result = web::block(move || { data1.validate_args((&mut conn1, &mut conn2)) }).await??; let mut conn3 = pool.get().expect("couldn't get db connection from pool"); let _register_result = web::block(move || { schema::register(&mut conn3, register_request) }).await??; return Ok(HttpResponse::Ok()) }