From 7719c1722795d79a33cc6f24df9171c7999fdd8d Mon Sep 17 00:00:00 2001 From: beckerinj Date: Thu, 15 Dec 2022 00:24:57 -0500 Subject: [PATCH] outline functions on state to work with procedures --- cli/src/types.rs | 4 +- core/src/actions/build.rs | 12 +++--- core/src/actions/deployment.rs | 14 +++---- core/src/actions/mod.rs | 1 + core/src/actions/procedure.rs | 69 ++++++++++++++++++++++++++++++++ core/src/actions/server.rs | 12 +++--- core/src/api/build.rs | 4 +- core/src/api/deployment.rs | 4 +- core/src/api/server.rs | 4 +- lib/db_client/src/collections.rs | 12 ------ lib/db_client/src/lib.rs | 27 ++++++++++++- lib/types/src/lib.rs | 26 +++++++++++- lib/types/src/traits.rs | 8 +++- 13 files changed, 153 insertions(+), 44 deletions(-) create mode 100644 core/src/actions/procedure.rs diff --git a/cli/src/types.rs b/cli/src/types.rs index cb6f42407..efa5534a4 100644 --- a/cli/src/types.rs +++ b/cli/src/types.rs @@ -89,9 +89,7 @@ fn default_repo_dir() -> String { "/repos".to_string() } -#[derive( - Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, -)] +#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] pub enum RestartMode { #[serde(rename = "no")] #[strum(serialize = "no")] diff --git a/core/src/actions/build.rs b/core/src/actions/build.rs index 1147aae22..266828dae 100644 --- a/core/src/actions/build.rs +++ b/core/src/actions/build.rs @@ -74,14 +74,14 @@ impl State { pub async fn create_full_build( &self, - mut full_build: Build, + mut build: Build, user: &RequestUser, ) -> anyhow::Result { - let build = self - .create_build(&full_build.name, full_build.server_id.clone(), user) - .await?; - full_build.id = build.id; - let build = self.update_build(full_build, user).await?; + build.id = self + .create_build(&build.name, build.server_id.clone(), user) + .await? + .id; + let build = self.update_build(build, user).await?; Ok(build) } diff --git a/core/src/actions/deployment.rs b/core/src/actions/deployment.rs index 12793c500..80d198146 100644 --- a/core/src/actions/deployment.rs +++ b/core/src/actions/deployment.rs @@ -72,18 +72,18 @@ impl State { pub async fn create_full_deployment( &self, - mut full_deployment: Deployment, + mut deployment: Deployment, user: &RequestUser, ) -> anyhow::Result { - let deployment = self + deployment.id = self .create_deployment( - &full_deployment.name, - full_deployment.server_id.clone(), + &deployment.name, + deployment.server_id.clone(), user, ) - .await?; - full_deployment.id = deployment.id; - let deployment = self.update_deployment(full_deployment, user).await?; + .await? + .id; + let deployment = self.update_deployment(deployment, user).await?; Ok(deployment) } diff --git a/core/src/actions/mod.rs b/core/src/actions/mod.rs index 5c62f478e..e5096f88a 100644 --- a/core/src/actions/mod.rs +++ b/core/src/actions/mod.rs @@ -5,6 +5,7 @@ use crate::state::State; mod build; mod deployment; +mod procedure; mod server; impl State { diff --git a/core/src/actions/procedure.rs b/core/src/actions/procedure.rs new file mode 100644 index 000000000..62b7687bf --- /dev/null +++ b/core/src/actions/procedure.rs @@ -0,0 +1,69 @@ +use anyhow::anyhow; +use types::{traits::Permissioned, PermissionLevel, Procedure, Update}; + +use crate::{auth::RequestUser, state::State}; + +impl State { + pub async fn get_procedure_check_permissions( + &self, + procedure_id: &str, + user: &RequestUser, + permission_level: PermissionLevel, + ) -> anyhow::Result { + let procedure = self.db.get_procedure(procedure_id).await?; + let permissions = procedure.get_user_permissions(&user.id); + if user.is_admin || permissions >= permission_level { + Ok(procedure) + } else { + Err(anyhow!( + "user does not have required permissions on this procedure" + )) + } + } + + pub async fn create_procedure( + &self, + name: &str, + user: &RequestUser, + ) -> anyhow::Result { + todo!() + } + + pub async fn create_full_procedure( + &self, + mut full_procedure: Procedure, + user: &RequestUser, + ) -> anyhow::Result { + let procedure = self.create_procedure(&full_procedure.name, user).await?; + full_procedure.id = procedure.id; + let procedure = self.update_procedure(full_procedure, user).await?; + Ok(procedure) + } + + pub async fn delete_procedure( + &self, + id: &str, + user: &RequestUser, + ) -> anyhow::Result { + todo!() + } + + pub async fn update_procedure( + &self, + new_procedure: Procedure, + user: &RequestUser, + ) -> anyhow::Result { + let current_procedure = self + .get_procedure_check_permissions(&new_procedure.id, user, PermissionLevel::Write) + .await?; + todo!() + } + + pub async fn run_procedure(&self, id: &str, user: &RequestUser) -> anyhow::Result> { + let procedure = self + .get_procedure_check_permissions(id, user, PermissionLevel::Write) + .await?; + + todo!() + } +} diff --git a/core/src/actions/server.rs b/core/src/actions/server.rs index 784f39ec7..531d3fd71 100644 --- a/core/src/actions/server.rs +++ b/core/src/actions/server.rs @@ -72,14 +72,14 @@ impl State { pub async fn create_full_server( &self, - mut full_server: Server, + mut server: Server, user: &RequestUser, ) -> anyhow::Result { - let server = self - .create_server(&full_server.name, full_server.address.clone(), user) - .await?; - full_server.id = server.id; - let server = self.update_server(full_server, user).await?; + server.id = self + .create_server(&server.name, server.address.clone(), user) + .await? + .id; + let server = self.update_server(server, user).await?; Ok(server) } diff --git a/core/src/api/build.rs b/core/src/api/build.rs index 3955ad559..79fe8a1a7 100644 --- a/core/src/api/build.rs +++ b/core/src/api/build.rs @@ -74,9 +74,9 @@ pub fn router() -> Router { post( |Extension(state): StateExtension, Extension(user): RequestUserExtension, - Json(full_build): Json| async move { + Json(build): Json| async move { let build = state - .create_full_build(full_build, &user) + .create_full_build(build, &user) .await .map_err(handle_anyhow_error)?; response!(Json(build)) diff --git a/core/src/api/deployment.rs b/core/src/api/deployment.rs index a56c97879..aaf24c26e 100644 --- a/core/src/api/deployment.rs +++ b/core/src/api/deployment.rs @@ -77,9 +77,9 @@ pub fn router() -> Router { post( |Extension(state): StateExtension, Extension(user): RequestUserExtension, - Json(full_deployment): Json| async move { + Json(deployment): Json| async move { let deployment = state - .create_full_deployment(full_deployment, &user) + .create_full_deployment(deployment, &user) .await .map_err(handle_anyhow_error)?; response!(Json(deployment)) diff --git a/core/src/api/server.rs b/core/src/api/server.rs index b517d1f0d..f272c71f6 100644 --- a/core/src/api/server.rs +++ b/core/src/api/server.rs @@ -63,9 +63,9 @@ pub fn router() -> Router { post( |Extension(state): StateExtension, Extension(user): RequestUserExtension, - Json(full_server): Json| async move { + Json(server): Json| async move { let server = state - .create_full_server(full_server, &user) + .create_full_server(server, &user) .await .map_err(handle_anyhow_error)?; response!(Json(server)) diff --git a/lib/db_client/src/collections.rs b/lib/db_client/src/collections.rs index c6b2b3ef7..752838381 100644 --- a/lib/db_client/src/collections.rs +++ b/lib/db_client/src/collections.rs @@ -18,9 +18,6 @@ pub async fn servers_collection( coll.create_unique_index("name") .await .context("failed at creating name index")?; - coll.create_index("permissions") - .await - .context("failed at creating permissions index")?; Ok(coll) } @@ -32,9 +29,6 @@ pub async fn deployments_collection( coll.create_unique_index("name") .await .context("failed at creating name index")?; - coll.create_index("permissions") - .await - .context("failed at creating permissions index")?; Ok(coll) } @@ -46,9 +40,6 @@ pub async fn builds_collection( coll.create_unique_index("name") .await .context("failed at creating name index")?; - coll.create_index("permissions") - .await - .context("failed at creating permissions index")?; Ok(coll) } @@ -77,8 +68,5 @@ pub async fn procedures_collection( coll.create_index("name") .await .context("failed at creating entity_id index")?; - coll.create_index("permissions") - .await - .context("failed at creating permissions index")?; Ok(coll) } diff --git a/lib/db_client/src/lib.rs b/lib/db_client/src/lib.rs index 52146fb34..e009ddffe 100644 --- a/lib/db_client/src/lib.rs +++ b/lib/db_client/src/lib.rs @@ -38,7 +38,6 @@ impl DbClient { builds: builds_collection(&mungos, db_name) .await .expect("failed to make builds collection"), - // build_records: updates: updates_collection(&mungos, db_name) .await .expect("failed to make updates collection"), @@ -131,4 +130,30 @@ impl DbClient { .unwrap_or_default(); Ok(permissions) } + + pub async fn get_procedure(&self, procedure_id: &str) -> anyhow::Result { + let procedure = self + .procedures + .find_one_by_id(procedure_id) + .await + .context(format!( + "failed at mongo query for procedure {procedure_id}" + ))? + .ok_or(anyhow!("procedure at {procedure_id} doesn't exist"))?; + Ok(procedure) + } + + pub async fn get_user_permission_on_procedure( + &self, + user_id: &str, + procedure_id: &str, + ) -> anyhow::Result { + let permissions = *self + .get_procedure(procedure_id) + .await? + .permissions + .get(user_id) + .unwrap_or_default(); + Ok(permissions) + } } diff --git a/lib/types/src/lib.rs b/lib/types/src/lib.rs index 1097e28af..91eb36afc 100644 --- a/lib/types/src/lib.rs +++ b/lib/types/src/lib.rs @@ -331,7 +331,7 @@ pub struct Update { pub version: Option, } -#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff)] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] #[diff(attr(#[derive(Debug, Serialize)]))] pub struct Procedure { #[serde( @@ -340,10 +340,27 @@ pub struct Procedure { skip_serializing_if = "String::is_empty", with = "hex_string_as_object_id" )] + #[builder(setter(skip))] pub id: String, pub name: String, - pub procedure: Vec, + pub procedure: Vec, + #[builder(setter(skip))] pub permissions: PermissionsMap, + + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub created_at: i64, + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub updated_at: i64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct ProcedureStage { + pub operation: Operation, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, Diff, Builder)] @@ -674,6 +691,11 @@ pub enum Operation { StartDeployment, PullDeployment, RecloneDeployment, + + // procedure + CreateProcedure, + UpdateProcedure, + DeleteProcedure, } impl Default for Operation { diff --git a/lib/types/src/traits.rs b/lib/types/src/traits.rs index a1a7840a5..b39c8cc6e 100644 --- a/lib/types/src/traits.rs +++ b/lib/types/src/traits.rs @@ -1,4 +1,4 @@ -use crate::{Build, Deployment, PermissionLevel, PermissionsMap, Server}; +use crate::{Build, Deployment, PermissionLevel, PermissionsMap, Procedure, Server}; pub trait Permissioned { fn permissions_map(&self) -> &PermissionsMap; @@ -25,3 +25,9 @@ impl Permissioned for Server { &self.permissions } } + +impl Permissioned for Procedure { + fn permissions_map(&self) -> &PermissionsMap { + &self.permissions + } +}