Compare commits
No commits in common. "c36a38cd7a7c0226fd97bdb1b9f004efbdbdbb01" and "e078bffc255e4974528944c7f86cd70b3152e3fc" have entirely different histories.
c36a38cd7a
...
e078bffc25
5 changed files with 11 additions and 196 deletions
|
|
@ -107,10 +107,6 @@ async fn main() {
|
|||
log::error!(target: "database", "Error while creating user table: {err:?}");
|
||||
return;
|
||||
}
|
||||
if let Err(err) = db.execute(builder.build(schema.create_table_from_entity(crate::entities::prelude::Bal).if_not_exists())).await {
|
||||
log::error!(target: "database", "Error while creating bal table: {err:?}");
|
||||
return;
|
||||
}
|
||||
|
||||
match cli.command {
|
||||
Commands::Run => run_server(db).await,
|
||||
|
|
@ -175,11 +171,6 @@ async fn run_server(db: Arc<DatabaseConnection>) {
|
|||
.routes(routes!(routes::owner::create_owner))
|
||||
.routes(routes!(routes::owner::update_owner))
|
||||
.routes(routes!(routes::owner::get_owners))
|
||||
// Bal API
|
||||
.routes(routes!(routes::bal::get_bal_by_id))
|
||||
.routes(routes!(routes::bal::create_bal))
|
||||
.routes(routes!(routes::bal::update_bal))
|
||||
.routes(routes!(routes::bal::get_bals))
|
||||
// Misc
|
||||
.routes(routes!(routes::websocket::ws_handler))
|
||||
// Authentication
|
||||
|
|
|
|||
|
|
@ -1,161 +0,0 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{extract::{Path, State}, Json};
|
||||
use reqwest::{StatusCode};
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::{NotSet, Set}, ColumnTrait, EntityTrait, QueryFilter, TryIntoModel};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::{entities::{bal, prelude::*}, routes::auth::Claims, AppState};
|
||||
|
||||
|
||||
#[derive(IntoParams)]
|
||||
#[into_params(names("id"), parameter_in = Path)]
|
||||
#[allow(dead_code)]
|
||||
struct BalByIdParams(u32);
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/bal/{id}",
|
||||
params(BalByIdParams),
|
||||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = bal::Model, description = "Found bal with corresponding ID in the database"),
|
||||
(status = NOT_FOUND, description = "No bal with this id exists in the database"),
|
||||
(status = FORBIDDEN, description = "You don't own the specified bal"),
|
||||
),
|
||||
summary = "Get a bal by its ID",
|
||||
description = "Get a bal from its ID",
|
||||
tag = "bal-api",
|
||||
)]
|
||||
pub async fn get_bal_by_id(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(id): Path<u32>,
|
||||
) -> (StatusCode, Json<Option<bal::Model>>) {
|
||||
if let Ok(Some(res)) = Bal::find_by_id(id).one(state.db_conn.as_ref()).await {
|
||||
if !res.user_id == claims.user_id {
|
||||
(StatusCode::FORBIDDEN, Json(None))
|
||||
} else {
|
||||
(StatusCode::OK, Json(Some(res)))
|
||||
}
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, Json(None))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
|
||||
pub struct BalCreateParams {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/bal",
|
||||
request_body = BalCreateParams,
|
||||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = bal::Model, description = "Successfully created BAL"),
|
||||
),
|
||||
summary = "Create a new bal",
|
||||
description = "Create a new bal",
|
||||
tag = "bal-api",
|
||||
)]
|
||||
pub async fn create_bal(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Json(instance_payload): Json<BalCreateParams>,
|
||||
) -> (StatusCode, Json<Option<bal::Model>>) {
|
||||
let bal = bal::ActiveModel {
|
||||
id: NotSet,
|
||||
user_id: Set(claims.user_id),
|
||||
name: Set(instance_payload.name),
|
||||
};
|
||||
|
||||
let b = bal.save(state.db_conn.as_ref()).await;
|
||||
match b {
|
||||
Err(e) => {
|
||||
log::error!(target: "api", "Error while inserting new bal: {:#?}", e);
|
||||
(StatusCode::BAD_REQUEST, Json(None))
|
||||
},
|
||||
Ok(res) => (StatusCode::OK, Json(Some(res.try_into_model().expect("All fields should be set once the bal is saved"))))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
|
||||
pub struct BalUpdateParams {
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[utoipa::path(
|
||||
patch,
|
||||
path = "/bal/{id}",
|
||||
params(BalByIdParams),
|
||||
request_body = BalUpdateParams,
|
||||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = bal::Model, description = "Successfully updated bal"),
|
||||
(status = NOT_FOUND, description = "No bal with specified id was found"),
|
||||
(status = FORBIDDEN, description = "You don't own the specified bal"),
|
||||
),
|
||||
summary = "Update a bal",
|
||||
description = "Update a bal",
|
||||
tag = "bal-api",
|
||||
)]
|
||||
pub async fn update_bal(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(id): Path<u32>,
|
||||
Json(instance_payload): Json<BalUpdateParams>,
|
||||
) -> (StatusCode, Json<Option<bal::Model>>) {
|
||||
if let Ok(Some(bal)) = Bal::find_by_id(id).one(state.db_conn.as_ref()).await {
|
||||
if bal.user_id != claims.user_id {
|
||||
return (StatusCode::FORBIDDEN, Json(None));
|
||||
}
|
||||
let mut bal: bal::ActiveModel = bal.into();
|
||||
bal.name = match instance_payload.name {
|
||||
None => bal.name,
|
||||
Some(v) => Set(v)
|
||||
};
|
||||
|
||||
match bal.update(state.db_conn.as_ref()).await {
|
||||
Err(e) => {
|
||||
log::error!(target: "api", "Error while updating bal from api: {:#?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(None))
|
||||
},
|
||||
Ok(res) => {
|
||||
let model = res.try_into_model().expect("All fields should be set once the bal is saved");
|
||||
(StatusCode::OK, Json(Some(model)))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, Json(None))
|
||||
}
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/bals",
|
||||
params(BalByIdParams),
|
||||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = Vec<bal::Model>, description = "All Bals you own"),
|
||||
),
|
||||
summary = "Get all Bals you own",
|
||||
description = "Get all Bals you own",
|
||||
tag = "bal-api",
|
||||
)]
|
||||
pub async fn get_bals(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
) -> (StatusCode, Json<Vec<bal::Model>>) {
|
||||
if let Ok(res) = Bal::find().filter(bal::Column::UserId.eq(claims.user_id)).all(state.db_conn.as_ref()).await {
|
||||
(StatusCode::OK, Json(res))
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, Json(vec![]))
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,7 @@ struct BookInstanceByIdParams(u32);
|
|||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = book_instance::Model, description = "Found book instance with corresponding ID in the database"),
|
||||
(status = NOT_FOUND, description = "No book instance with this id exists in the database"),
|
||||
(status = FORBIDDEN, description = "You don't own the requested book instance"),
|
||||
(status = NOT_FOUND, description = "No book instance with this id exists in the database")
|
||||
),
|
||||
summary = "Get a book instance by its ID",
|
||||
description = "Get a book instance from its ID",
|
||||
|
|
@ -31,13 +30,9 @@ struct BookInstanceByIdParams(u32);
|
|||
)]
|
||||
pub async fn get_book_instance_by_id(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(id): Path<u32>,
|
||||
) -> (StatusCode, Json<Option<book_instance::Model>>) {
|
||||
if let Ok(Some(res)) = BookInstance::find_by_id(id).one(state.db_conn.as_ref()).await {
|
||||
if !user_is_book_instance_owner(claims.user_id, res.id, state.db_conn.as_ref()).await {
|
||||
return (StatusCode::FORBIDDEN, Json(None));
|
||||
}
|
||||
(StatusCode::OK, Json(Some(res)))
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, Json(None))
|
||||
|
|
@ -60,7 +55,7 @@ pub struct BookInstanceCreateParams {
|
|||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = book_instance::Model, description = "Successfully created book instance"),
|
||||
(status = FORBIDDEN, description = "You don't own the specified book instance"),
|
||||
(status = FORBIDDEN, description = "You don't own the specified BAL"),
|
||||
),
|
||||
summary = "Create a new book instance",
|
||||
description = "Create a new book instance",
|
||||
|
|
@ -81,8 +76,7 @@ pub async fn create_book_instance(
|
|||
bal_id: Set(instance_payload.bal_id),
|
||||
price: Set(instance_payload.price),
|
||||
status: Set(book_instance::BookStatus::Available),
|
||||
id: NotSet,
|
||||
sold_price: NotSet,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let b = book_instance.save(state.db_conn.as_ref()).await;
|
||||
|
|
@ -173,7 +167,6 @@ pub struct BookInstanceSaleParams {
|
|||
responses(
|
||||
(status = OK, body = book_instance::Model, description = "Successfully sold book instance"),
|
||||
(status = NOT_FOUND, description = "No book instance with specified id was found"),
|
||||
(status = FORBIDDEN, description = "You don't own the specified book instance"),
|
||||
),
|
||||
summary = "Sell a book instance",
|
||||
description = "Sell a book instance",
|
||||
|
|
@ -234,7 +227,7 @@ pub async fn bulk_create_book_instance(
|
|||
}
|
||||
}
|
||||
|
||||
let instances = instance_payload
|
||||
let instances = instance_payload
|
||||
.into_iter()
|
||||
.map(|p| {
|
||||
book_instance::ActiveModel {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
pub mod auth;
|
||||
pub mod bal;
|
||||
pub mod book;
|
||||
pub mod book_instance;
|
||||
pub mod owner;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||
|
||||
use axum::{extract::{Path, State}, Json};
|
||||
use reqwest::{StatusCode};
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::{NotSet, Set}, ColumnTrait, EntityTrait, QueryFilter, TryIntoModel};
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::{NotSet, Set, Unchanged}, EntityTrait, TryIntoModel};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::IntoParams;
|
||||
|
||||
|
|
@ -22,8 +22,7 @@ struct OwnerByIdParams(u32);
|
|||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = owner::Model, description = "Found owner with corresponding ID in the database"),
|
||||
(status = NOT_FOUND, description = "No owner with this id exists in the database"),
|
||||
(status = FORBIDDEN, description = "You do not own the specified owner"),
|
||||
(status = NOT_FOUND, description = "No owner with this id exists in the database")
|
||||
),
|
||||
summary = "Get an owner by its ID",
|
||||
description = "Get an owner from its ID",
|
||||
|
|
@ -31,15 +30,10 @@ struct OwnerByIdParams(u32);
|
|||
)]
|
||||
pub async fn get_owner_by_id(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(id): Path<u32>,
|
||||
) -> (StatusCode, Json<Option<owner::Model>>) {
|
||||
if let Ok(Some(res)) = Owner::find_by_id(id).one(state.db_conn.as_ref()).await {
|
||||
if res.user_id != claims.user_id {
|
||||
(StatusCode::FORBIDDEN, Json(None))
|
||||
} else {
|
||||
(StatusCode::OK, Json(Some(res)))
|
||||
}
|
||||
(StatusCode::OK, Json(Some(res)))
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, Json(None))
|
||||
}
|
||||
|
|
@ -171,15 +165,14 @@ pub async fn update_owner(
|
|||
)]
|
||||
pub async fn get_owners(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims
|
||||
) -> (StatusCode, Json<Vec<owner::Model>>) {
|
||||
match Owner::find().filter(owner::Column::UserId.eq(claims.user_id)).all(state.db_conn.as_ref()).await {
|
||||
) -> (StatusCode, Json<Option<Vec<owner::Model>>>) {
|
||||
match Owner::find().all(state.db_conn.as_ref()).await {
|
||||
Err(e) => {
|
||||
log::error!(target: "api", "Error while getting owner list: {:#?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(vec![]))
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(None))
|
||||
}
|
||||
Ok(owners) => {
|
||||
(StatusCode::OK, Json(owners))
|
||||
(StatusCode::OK, Json(Some(owners)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue