99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
|
|
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<schema::user::LoginUser> for Login {
|
|
fn into(self) -> schema::user::LoginUser {
|
|
schema::user::LoginUser {
|
|
username: self.username,
|
|
password: self.password
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<schema::user::Register> 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<DbPool>, login_data: web::Json<Login>) -> Result<impl Responder, ApiError> {
|
|
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<DbPool>, register_data: web::Json<Register>) -> Result<impl Responder, ApiError> {
|
|
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())
|
|
}
|
|
|
|
|