forked from Roflin/gamenight
Last cleanup
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
use std::{fs::{self, File}, io::Write, process::Command};
|
||||
use std::{fs::{exists, read_dir, remove_dir_all, File}, io::Write, process::Command};
|
||||
|
||||
|
||||
fn main() {
|
||||
|
||||
if exists("src/models").unwrap() {
|
||||
remove_dir_all("src/models").unwrap();
|
||||
}
|
||||
|
||||
let _ =
|
||||
Command::new("openapi-generator")
|
||||
.args(["generate", "-i", "gamenight-api.yaml", "-g", "rust", "--global-property", "models"])
|
||||
@@ -9,7 +14,7 @@ fn main() {
|
||||
.expect("Failed to generate models sources for the gamenight API");
|
||||
|
||||
let mut file = File::create("src/models/mod.rs").unwrap();
|
||||
let paths = fs::read_dir("./src/models").unwrap();
|
||||
let paths = read_dir("./src/models").unwrap();
|
||||
for path in paths {
|
||||
let path = path.unwrap();
|
||||
let path = path.path();
|
||||
@@ -19,6 +24,6 @@ fn main() {
|
||||
}
|
||||
|
||||
let line = format!("pub mod {};\n", stem.to_str().unwrap());
|
||||
file.write(line.as_bytes()).unwrap();
|
||||
let _ = file.write(line.as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ components:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
description: ''
|
||||
description: 'Failure Reason'
|
||||
Token:
|
||||
title: Token
|
||||
type: object
|
||||
|
||||
@@ -4,35 +4,31 @@ use uuid::Uuid;
|
||||
|
||||
use gamenight_database::{gamenight::Gamenight, DbPool, GetConnection};
|
||||
|
||||
use crate::models;
|
||||
use crate::request::authorization::AuthUser;
|
||||
use crate::request::requests::GamenightGet;
|
||||
use crate::request::requests::GamenightPost;
|
||||
use crate::request::responses::GameNightsResponse;
|
||||
use crate::{models::{gamenight, add_gamenight_request_body::AddGamenightRequestBody, get_gamenight_request::GetGamenightRequest}, request::authorization::AuthUser};
|
||||
use crate::request::error::ApiError;
|
||||
|
||||
|
||||
impl GamenightPost {
|
||||
impl AddGamenightRequestBody {
|
||||
pub fn into_with_user(&self, user: AuthUser) -> Result<Gamenight, ParseError> {
|
||||
Ok(Gamenight {
|
||||
datetime: DateTime::parse_from_rfc3339(&self.datetime)?.with_timezone(&chrono::Utc),
|
||||
datetime: DateTime::parse_from_rfc3339(&self.clone().datetime.unwrap())?.with_timezone(&chrono::Utc),
|
||||
id: Uuid::new_v4(),
|
||||
name: self.name.clone(),
|
||||
name: self.clone().name.unwrap().clone(),
|
||||
owner_id: user.id
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GamenightGet> for Uuid {
|
||||
fn from(value: GamenightGet) -> Self {
|
||||
Uuid::parse_str(value.id.as_str()).unwrap()
|
||||
impl From<GetGamenightRequest> for Uuid {
|
||||
fn from(value: GetGamenightRequest) -> Self {
|
||||
Uuid::parse_str(value.id.unwrap().as_str()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/gamenights")]
|
||||
pub async fn gamenights(pool: web::Data<DbPool>, _user: AuthUser) -> Result<impl Responder, ApiError> {
|
||||
let mut conn = pool.get_conn();
|
||||
let gamenights: GameNightsResponse = gamenight_database::gamenights(&mut conn)?;
|
||||
let gamenights: Vec<gamenight_database::gamenight::Gamenight> = gamenight_database::gamenights(&mut conn)?;
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type(ContentType::json())
|
||||
@@ -41,7 +37,7 @@ pub async fn gamenights(pool: web::Data<DbPool>, _user: AuthUser) -> Result<impl
|
||||
}
|
||||
|
||||
#[post("/gamenight")]
|
||||
pub async fn gamenight_post(pool: web::Data<DbPool>, user: AuthUser, gamenight_data: web::Json<GamenightPost>) -> Result<impl Responder, ApiError> {
|
||||
pub async fn gamenight_post(pool: web::Data<DbPool>, user: AuthUser, gamenight_data: web::Json<AddGamenightRequestBody>) -> Result<impl Responder, ApiError> {
|
||||
let mut conn = pool.get_conn();
|
||||
|
||||
gamenight_database::gamenight::add_gamenight(&mut conn, gamenight_data.into_with_user(user)?)?;
|
||||
@@ -50,13 +46,13 @@ pub async fn gamenight_post(pool: web::Data<DbPool>, user: AuthUser, gamenight_d
|
||||
}
|
||||
|
||||
#[get("/gamenight")]
|
||||
pub async fn gamenight_get(pool: web::Data<DbPool>, _user: AuthUser, gamenight_data: web::Json<GamenightGet>) -> Result<impl Responder, ApiError> {
|
||||
pub async fn gamenight_get(pool: web::Data<DbPool>, _user: AuthUser, gamenight_data: web::Json<GetGamenightRequest>) -> Result<impl Responder, ApiError> {
|
||||
let mut conn = pool.get_conn();
|
||||
|
||||
let gamenight = gamenight_database::gamenight::get_gamenight(&mut conn, gamenight_data.into_inner().into())?;
|
||||
let participants = gamenight_database::gamenight_participants::get_participants(&mut conn, &gamenight.id)?;
|
||||
|
||||
let model = models::gamenight::Gamenight{
|
||||
let model = gamenight::Gamenight{
|
||||
id: gamenight.id.to_string(),
|
||||
datetime: gamenight.datetime.to_rfc3339(),
|
||||
name: gamenight.name,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
pub mod requests;
|
||||
mod responses;
|
||||
mod user_handlers;
|
||||
mod gamenight_handlers;
|
||||
mod error;
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
use gamenight_database::{DbPool, GetConnection, user::count_users_with_username, user::count_users_with_email};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use validator::{Validate, ValidationError};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Login {
|
||||
pub username: String,
|
||||
pub password: String
|
||||
}
|
||||
|
||||
pub struct RegisterContext<'v_a> {
|
||||
pub pool: &'v_a DbPool
|
||||
}
|
||||
|
||||
pub fn unique_username(username: &String, context: &RegisterContext) -> Result<(), ValidationError> {
|
||||
let mut conn = context.pool.get_conn();
|
||||
|
||||
match count_users_with_username(&mut conn, username)
|
||||
{
|
||||
Ok(0) => Ok(()),
|
||||
Ok(_) => Err(ValidationError::new("User already exists")),
|
||||
Err(_) => Err(ValidationError::new("Database error while validating user")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unique_email(email: &String, context: &RegisterContext) -> Result<(), ValidationError> {
|
||||
let mut conn = context.pool.get_conn();
|
||||
|
||||
match count_users_with_email(&mut conn, email)
|
||||
{
|
||||
Ok(0) => Ok(()),
|
||||
Ok(_) => Err(ValidationError::new("email already exists")),
|
||||
Err(_) => Err(ValidationError::new("Database error while validating email"))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate)]
|
||||
#[validate(context = RegisterContext::<'v_a>)]
|
||||
pub struct Register {
|
||||
#[validate(
|
||||
length(min = 1),
|
||||
custom(function = "unique_username", use_context)
|
||||
)]
|
||||
pub username: String,
|
||||
#[validate(
|
||||
email,
|
||||
custom(function = "unique_email", use_context)
|
||||
)]
|
||||
pub email: String,
|
||||
#[validate(length(min = 10), must_match(other = "password_repeat", ))]
|
||||
pub password: String,
|
||||
pub password_repeat: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct GamenightPost {
|
||||
pub name: String,
|
||||
pub datetime: String
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct GamenightGet {
|
||||
pub id: String
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use gamenight_database::gamenight::Gamenight;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct LoginResponse {
|
||||
pub login_result: bool,
|
||||
pub message: Option<String>,
|
||||
pub user_id: Option<Uuid>,
|
||||
pub jwt_token: Option<String>
|
||||
}
|
||||
|
||||
impl LoginResponse {
|
||||
pub fn success(user_id: Uuid, token: String) -> Self {
|
||||
Self {
|
||||
login_result: true,
|
||||
message: None,
|
||||
user_id: Some(user_id),
|
||||
jwt_token: Some(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type GameNightsResponse = Vec<Gamenight>;
|
||||
@@ -1,13 +1,15 @@
|
||||
|
||||
use actix_web::http::header::ContentType;
|
||||
use actix_web::{get, post, web, HttpResponse, Responder};
|
||||
use serde::Deserialize;
|
||||
use gamenight_database::user::{count_users_with_email, count_users_with_username};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
use validator::ValidateArgs;
|
||||
use validator::{Validate, ValidateArgs, ValidationError};
|
||||
use crate::models::login::Login;
|
||||
use crate::models::registration::Registration;
|
||||
use crate::models::token::Token;
|
||||
use crate::models::user::User;
|
||||
use crate::request::requests::{Login, Register, RegisterContext};
|
||||
use crate::request::error::ApiError;
|
||||
use crate::request::responses::LoginResponse;
|
||||
use crate::request::authorization::get_token;
|
||||
use serde_json;
|
||||
use gamenight_database::{DbPool, GetConnection};
|
||||
@@ -23,8 +25,8 @@ impl From<Login> for gamenight_database::user::LoginUser {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Register> for gamenight_database::user::Register {
|
||||
fn from(val: Register) -> Self {
|
||||
impl From<Registration> for gamenight_database::user::Register {
|
||||
fn from(val: Registration) -> Self {
|
||||
gamenight_database::user::Register {
|
||||
email: val.email,
|
||||
username: val.username,
|
||||
@@ -33,6 +35,61 @@ impl From<Register> for gamenight_database::user::Register {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegisterContext<'v_a> {
|
||||
pub pool: &'v_a DbPool
|
||||
}
|
||||
|
||||
pub fn unique_username(username: &String, context: &RegisterContext) -> Result<(), ValidationError> {
|
||||
let mut conn = context.pool.get_conn();
|
||||
|
||||
match count_users_with_username(&mut conn, username)
|
||||
{
|
||||
Ok(0) => Ok(()),
|
||||
Ok(_) => Err(ValidationError::new("User already exists")),
|
||||
Err(_) => Err(ValidationError::new("Database error while validating user")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unique_email(email: &String, context: &RegisterContext) -> Result<(), ValidationError> {
|
||||
let mut conn = context.pool.get_conn();
|
||||
|
||||
match count_users_with_email(&mut conn, email)
|
||||
{
|
||||
Ok(0) => Ok(()),
|
||||
Ok(_) => Err(ValidationError::new("email already exists")),
|
||||
Err(_) => Err(ValidationError::new("Database error while validating email"))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate)]
|
||||
#[validate(context = RegisterContext::<'v_a>)]
|
||||
pub struct ValidatableRegistration {
|
||||
#[validate(
|
||||
length(min = 1),
|
||||
custom(function = "unique_username", use_context)
|
||||
)]
|
||||
pub username: String,
|
||||
#[validate(
|
||||
email,
|
||||
custom(function = "unique_email", use_context)
|
||||
)]
|
||||
pub email: String,
|
||||
#[validate(length(min = 10), must_match(other = "password_repeat", ))]
|
||||
pub password: String,
|
||||
pub password_repeat: String,
|
||||
}
|
||||
|
||||
impl From<Registration> for ValidatableRegistration {
|
||||
fn from(value: Registration) -> Self {
|
||||
Self {
|
||||
username: value.username,
|
||||
email: value.email,
|
||||
password: value.password,
|
||||
password_repeat: value.password_repeat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/token")]
|
||||
pub async fn login(pool: web::Data<DbPool>, login_data: web::Json<Login>) -> Result<impl Responder, ApiError> {
|
||||
let data = login_data.into_inner();
|
||||
@@ -44,7 +101,7 @@ pub async fn login(pool: web::Data<DbPool>, login_data: web::Json<Login>) -> Res
|
||||
.await?
|
||||
{
|
||||
let token = get_token(&user)?;
|
||||
let response = LoginResponse::success(user.id, token);
|
||||
let response = Token{ jwt_token: Some(token) };
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type(ContentType::json())
|
||||
.body(serde_json::to_string(&response)?)
|
||||
@@ -56,9 +113,10 @@ pub async fn login(pool: web::Data<DbPool>, login_data: web::Json<Login>) -> Res
|
||||
}
|
||||
|
||||
#[post("/user")]
|
||||
pub async fn register(pool: web::Data<DbPool>, register_data: web::Json<Register>) -> Result<impl Responder, ApiError> {
|
||||
pub async fn register(pool: web::Data<DbPool>, register_data: web::Json<Registration>) -> Result<impl Responder, ApiError> {
|
||||
web::block(move || -> Result<(), ApiError> {
|
||||
register_data.validate_with_args(&RegisterContext{pool: &pool})?;
|
||||
let validatable_registration: ValidatableRegistration = register_data.clone().into();
|
||||
validatable_registration.validate_with_args(&RegisterContext{pool: &pool})?;
|
||||
let register_request = register_data.into_inner().into();
|
||||
let mut conn = pool.get_conn();
|
||||
gamenight_database::register(&mut conn, register_request)?;
|
||||
|
||||
Reference in New Issue
Block a user