diff --git a/Cargo.toml b/Cargo.toml index 9df46a3a..d7576283 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ description = "The CdsCTF project is an open-source, high-performance, Jeopardy- async-trait = { version = "0.1" } tokio = { version = "1.41", features = ["full"] } tokio-util = { version = "0.7.12" } +tokio-rustls = { version = "0.26.0", features = ["ring"] } futures = { version = "^0.3" } futures-util = { version = "^0.3" } tower = { version = "0.5" } @@ -92,7 +93,7 @@ fred = { version = "9.4", features = [ ] } # Containerization & Orchestration -kube = { version = "0.96", features = ["client", "config", "runtime", "derive", "rustls-tls", "ws"] } +kube = { version = "0.97", features = ["client", "config", "runtime", "derive", "rustls-tls", "ws"] } k8s-openapi = { version = "0.23", features = ["latest"] } # Miscellaneous diff --git a/src/cluster/mod.rs b/src/cluster/mod.rs index f107e8a2..17868955 100644 --- a/src/cluster/mod.rs +++ b/src/cluster/mod.rs @@ -41,7 +41,7 @@ pub async fn init() { } pub async fn create( - name: String, challenge: crate::shared::Challenge, + name: String, challenge: crate::db::entity::challenge::Model, injected_flag: crate::db::entity::challenge::Flag, ) -> Result, anyhow::Error> { let client = get_k8s_client().clone(); diff --git a/src/db/mod.rs b/src/db/mod.rs index b2d161d7..9945c888 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,5 +1,6 @@ pub mod entity; mod migration; +pub mod transfer; use std::time::Duration; diff --git a/src/shared/challenge.rs b/src/db/transfer/challenge.rs similarity index 79% rename from src/shared/challenge.rs rename to src/db/transfer/challenge.rs index 794ed25f..93594b46 100644 --- a/src/shared/challenge.rs +++ b/src/db/transfer/challenge.rs @@ -52,6 +52,30 @@ impl From for Challenge { } } +impl From for entity::challenge::Model { + fn from(challenge: Challenge) -> Self { + Self { + id: challenge.id, + title: challenge.title, + description: challenge.description, + category: challenge.category, + tags: challenge.tags, + is_dynamic: challenge.is_dynamic, + has_attachment: challenge.has_attachment, + is_practicable: challenge.is_practicable, + image_name: challenge.image_name, + cpu_limit: challenge.cpu_limit, + memory_limit: challenge.memory_limit, + duration: challenge.duration, + ports: challenge.ports, + envs: challenge.envs, + flags: challenge.flags, + created_at: challenge.created_at, + updated_at: challenge.updated_at, + } + } +} + impl Challenge { pub fn desensitize(&mut self) { self.envs.clear(); diff --git a/src/shared/config.rs b/src/db/transfer/config.rs similarity index 100% rename from src/shared/config.rs rename to src/db/transfer/config.rs diff --git a/src/shared/game.rs b/src/db/transfer/game.rs similarity index 100% rename from src/shared/game.rs rename to src/db/transfer/game.rs diff --git a/src/shared/game_challenge.rs b/src/db/transfer/game_challenge.rs similarity index 100% rename from src/shared/game_challenge.rs rename to src/db/transfer/game_challenge.rs diff --git a/src/shared/game_team.rs b/src/db/transfer/game_team.rs similarity index 100% rename from src/shared/game_team.rs rename to src/db/transfer/game_team.rs diff --git a/src/shared/mod.rs b/src/db/transfer/mod.rs similarity index 100% rename from src/shared/mod.rs rename to src/db/transfer/mod.rs diff --git a/src/shared/pod.rs b/src/db/transfer/pod.rs similarity index 100% rename from src/shared/pod.rs rename to src/db/transfer/pod.rs diff --git a/src/shared/submission.rs b/src/db/transfer/submission.rs similarity index 100% rename from src/shared/submission.rs rename to src/db/transfer/submission.rs diff --git a/src/shared/team.rs b/src/db/transfer/team.rs similarity index 100% rename from src/shared/team.rs rename to src/db/transfer/team.rs diff --git a/src/shared/user.rs b/src/db/transfer/user.rs similarity index 100% rename from src/shared/user.rs rename to src/db/transfer/user.rs diff --git a/src/shared/user_team.rs b/src/db/transfer/user_team.rs similarity index 100% rename from src/shared/user_team.rs rename to src/db/transfer/user_team.rs diff --git a/src/main.rs b/src/main.rs index 3351f775..d9bb1f5e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,6 @@ mod logger; mod media; mod metric; mod queue; -mod shared; -mod util; mod web; use std::net::SocketAddr; diff --git a/src/util/mod.rs b/src/util/mod.rs deleted file mode 100644 index 69e1595b..00000000 --- a/src/util/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod jwt; -pub mod math; -pub mod validate; diff --git a/src/web/extract/mod.rs b/src/web/extract/mod.rs new file mode 100644 index 00000000..5109a042 --- /dev/null +++ b/src/web/extract/mod.rs @@ -0,0 +1,42 @@ +use async_trait::async_trait; +use axum::{ + extract::{path::ErrorKind, rejection::PathRejection, FromRequest, FromRequestParts}, + http::request::Parts, +}; +use serde::de::DeserializeOwned; + +use crate::web::traits::WebError; + +pub mod validate; + +pub struct Path(T); + +#[async_trait] +impl FromRequestParts for Path +where + T: DeserializeOwned + Send, + S: Send + Sync, +{ + type Rejection = WebError; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + match axum::extract::Path::::from_request_parts(parts, state).await { + Ok(value) => Ok(Self(value.0)), + Err(rejection) => match rejection { + PathRejection::FailedToDeserializePathParams(inner) => { + let kind = inner.kind(); + match &kind { + ErrorKind::UnsupportedType { .. } => { + Err(WebError::InternalServerError(kind.to_string())) + } + _ => Err(WebError::BadRequest(kind.to_string())), + } + } + PathRejection::MissingPathParams(error) => { + Err(WebError::InternalServerError(error.to_string())) + } + _ => Err(WebError::InternalServerError(rejection.to_string())), + }, + } + } +} diff --git a/src/util/validate.rs b/src/web/extract/validate.rs similarity index 100% rename from src/util/validate.rs rename to src/web/extract/validate.rs diff --git a/src/web/middleware/auth.rs b/src/web/middleware/auth.rs index 1c93c7f8..db9ab010 100644 --- a/src/web/middleware/auth.rs +++ b/src/web/middleware/auth.rs @@ -12,7 +12,7 @@ use sea_orm::EntityTrait; use crate::{ db::{entity::user::Group, get_db}, - util, + web, web::traits::{Ext, WebError}, }; @@ -37,12 +37,12 @@ pub async fn jwt(mut req: Request, next: Next) -> Result = None; + let mut user: Option = None; - let result = decode::(token, &decoding_key, &validation); + let result = decode::(token, &decoding_key, &validation); if let Ok(data) = result { user = crate::db::entity::user::Entity::find_by_id(data.claims.id) @@ -59,6 +59,8 @@ pub async fn jwt(mut req: Request, next: Next) -> Result>().unwrap(); diff --git a/src/web/middleware/error.rs b/src/web/middleware/error.rs new file mode 100644 index 00000000..43757061 --- /dev/null +++ b/src/web/middleware/error.rs @@ -0,0 +1,9 @@ +use axum::response::IntoResponse; + +use crate::web::traits::WebError; + +pub async fn validation_error(err: validator::ValidationError) -> impl IntoResponse {} + +pub async fn box_error(err: axum::BoxError) -> WebError { + WebError::InternalServerError(format!("{:?}", err)) +} diff --git a/src/web/middleware/mod.rs b/src/web/middleware/mod.rs index ceed771a..4e497c32 100644 --- a/src/web/middleware/mod.rs +++ b/src/web/middleware/mod.rs @@ -1,2 +1,2 @@ pub mod auth; -mod validate; +pub mod error; diff --git a/src/web/middleware/validate.rs b/src/web/middleware/validate.rs deleted file mode 100644 index 20fd618a..00000000 --- a/src/web/middleware/validate.rs +++ /dev/null @@ -1,3 +0,0 @@ -use axum::response::IntoResponse; - -pub async fn validation_error(err: validator::ValidationError) -> impl IntoResponse {} diff --git a/src/web/mod.rs b/src/web/mod.rs index d120c93b..c5b95e0f 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -1,3 +1,4 @@ +pub mod extract; pub mod middleware; pub mod model; pub mod router; diff --git a/src/web/router/api/challenge/mod.rs b/src/web/router/api/challenge/mod.rs index 6734988c..e28d832c 100644 --- a/src/web/router/api/challenge/mod.rs +++ b/src/web/router/api/challenge/mod.rs @@ -16,8 +16,8 @@ use crate::{ entity::{submission::Status, user::Group}, get_db, }, - util::validate, web::{ + extract::validate, model::Metadata, traits::{Ext, WebError, WebResult}, }, @@ -58,13 +58,13 @@ pub struct GetRequest { pub async fn get( Extension(ext): Extension, Query(params): Query, -) -> Result>, WebError> { +) -> Result>, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin && params.is_detailed.unwrap_or(false) { return Err(WebError::Forbidden(String::new())); } - let (mut challenges, total) = crate::shared::challenge::find( + let (mut challenges, total) = crate::db::transfer::challenge::find( params.id, params.title, params.category, @@ -103,7 +103,7 @@ pub struct StatusResult { pub is_solved: bool, pub solved_times: i64, pub pts: i64, - pub bloods: Vec, + pub bloods: Vec, } pub async fn get_status( @@ -112,7 +112,7 @@ pub async fn get_status( let _ = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; let mut submissions = - crate::shared::submission::get_by_challenge_ids(body.cids.clone()).await?; + crate::db::transfer::submission::get_by_challenge_ids(body.cids.clone()).await?; let mut result: HashMap = HashMap::new(); @@ -164,7 +164,7 @@ pub async fn get_status( if let Some(game_id) = body.game_id { let (game_challenges, _) = - crate::shared::game_challenge::find(Some(game_id), None, None).await?; + crate::db::transfer::game_challenge::find(Some(game_id), None, None).await?; for game_challenge in game_challenges { let status_response = result.get_mut(&game_challenge.challenge_id).unwrap(); @@ -200,7 +200,7 @@ pub struct CreateRequest { pub async fn create( Extension(ext): Extension, Json(body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -225,7 +225,7 @@ pub async fn create( } .insert(get_db()) .await?; - let challenge = crate::shared::Challenge::from(challenge); + let challenge = crate::db::transfer::Challenge::from(challenge); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -257,7 +257,7 @@ pub struct UpdateRequest { pub async fn update( Extension(ext): Extension, Path(id): Path, validate::Json(mut body): validate::Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -285,7 +285,7 @@ pub async fn update( } .update(get_db()) .await?; - let challenge = crate::shared::Challenge::from(challenge); + let challenge = crate::db::transfer::Challenge::from(challenge); Ok(WebResult { code: StatusCode::OK.as_u16(), diff --git a/src/web/router/api/game/calculator.rs b/src/web/router/api/game/calculator.rs index 7a6bdd3c..452645e5 100644 --- a/src/web/router/api/game/calculator.rs +++ b/src/web/router/api/game/calculator.rs @@ -56,7 +56,7 @@ pub async fn calculate(game_id: i64) { // sort submissions by created_at submissions.sort_by_key(|s| s.created_at); - let base_pts = crate::util::math::curve( + let base_pts = crate::web::util::math::curve( game_challenge.max_pts, game_challenge.min_pts, game_challenge.difficulty, diff --git a/src/web/router/api/game/mod.rs b/src/web/router/api/game/mod.rs index cb0e40b3..24fa8e5d 100644 --- a/src/web/router/api/game/mod.rs +++ b/src/web/router/api/game/mod.rs @@ -80,13 +80,13 @@ pub struct GetRequest { pub async fn get( Extension(ext): Extension, Query(params): Query, -) -> Result>, WebError> { +) -> Result>, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin && !params.is_enabled.unwrap_or(true) { return Err(WebError::Forbidden(String::new())); } - let (games, total) = crate::shared::game::find( + let (games, total) = crate::db::transfer::game::find( params.id, params.title, params.is_enabled, @@ -96,8 +96,8 @@ pub async fn get( .await?; let games = games .into_iter() - .map(|game| crate::shared::Game::from(game)) - .collect::>(); + .map(|game| crate::db::transfer::Game::from(game)) + .collect::>(); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -125,7 +125,7 @@ pub struct CreateRequest { pub async fn create( Extension(ext): Extension, Json(body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -152,7 +152,7 @@ pub async fn create( } .insert(get_db()) .await?; - let game = crate::shared::Game::from(game); + let game = crate::db::transfer::Game::from(game); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -180,7 +180,7 @@ pub struct UpdateRequest { pub async fn update( Extension(ext): Extension, Path(id): Path, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -208,7 +208,7 @@ pub async fn update( } .update(get_db()) .await?; - let game = crate::shared::Game::from(game); + let game = crate::db::transfer::Game::from(game); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -245,10 +245,10 @@ pub struct GetChallengeRequest { pub async fn get_challenge( Extension(ext): Extension, Query(params): Query, -) -> Result>, WebError> { +) -> Result>, WebError> { let _ = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; - let (game_challenges, _) = crate::shared::game_challenge::find( + let (game_challenges, _) = crate::db::transfer::game_challenge::find( params.game_id, params.challenge_id, params.is_enabled, @@ -277,7 +277,7 @@ pub struct CreateChallengeRequest { pub async fn create_challenge( Extension(ext): Extension, Json(body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -297,7 +297,7 @@ pub async fn create_challenge( } .insert(get_db()) .await?; - let game_challenge = crate::shared::GameChallenge::from(game_challenge); + let game_challenge = crate::db::transfer::GameChallenge::from(game_challenge); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -322,7 +322,7 @@ pub struct UpdateChallengeRequest { pub async fn update_challenge( Extension(ext): Extension, Path((id, challenge_id)): Path<(i64, i64)>, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -345,7 +345,7 @@ pub async fn update_challenge( } .update(get_db()) .await?; - let game_challenge = crate::shared::GameChallenge::from(game_challenge); + let game_challenge = crate::db::transfer::GameChallenge::from(game_challenge); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -382,11 +382,11 @@ pub struct GetTeamRequest { pub async fn get_team( Extension(ext): Extension, Query(params): Query, -) -> Result>, WebError> { +) -> Result>, WebError> { let _ = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; let (game_teams, total) = - crate::shared::game_team::find(params.game_id, params.team_id).await?; + crate::db::transfer::game_team::find(params.game_id, params.team_id).await?; Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -404,7 +404,7 @@ pub struct CreateTeamRequest { pub async fn create_team( Extension(ext): Extension, Json(body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -418,7 +418,7 @@ pub async fn create_team( } .insert(get_db()) .await?; - let game_team = crate::shared::GameTeam::from(game_team); + let game_team = crate::db::transfer::GameTeam::from(game_team); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -437,7 +437,7 @@ pub struct UpdateTeamRequest { pub async fn update_team( Extension(ext): Extension, Path((id, team_id)): Path<(i64, i64)>, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Forbidden(String::new())); @@ -454,7 +454,7 @@ pub async fn update_team( } .update(get_db()) .await?; - let game_team = crate::shared::GameTeam::from(game_team); + let game_team = crate::db::transfer::GameTeam::from(game_team); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -518,7 +518,7 @@ pub async fn calculate( // pub async fn get_submission( // Path(id): Path, Query(params): Query, // ) -> Result { -// let submissions = crate::shared::submission::get_with_pts(id, +// let submissions = crate::transfer::submission::get_with_pts(id, // params.status).await?; // return Ok(( @@ -534,14 +534,14 @@ pub async fn calculate( // WebError> { pub struct TeamScoreRecord {} // let submissions = -// crate::shared::submission::get_with_pts(id, -// Some(crate::shared::submission::Status::Correct)) .await; +// crate::transfer::submission::get_with_pts(id, +// Some(crate::transfer::submission::Status::Correct)) .await; -// let game_teams = crate::shared::game_team::Entity::find() +// let game_teams = crate::transfer::game_team::Entity::find() // .filter( // Condition::all() -// .add(crate::shared::game_team::Column::GameId.eq(id)) -// .add(crate::shared::game_team::Column::IsAllowed.eq(true)), +// .add(crate::transfer::game_team::Column::GameId.eq(id)) +// .add(crate::transfer::game_team::Column::IsAllowed.eq(true)), // ) // .all(get_db()) // .await?; diff --git a/src/web/router/api/pod/mod.rs b/src/web/router/api/pod/mod.rs index 1326f210..f8bf52b5 100644 --- a/src/web/router/api/pod/mod.rs +++ b/src/web/router/api/pod/mod.rs @@ -43,10 +43,10 @@ pub struct GetRequest { pub async fn get( Extension(ext): Extension, Query(params): Query, -) -> Result>, WebError> { +) -> Result>, WebError> { let _ = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; - let (mut pods, total) = crate::shared::pod::find( + let (mut pods, total) = crate::db::transfer::pod::find( params.id, params.name, params.user_id, @@ -83,14 +83,14 @@ pub struct CreateRequest { pub async fn create( Extension(ext): Extension, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; body.user_id = Some(operator.id); let challenge = crate::db::entity::challenge::Entity::find_by_id(body.challenge_id) .one(get_db()) .await? - .map(|challenge| crate::shared::Challenge::from(challenge)); + .map(|challenge| crate::db::transfer::Challenge::from(challenge)); let challenge = challenge.ok_or(WebError::BadRequest(String::from("challenge_not_found")))?; @@ -109,9 +109,13 @@ pub async fn create( .to_string(); } - let nats = crate::cluster::create(ctn_name.clone(), challenge.clone(), injected_flag.clone()) - .await - .map_err(|err| WebError::OtherError(anyhow!("{:?}", err)))?; + let nats = crate::cluster::create( + ctn_name.clone(), + crate::db::entity::challenge::Model::from(challenge.clone()), + injected_flag.clone(), + ) + .await + .map_err(|err| WebError::OtherError(anyhow!("{:?}", err)))?; let pod = crate::db::entity::pod::ActiveModel { name: Set(ctn_name), @@ -126,7 +130,7 @@ pub async fn create( } .insert(get_db()) .await?; - let mut pod = crate::shared::Pod::from(pod); + let mut pod = crate::db::transfer::Pod::from(pod); pod.desensitize(); diff --git a/src/web/router/api/submission/mod.rs b/src/web/router/api/submission/mod.rs index 81c1a947..0efb261d 100644 --- a/src/web/router/api/submission/mod.rs +++ b/src/web/router/api/submission/mod.rs @@ -42,13 +42,13 @@ pub struct GetRequest { pub async fn get( Extension(ext): Extension, Query(params): Query, -) -> Result>, WebError> { +) -> Result>, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin && params.is_detailed.unwrap_or(false) { return Err(WebError::Forbidden(String::new())); } - let (mut submissions, total) = crate::shared::submission::find( + let (mut submissions, total) = crate::db::transfer::submission::find( params.id, params.user_id, params.team_id, @@ -77,7 +77,7 @@ pub async fn get( pub async fn get_by_id( Extension(ext): Extension, Path(id): Path, -) -> Result, WebError> { +) -> Result, WebError> { let _ = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; let submission = crate::db::entity::submission::Entity::find_by_id(id) @@ -89,7 +89,7 @@ pub async fn get_by_id( } let submission = submission.unwrap(); - let mut submission = crate::shared::Submission::from(submission); + let mut submission = crate::db::transfer::Submission::from(submission); submission.desensitize(); Ok(WebResult { @@ -110,7 +110,7 @@ pub struct CreateRequest { pub async fn create( Extension(ext): Extension, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; body.user_id = Some(operator.id); @@ -156,7 +156,7 @@ pub async fn create( } .insert(get_db()) .await?; - let submission = crate::shared::Submission::from(submission); + let submission = crate::db::transfer::Submission::from(submission); crate::queue::publish("checker", submission.id).await?; diff --git a/src/web/router/api/team/mod.rs b/src/web/router/api/team/mod.rs index 1482b243..06b9856b 100644 --- a/src/web/router/api/team/mod.rs +++ b/src/web/router/api/team/mod.rs @@ -48,7 +48,7 @@ pub fn router() -> Router { .route("/:id/avatar", axum::routing::delete(delete_avatar)) } -fn can_modify_team(user: crate::shared::User, team_id: i64) -> bool { +fn can_modify_team(user: crate::db::transfer::User, team_id: i64) -> bool { user.group == Group::Admin || user .teams @@ -68,8 +68,8 @@ pub struct GetRequest { pub async fn get( Query(params): Query, -) -> Result>, WebError> { - let (teams, total) = crate::shared::team::find( +) -> Result>, WebError> { + let (teams, total) = crate::db::transfer::team::find( params.id, params.name, params.email, @@ -96,7 +96,7 @@ pub struct CreateRequest { pub async fn create( Extension(ext): Extension, Json(body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if !(operator.group == Group::Admin || operator.id == body.captain_id) { return Err(WebError::Forbidden(String::new())); @@ -112,7 +112,7 @@ pub async fn create( .insert(get_db()) .await?; - let team = crate::shared::Team::from(team); + let team = crate::db::transfer::Team::from(team); let _ = crate::db::entity::user_team::ActiveModel { user_id: Set(body.captain_id), @@ -140,7 +140,7 @@ pub struct UpdateRequest { pub async fn update( Extension(ext): Extension, Path(id): Path, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if !can_modify_team(operator, id) { @@ -158,7 +158,7 @@ pub async fn update( } .update(get_db()) .await?; - let team = crate::shared::Team::from(team); + let team = crate::db::transfer::Team::from(team); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -295,7 +295,7 @@ pub struct JoinRequest { pub async fn join( Extension(ext): Extension, Json(mut body): Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; body.user_id = operator.id; @@ -321,7 +321,7 @@ pub async fn join( } .insert(get_db()) .await?; - let user_team = crate::shared::UserTeam::from(user_team); + let user_team = crate::db::transfer::UserTeam::from(user_team); Ok(WebResult { code: StatusCode::OK.as_u16(), diff --git a/src/web/router/api/user/mod.rs b/src/web/router/api/user/mod.rs index 8077b943..1ee88f00 100644 --- a/src/web/router/api/user/mod.rs +++ b/src/web/router/api/user/mod.rs @@ -24,11 +24,11 @@ use crate::{ config, db::{entity::user::Group, get_db}, media::util::hash, - util::{jwt, validate}, web::{ + extract::validate, model::Metadata, traits::{Ext, WebError, WebResult}, - util::handle_image_multipart, + util::{handle_image_multipart, jwt}, }, }; @@ -66,8 +66,8 @@ pub struct GetRequest { pub async fn get( Query(params): Query, -) -> Result>, WebError> { - let (mut users, total) = crate::shared::user::find( +) -> Result>, WebError> { + let (mut users, total) = crate::db::transfer::user::find( params.id, params.name, None, @@ -101,7 +101,7 @@ pub struct CreateRequest { pub async fn create( Extension(ext): Extension, validate::Json(mut body): validate::Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; if operator.group != Group::Admin { return Err(WebError::Unauthorized(String::new())); @@ -125,7 +125,7 @@ pub async fn create( } .insert(get_db()) .await?; - let mut user = crate::shared::User::from(user); + let mut user = crate::db::transfer::User::from(user); user.desensitize(); @@ -151,7 +151,7 @@ pub struct UpdateRequest { pub async fn update( Extension(ext): Extension, Path(id): Path, validate::Json(mut body): validate::Json, -) -> Result, WebError> { +) -> Result, WebError> { let operator = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; body.id = Some(id); if !(operator.group == Group::Admin @@ -180,7 +180,7 @@ pub async fn update( } .update(get_db()) .await?; - let user = crate::shared::User::from(user); + let user = crate::db::transfer::User::from(user); Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -213,10 +213,10 @@ pub async fn delete( pub async fn get_teams( Extension(ext): Extension, Path(id): Path, -) -> Result>, WebError> { +) -> Result>, WebError> { let _ = ext.operator.ok_or(WebError::Unauthorized(String::new()))?; - let teams = crate::shared::team::find_by_user_id(id).await?; + let teams = crate::db::transfer::team::find_by_user_id(id).await?; Ok(WebResult { code: StatusCode::OK.as_u16(), @@ -254,7 +254,7 @@ pub async fn login(Json(mut body): Json) -> Result, validate::Json(mut body): validate::Json, -) -> Result, WebError> { +) -> Result, WebError> { body.email = body.email.to_lowercase(); body.username = body.username.to_lowercase(); @@ -350,7 +350,7 @@ pub async fn register( } .insert(get_db()) .await?; - let user = crate::shared::User::from(user); + let user = crate::db::transfer::User::from(user); Ok(WebResult { code: StatusCode::OK.as_u16(), diff --git a/src/web/router/mod.rs b/src/web/router/mod.rs index c956d503..68f039f8 100644 --- a/src/web/router/mod.rs +++ b/src/web/router/mod.rs @@ -1,7 +1,7 @@ pub mod api; pub mod metric; -use axum::{middleware::from_fn, response::IntoResponse, Router}; +use axum::{extract::FromRequest, middleware::from_fn, response::IntoResponse, Router}; use tower_http::trace::TraceLayer; use crate::web::middleware; diff --git a/src/web/traits.rs b/src/web/traits.rs index ef1aa566..b4e2a0e5 100644 --- a/src/web/traits.rs +++ b/src/web/traits.rs @@ -12,7 +12,7 @@ use tracing::error; #[derive(Clone, Debug)] pub struct Ext { - pub operator: Option, + pub operator: Option, pub client_ip: String, } diff --git a/src/util/jwt.rs b/src/web/util/jwt.rs similarity index 100% rename from src/util/jwt.rs rename to src/web/util/jwt.rs diff --git a/src/util/math.rs b/src/web/util/math.rs similarity index 100% rename from src/util/math.rs rename to src/web/util/math.rs diff --git a/src/web/util/mod.rs b/src/web/util/mod.rs index 00f5a6a8..989ad293 100644 --- a/src/web/util/mod.rs +++ b/src/web/util/mod.rs @@ -3,6 +3,9 @@ use mime::Mime; use crate::web::traits::WebError; +pub mod jwt; +pub mod math; + pub async fn handle_image_multipart(mut multipart: Multipart) -> Result, WebError> { while let Some(field) = multipart.next_field().await.unwrap() { if field.name() == Some("file") {