Splits database into a separate crate
This commit is contained in:
@@ -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())
|
||||
})()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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??;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user