diff --git a/bin/core/src/helpers.rs b/bin/core/src/helpers.rs index 0efcd6695..a9031c830 100644 --- a/bin/core/src/helpers.rs +++ b/bin/core/src/helpers.rs @@ -9,6 +9,7 @@ use monitor_types::{ deployment::{Deployment, DockerContainerState}, repo::Repo, server::{Server, ServerStatus}, + tag::CustomTag, update::{ResourceTarget, Update}, user::User, Operation, PermissionLevel, @@ -53,6 +54,8 @@ pub fn make_update( } impl State { + // USER + pub async fn get_user(&self, user_id: &str) -> anyhow::Result { self.db .users @@ -61,11 +64,14 @@ impl State { .context(format!("no user exists with id {user_id}")) } + // SERVER + pub async fn get_server(&self, server_id: &str) -> anyhow::Result { self.db .servers .find_one_by_id(server_id) - .await? + .await + .context("failed to get server from db")? .context(format!("did not find any server with id {server_id}")) } @@ -88,37 +94,13 @@ impl State { Ok((server, status)) } - // pub async fn get_server_status( - // &self, - // server_id: &str, - // ) -> anyhow::Result { - // let server = self.get_server(server_id).await?; - // if !server.config.enabled { - // return Ok(ServerStatus::Disabled); - // } - // let status = match self - // .periphery_client(&server) - // .request(requests::GetHealth {}) - // .await - // { - // Ok(_) => ServerStatus::Ok, - // Err(_) => ServerStatus::NotOk, - // }; - // Ok(status) - // } - pub async fn get_server_check_permissions( &self, server_id: &str, user: &RequestUser, permission_level: PermissionLevel, ) -> anyhow::Result { - let server = self - .db - .servers - .find_one_by_id(server_id) - .await? - .context(format!("did not find any server with id {server_id}"))?; + let server = self.get_server(server_id).await?; let permissions = server.get_user_permissions(&user.id); if user.is_admin || permissions >= permission_level { Ok(server) @@ -138,11 +120,14 @@ impl State { Ok(server.get_user_permissions(user_id)) } + // DEPLOYMENT + pub async fn get_deployment(&self, deployment_id: &str) -> anyhow::Result { self.db .deployments .find_one_by_id(deployment_id) - .await? + .await + .context("failed to get deployment from db")? .context(format!( "did not find any deployment with id {deployment_id}" )) @@ -176,29 +161,13 @@ impl State { Ok(state) } - // pub async fn get_deployment_with_state( - // &self, - // deployment_id: &str, - // ) -> anyhow::Result<(Deployment, DockerContainerState)> { - // let deployment = self.get_deployment(deployment_id).await?; - // let state = self.get_deployment_state(&deployment).await?; - // Ok((deployment, state)) - // } - pub async fn get_deployment_check_permissions( &self, deployment_id: &str, user: &RequestUser, permission_level: PermissionLevel, ) -> anyhow::Result { - let deployment = self - .db - .deployments - .find_one_by_id(deployment_id) - .await? - .context(format!( - "did not find any deployment with id {deployment_id}" - ))?; + let deployment = self.get_deployment(deployment_id).await?; let permissions = deployment.get_user_permissions(&user.id); if user.is_admin || permissions >= permission_level { Ok(deployment) @@ -218,11 +187,14 @@ impl State { Ok(deployment.get_user_permissions(user_id)) } + // BUILD + pub async fn get_build(&self, build_id: &str) -> anyhow::Result { self.db .builds .find_one_by_id(build_id) - .await? + .await + .context("failed to get build from db")? .context(format!("did not find any build with id {build_id}")) } @@ -232,12 +204,7 @@ impl State { user: &RequestUser, permission_level: PermissionLevel, ) -> anyhow::Result { - let build = self - .db - .builds - .find_one_by_id(build_id) - .await? - .context(format!("did not find any build with id {build_id}"))?; + let build = self.get_build(build_id).await?; let permissions = build.get_user_permissions(&user.id); if user.is_admin || permissions >= permission_level { Ok(build) @@ -257,11 +224,14 @@ impl State { Ok(build.get_user_permissions(user_id)) } + // BUILDER + pub async fn get_builder(&self, builder_id: &str) -> anyhow::Result { self.db .builders .find_one_by_id(builder_id) - .await? + .await + .context("failed to get builder from db")? .context(format!("did not find any builder with id {builder_id}")) } @@ -271,12 +241,7 @@ impl State { user: &RequestUser, permission_level: PermissionLevel, ) -> anyhow::Result { - let builder = self - .db - .builders - .find_one_by_id(builder_id) - .await? - .context(format!("did not find any builder with id {builder_id}"))?; + let builder = self.get_builder(builder_id).await?; let permissions = builder.get_user_permissions(&user.id); if user.is_admin || permissions >= permission_level { Ok(builder) @@ -296,11 +261,14 @@ impl State { Ok(builder.get_user_permissions(user_id)) } + // REPO + pub async fn get_repo(&self, repo_id: &str) -> anyhow::Result { self.db .repos .find_one_by_id(repo_id) - .await? + .await + .context("failed to get repo from db")? .context(format!("did not find any repo with id {repo_id}")) } @@ -310,12 +278,7 @@ impl State { user: &RequestUser, permission_level: PermissionLevel, ) -> anyhow::Result { - let repo = self - .db - .repos - .find_one_by_id(repo_id) - .await? - .context(format!("did not find any repo with id {repo_id}"))?; + let repo = self.get_repo(repo_id).await?; let permissions = repo.get_user_permissions(&user.id); if user.is_admin || permissions >= permission_level { Ok(repo) @@ -335,11 +298,14 @@ impl State { Ok(repo.get_user_permissions(user_id)) } + // ALERTER + pub async fn get_alerter(&self, alerter_id: &str) -> anyhow::Result { self.db .alerters .find_one_by_id(alerter_id) - .await? + .await + .context("failed to get alerter from mongo")? .context(format!("did not find any alerter with id {alerter_id}")) } @@ -349,12 +315,7 @@ impl State { user: &RequestUser, permission_level: PermissionLevel, ) -> anyhow::Result { - let alerter = self - .db - .alerters - .find_one_by_id(alerter_id) - .await? - .context(format!("did not find any alerter with id {alerter_id}"))?; + let alerter = self.get_alerter(alerter_id).await?; let permissions = alerter.get_user_permissions(&user.id); if user.is_admin || permissions >= permission_level { Ok(alerter) @@ -374,6 +335,31 @@ impl State { Ok(alerter.get_user_permissions(user_id)) } + // TAG + + pub async fn get_tag(&self, tag_id: &str) -> anyhow::Result { + self.db + .tags + .find_one_by_id(tag_id) + .await + .context("failed to get tag from db")? + .context(format!("did not find any tag with id {tag_id}")) + } + + pub async fn get_tag_check_owner( + &self, + tag_id: &str, + user: &RequestUser, + ) -> anyhow::Result { + let tag = self.get_tag(tag_id).await?; + if !user.is_admin && tag.owner != user.id { + return Err(anyhow!("user must be tag owner or admin")); + } + Ok(tag) + } + + // UPDATE + pub async fn send_update(&self, update: Update) -> anyhow::Result<()> { self.update.sender.lock().await.send(update)?; Ok(()) @@ -404,6 +390,8 @@ impl State { Ok(()) } + // + pub fn periphery_client(&self, server: &Server) -> PeripheryClient { PeripheryClient::new(&server.config.address, &self.config.passkey) } diff --git a/bin/core/src/requests/write/tag.rs b/bin/core/src/requests/write/tag.rs index 19bf2d5b2..d5482f2a0 100644 --- a/bin/core/src/requests/write/tag.rs +++ b/bin/core/src/requests/write/tag.rs @@ -1,8 +1,10 @@ +use anyhow::Context; use async_trait::async_trait; use monitor_types::{ entities::tag::CustomTag, requests::write::{CreateTag, DeleteTag, UpdateTag}, }; +use mungos::mongodb::bson::{doc, to_bson}; use resolver_api::Resolve; use crate::{auth::RequestUser, state::State}; @@ -18,7 +20,20 @@ impl Resolve for State { }: CreateTag, user: RequestUser, ) -> anyhow::Result { - todo!() + let mut tag = CustomTag { + id: Default::default(), + name, + category, + color, + owner: user.id.clone(), + }; + tag.id = self + .db + .tags + .create_one(&tag) + .await + .context("failed to create tag on db")?; + Ok(tag) } } @@ -29,7 +44,16 @@ impl Resolve for State { UpdateTag { id, config }: UpdateTag, user: RequestUser, ) -> anyhow::Result { - todo!() + self.get_tag_check_owner(&id, &user).await?; + self.db + .tags + .update_one( + &id, + mungos::Update::Custom(doc! { "$set": to_bson(&config)? }), + ) + .await + .context("context")?; + self.get_tag(&id).await } } @@ -40,6 +64,8 @@ impl Resolve for State { DeleteTag { id }: DeleteTag, user: RequestUser, ) -> anyhow::Result { - todo!() + let tag = self.get_tag_check_owner(&id, &user).await?; + self.db.tags.delete_one(&id).await?; + Ok(tag) } } diff --git a/lib/types/src/entities/tag.rs b/lib/types/src/entities/tag.rs index 7f58540b8..80c0e8332 100644 --- a/lib/types/src/entities/tag.rs +++ b/lib/types/src/entities/tag.rs @@ -40,6 +40,11 @@ pub struct CustomTag { #[index] pub name: String, + #[serde(default)] + #[builder(default)] + #[index] + pub owner: String, + #[serde(default)] #[builder(default)] #[index]