Splits database into a separate crate

This commit is contained in:
2025-05-30 14:31:00 +02:00
parent 3f7ed03973
commit 597a960bf1
34 changed files with 368 additions and 402 deletions

View File

@@ -6,7 +6,7 @@ use jsonwebtoken::{encode, Header, EncodingKey, decode, DecodingKey, Validation}
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use crate::{schema::user::{User, get_user}, DbPool};
use gamenight_database::{user::{get_user, Role, User}, DbPool};
use super::error::ApiError;
@@ -16,6 +16,24 @@ pub struct Claims {
uid: Uuid
}
pub struct AuthUser {
pub id: Uuid,
pub username: String,
pub email: String,
pub role: Role,
}
impl From<User> for AuthUser {
fn from(value: User) -> Self {
Self{
id: value.id,
username: value.username,
email: value.email,
role: value.role,
}
}
}
fn get_claims(req: &HttpRequest) -> Result<Claims, ApiError> {
let token = req.headers()
.get(http::header::AUTHORIZATION)
@@ -43,18 +61,19 @@ pub fn get_token(user: &User) -> Result<String, ApiError> {
&EncodingKey::from_secret(secret.as_bytes()))?)
}
impl FromRequest for User {
impl FromRequest for AuthUser {
type Error = ApiError;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
ready(
(|| -> Result<User, ApiError>{
(|| -> Result<AuthUser, ApiError>{
let pool = req.app_data::<Data<DbPool>>().expect("No database configured");
let mut conn = pool.get().expect("couldn't get db connection from pool");
let uid = get_claims(req)?.uid;
let user = get_user(&mut conn, uid)?;
Ok(get_user(&mut conn, uid)?)
Ok(user.into())
})()
)
}

View File

@@ -3,7 +3,7 @@ use actix_web::{ResponseError, error::BlockingError, HttpResponse, http::{header
use serde::{Serialize, Deserialize};
use validator::ValidationErrors;
use crate::schema::error::DatabaseError;
use gamenight_database::error::DatabaseError;
#[derive(Serialize, Deserialize, Debug)]
pub struct ApiError {

View File

@@ -2,18 +2,18 @@ use actix_web::{get, web, Responder, http::header::ContentType, HttpResponse, po
use chrono::{DateTime, ParseError};
use uuid::Uuid;
use crate::schema::{self};
use crate::schema::user::User;
use gamenight_database::{gamenight::Gamenight, DbPool, GetConnection};
use crate::request::authorization::AuthUser;
use crate::request::requests::GamenightGet;
use crate::request::requests::GamenightPost;
use crate::request::responses::GameNightsResponse;
use crate::request::error::ApiError;
use crate::DbPool;
use crate::util::GetConnection;
impl GamenightPost {
pub fn into_with_user(&self, user: User) -> Result<schema::gamenight::Gamenight, ParseError> {
Ok(schema::gamenight::Gamenight {
pub fn into_with_user(&self, user: AuthUser) -> Result<Gamenight, ParseError> {
Ok(Gamenight {
datetime: DateTime::parse_from_rfc3339(&self.datetime)?.with_timezone(&chrono::Utc),
id: Uuid::new_v4(),
name: self.name.clone(),
@@ -29,9 +29,9 @@ impl From<GamenightGet> for Uuid {
}
#[get("/gamenights")]
pub async fn gamenights(pool: web::Data<DbPool>, _user: User) -> Result<impl Responder, ApiError> {
pub async fn gamenights(pool: web::Data<DbPool>, _user: AuthUser) -> Result<impl Responder, ApiError> {
let mut conn = pool.get_conn();
let gamenights: GameNightsResponse = schema::gamenights(&mut conn)?;
let gamenights: GameNightsResponse = gamenight_database::gamenights(&mut conn)?;
Ok(HttpResponse::Ok()
.content_type(ContentType::json())
@@ -40,19 +40,19 @@ pub async fn gamenights(pool: web::Data<DbPool>, _user: User) -> Result<impl Res
}
#[post("/gamenight")]
pub async fn gamenight_post(pool: web::Data<DbPool>, user: User, gamenight_data: web::Json<GamenightPost>) -> Result<impl Responder, ApiError> {
pub async fn gamenight_post(pool: web::Data<DbPool>, user: AuthUser, gamenight_data: web::Json<GamenightPost>) -> Result<impl Responder, ApiError> {
let mut conn = pool.get_conn();
schema::gamenight::add_gamenight(&mut conn, gamenight_data.into_with_user(user)?)?;
gamenight_database::gamenight::add_gamenight(&mut conn, gamenight_data.into_with_user(user)?)?;
Ok(HttpResponse::Ok())
}
#[get("/gamenight")]
pub async fn gamenight_get(pool: web::Data<DbPool>, _user: User, gamenight_data: web::Json<GamenightGet>) -> Result<impl Responder, ApiError> {
pub async fn gamenight_get(pool: web::Data<DbPool>, _user: AuthUser, gamenight_data: web::Json<GamenightGet>) -> Result<impl Responder, ApiError> {
let mut conn = pool.get_conn();
let gamenight = schema::gamenight::get_gamenight(&mut conn, gamenight_data.into_inner().into())?;
let gamenight = gamenight_database::gamenight::get_gamenight(&mut conn, gamenight_data.into_inner().into())?;
//let participants = schema::user::get_participants(&mut conn, gamenight_id);
Ok(HttpResponse::Ok()

View File

@@ -1,10 +1,6 @@
use gamenight_database::{DbPool, GetConnection, user::count_users_with_username, user::count_users_with_email};
use serde::{Serialize, Deserialize};
use validator::Validate;
use diesel::PgConnection;
use diesel::r2d2::ConnectionManager;
use diesel::r2d2::Pool;
use crate::schema::user::{unique_email, unique_username};
use validator::{Validate, ValidationError};
#[derive(Serialize, Deserialize, Clone)]
pub struct Login {
@@ -13,7 +9,29 @@ pub struct Login {
}
pub struct RegisterContext<'v_a> {
pub pool: &'v_a Pool<ConnectionManager<PgConnection>>
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)]

View File

@@ -1,7 +1,7 @@
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use crate::schema::gamenight::Gamenight;
use gamenight_database::gamenight::Gamenight;
#[derive(Serialize, Deserialize)]
pub struct LoginResponse {

View File

@@ -2,27 +2,25 @@
use actix_web::http::header::ContentType;
use actix_web::{web, get, post, HttpResponse, Responder};
use validator::ValidateArgs;
use crate::DbPool;
use crate::request::requests::{Login, Register, RegisterContext};
use crate::request::error::ApiError;
use crate::request::responses::LoginResponse;
use crate::request::authorization::get_token;
use crate::util::GetConnection;
use crate::schema::{self};
use serde_json;
use gamenight_database::{DbPool, GetConnection};
impl From<Login> for schema::user::LoginUser {
impl From<Login> for gamenight_database::user::LoginUser {
fn from(val: Login) -> Self {
schema::user::LoginUser {
gamenight_database::user::LoginUser {
username: val.username,
password: val.password
}
}
}
impl From<Register> for schema::user::Register {
impl From<Register> for gamenight_database::user::Register {
fn from(val: Register) -> Self {
schema::user::Register {
gamenight_database::user::Register {
email: val.email,
username: val.username,
password: val.password
@@ -36,7 +34,7 @@ pub async fn login(pool: web::Data<DbPool>, login_data: web::Json<Login>) -> Res
if let Ok(Some(user)) = web::block(move || {
let mut conn = pool.get_conn();
schema::login(&mut conn, data.into())
gamenight_database::login(&mut conn, data.into())
})
.await?
{
@@ -58,7 +56,7 @@ pub async fn register(pool: web::Data<DbPool>, register_data: web::Json<Register
register_data.validate_with_args(&RegisterContext{pool: &pool})?;
let register_request = register_data.into_inner().into();
let mut conn = pool.get_conn();
schema::register(&mut conn, register_request)?;
gamenight_database::register(&mut conn, register_request)?;
Ok(())
}).await??;