diff --git a/core/src/api/build.rs b/core/src/api/build.rs index 68b3d6791..8d70357fe 100644 --- a/core/src/api/build.rs +++ b/core/src/api/build.rs @@ -2,17 +2,25 @@ use std::str::FromStr; use anyhow::{anyhow, Context}; use async_timing_util::unix_timestamp_ms; -use axum::{Extension, Json, Router}; +use axum::{routing::post, Extension, Json, Router}; use db::DbExtension; +use helpers::handle_anyhow_error; use mungos::ObjectId; use types::{Build, EntityType, Operation, PermissionLevel, Update}; use crate::{auth::RequestUserExtension, ws::update}; -use super::PeripheryExtension; +use super::{add_update, PeripheryExtension}; pub fn router() -> Router { - Router::new() + Router::new().route( + "/create", + post(|db, user, update_ws, build| async { + create(db, user, update_ws, build) + .await + .map_err(handle_anyhow_error); + }), + ) } async fn create( @@ -40,21 +48,14 @@ async fn create( .collect(); let start_ts = unix_timestamp_ms() as i64; let build_id = db.builds.create_one(build).await?; - let mut update = Update { + let update = Update { entity_type: EntityType::Build, entity_id: Some(build_id), operation: Operation::CreateBuild, start_ts, end_ts: unix_timestamp_ms() as i64, + operator: user.id.clone(), ..Default::default() }; - let update_id = db - .updates - .create_one(update.clone()) - .await - .context("failed to insert update into db. the create build process was completed.")?; - update.id = Some(ObjectId::from_str(&update_id).context("failed at attaching update id")?); - let update_msg = serde_json::to_string(&update).unwrap(); - let _ = update_ws.lock().await.send((update, update_msg)); - Ok(()) + add_update(update, &db, &update_ws).await } diff --git a/core/src/api/deployment.rs b/core/src/api/deployment.rs new file mode 100644 index 000000000..33872e7cd --- /dev/null +++ b/core/src/api/deployment.rs @@ -0,0 +1,48 @@ +use anyhow::{anyhow, Context}; +use async_timing_util::unix_timestamp_ms; +use axum::{routing::post, Extension, Json, Router}; +use db::DbExtension; +use helpers::handle_anyhow_error; +use types::{Deployment, EntityType, Operation, PermissionLevel, Update}; + +use crate::{auth::RequestUserExtension, ws::update}; + +use super::add_update; + +pub fn router() -> Router { + Router::new().route( + "/create", + post(|db, user, update_ws, deployment| async { + create(db, user, update_ws, deployment) + .await + .map_err(handle_anyhow_error) + }), + ) +} + +async fn create( + Extension(db): DbExtension, + Extension(user): RequestUserExtension, + Extension(update_ws): update::WsSenderExtension, + Json(mut deployment): Json, +) -> anyhow::Result<()> { + deployment.permissions = [(user.id.clone(), PermissionLevel::Write)] + .into_iter() + .collect(); + let start_ts = unix_timestamp_ms() as i64; + let deployment_id = db + .deployments + .create_one(deployment) + .await + .context("failed to add server to db")?; + let update = Update { + entity_type: EntityType::Deployment, + entity_id: Some(deployment_id), + operation: Operation::CreateDeployment, + start_ts, + end_ts: unix_timestamp_ms() as i64, + operator: user.id.clone(), + ..Default::default() + }; + add_update(update, &db, &update_ws).await +} diff --git a/core/src/api/mod.rs b/core/src/api/mod.rs index c46d419ff..7810e0064 100644 --- a/core/src/api/mod.rs +++ b/core/src/api/mod.rs @@ -1,15 +1,21 @@ -use std::sync::Arc; +use std::{str::FromStr, sync::Arc}; -use anyhow::anyhow; +use anyhow::{anyhow, Context}; use axum::{middleware, routing::get, Extension, Json, Router}; -use db::DbExtension; +use db::{DbClient, DbExtension}; use helpers::handle_anyhow_error; +use mungos::ObjectId; use periphery::PeripheryClient; -use types::User; +use types::{Update, User}; -use crate::auth::{auth_request, RequestUserExtension}; +use crate::{ + auth::{auth_request, RequestUserExtension}, + ws::update, +}; mod build; +mod deployment; +mod server; type PeripheryExtension = Extension>; @@ -20,6 +26,8 @@ pub fn router() -> Router { get(|user, db| async { get_user(user, db).await.map_err(handle_anyhow_error) }), ) .nest("/build", build::router()) + .nest("/deployment", deployment::router()) + .nest("/server", server::router()) .layer(Extension(Arc::new(PeripheryClient::new()))) .layer(middleware::from_fn(auth_request)) } @@ -36,3 +44,19 @@ async fn get_user( user.password = None; Ok(Json(user)) } + +async fn add_update( + mut update: Update, + db: &DbClient, + update_ws: &update::WsSender, +) -> anyhow::Result<()> { + let update_id = db + .updates + .create_one(update.clone()) + .await + .context("failed to insert update into db. the create build process was completed.")?; + update.id = Some(ObjectId::from_str(&update_id).context("failed at attaching update id")?); + let update_msg = serde_json::to_string(&update).unwrap(); + let _ = update_ws.lock().await.send((update, update_msg)); + Ok(()) +} diff --git a/core/src/api/server.rs b/core/src/api/server.rs new file mode 100644 index 000000000..a8b85ce94 --- /dev/null +++ b/core/src/api/server.rs @@ -0,0 +1,48 @@ +use anyhow::{anyhow, Context}; +use async_timing_util::unix_timestamp_ms; +use axum::{routing::post, Extension, Json, Router}; +use db::DbExtension; +use helpers::handle_anyhow_error; +use types::{EntityType, Operation, PermissionLevel, Server, Update}; + +use crate::{auth::RequestUserExtension, ws::update}; + +use super::add_update; + +pub fn router() -> Router { + Router::new().route( + "/create", + post(|db, user, update_ws, server| async { + create(db, user, update_ws, server) + .await + .map_err(handle_anyhow_error) + }), + ) +} + +async fn create( + Extension(db): DbExtension, + Extension(user): RequestUserExtension, + Extension(update_ws): update::WsSenderExtension, + Json(mut server): Json, +) -> anyhow::Result<()> { + server.permissions = [(user.id.clone(), PermissionLevel::Write)] + .into_iter() + .collect(); + let start_ts = unix_timestamp_ms() as i64; + let server_id = db + .servers + .create_one(server) + .await + .context("failed to add server to db")?; + let update = Update { + entity_type: EntityType::Server, + entity_id: Some(server_id), + operation: Operation::CreateServer, + start_ts, + end_ts: unix_timestamp_ms() as i64, + operator: user.id.clone(), + ..Default::default() + }; + add_update(update, &db, &update_ws).await +} diff --git a/core/src/ws/update.rs b/core/src/ws/update.rs index e695cfd1c..f7638ee3c 100644 --- a/core/src/ws/update.rs +++ b/core/src/ws/update.rs @@ -122,6 +122,9 @@ async fn user_can_see_update( entity_id: &Option, db_client: &DbClient, ) -> anyhow::Result<()> { + if user.admin { + return Ok(()); + } match entity_type { EntityType::System => { if user.admin {