diff --git a/bin/core/src/api/execute/build.rs b/bin/core/src/api/execute/build.rs index e8b98ab6c..425528d00 100644 --- a/bin/core/src/api/execute/build.rs +++ b/bin/core/src/api/execute/build.rs @@ -13,10 +13,11 @@ use monitor_client::{ builder::{AwsBuilderConfig, Builder, BuilderConfig}, deployment::DockerContainerState, monitor_timestamp, + permission::PermissionLevel, server::Server, update::{Log, Update}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ diff --git a/bin/core/src/api/execute/deployment.rs b/bin/core/src/api/execute/deployment.rs index 8a113f50d..1b6d6de3f 100644 --- a/bin/core/src/api/execute/deployment.rs +++ b/bin/core/src/api/execute/deployment.rs @@ -7,10 +7,11 @@ use monitor_client::{ build::Build, deployment::{Deployment, DeploymentImage}, get_image_name, monitor_timestamp, + permission::PermissionLevel, server::ServerStatus, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, - Operation, PermissionLevel, Version, + Operation, Version, }, }; use mungos::{find::find_collect, mongodb::bson::doc}; diff --git a/bin/core/src/api/execute/procedure.rs b/bin/core/src/api/execute/procedure.rs index 9c3b2c1a3..c459b926b 100644 --- a/bin/core/src/api/execute/procedure.rs +++ b/bin/core/src/api/execute/procedure.rs @@ -2,8 +2,8 @@ use async_trait::async_trait; use monitor_client::{ api::execute::RunProcedure, entities::{ - procedure::Procedure, update::Update, user::User, Operation, - PermissionLevel, + permission::PermissionLevel, procedure::Procedure, + update::Update, user::User, Operation, }, }; use resolver_api::Resolve; diff --git a/bin/core/src/api/execute/repo.rs b/bin/core/src/api/execute/repo.rs index ad64cdbd0..d955919d6 100644 --- a/bin/core/src/api/execute/repo.rs +++ b/bin/core/src/api/execute/repo.rs @@ -6,11 +6,12 @@ use monitor_client::{ api::execute::*, entities::{ monitor_timestamp, optional_string, + permission::PermissionLevel, repo::Repo, server::Server, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::mongodb::bson::{doc, oid::ObjectId}; diff --git a/bin/core/src/api/execute/server.rs b/bin/core/src/api/execute/server.rs index bb0d79cca..f87ce1d82 100644 --- a/bin/core/src/api/execute/server.rs +++ b/bin/core/src/api/execute/server.rs @@ -4,10 +4,11 @@ use monitor_client::{ api::execute::*, entities::{ monitor_timestamp, + permission::PermissionLevel, server::Server, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use periphery_client::api; diff --git a/bin/core/src/api/read/alerter.rs b/bin/core/src/api/read/alerter.rs index 38e83a0bf..7c7d552a7 100644 --- a/bin/core/src/api/read/alerter.rs +++ b/bin/core/src/api/read/alerter.rs @@ -4,9 +4,9 @@ use monitor_client::{ api::read::*, entities::{ alerter::{Alerter, AlerterListItem}, + permission::PermissionLevel, resource::AddFilters, user::User, - PermissionLevel, }, }; use mungos::mongodb::bson::{doc, Document}; diff --git a/bin/core/src/api/read/build.rs b/bin/core/src/api/read/build.rs index 9ebcf120d..f27cc40c1 100644 --- a/bin/core/src/api/read/build.rs +++ b/bin/core/src/api/read/build.rs @@ -8,10 +8,11 @@ use monitor_client::{ api::read::*, entities::{ build::{Build, BuildActionState, BuildListItem}, + permission::PermissionLevel, resource::AddFilters, update::UpdateStatus, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ diff --git a/bin/core/src/api/read/builder.rs b/bin/core/src/api/read/builder.rs index 31b4dd727..a7f1c721a 100644 --- a/bin/core/src/api/read/builder.rs +++ b/bin/core/src/api/read/builder.rs @@ -4,9 +4,9 @@ use monitor_client::{ api::read::{self, *}, entities::{ builder::{Builder, BuilderConfig, BuilderListItem}, + permission::PermissionLevel, resource::AddFilters, user::User, - PermissionLevel, }, }; use mungos::mongodb::bson::{doc, Document}; diff --git a/bin/core/src/api/read/deployment.rs b/bin/core/src/api/read/deployment.rs index cf7914ca7..2eb606d94 100644 --- a/bin/core/src/api/read/deployment.rs +++ b/bin/core/src/api/read/deployment.rs @@ -10,11 +10,12 @@ use monitor_client::{ DeploymentImage, DeploymentListItem, DockerContainerState, DockerContainerStats, }, + permission::PermissionLevel, resource::AddFilters, server::Server, update::{Log, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ diff --git a/bin/core/src/api/read/procedure.rs b/bin/core/src/api/read/procedure.rs index af8abafda..d7db27a66 100644 --- a/bin/core/src/api/read/procedure.rs +++ b/bin/core/src/api/read/procedure.rs @@ -9,8 +9,8 @@ use monitor_client::{ ListProceduresResponse, }, entities::{ - procedure::Procedure, resource::AddFilters, user::User, - PermissionLevel, + permission::PermissionLevel, procedure::Procedure, + resource::AddFilters, user::User, }, }; use mungos::mongodb::bson::{doc, Document}; diff --git a/bin/core/src/api/read/repo.rs b/bin/core/src/api/read/repo.rs index 29bde1ca1..0a293f8de 100644 --- a/bin/core/src/api/read/repo.rs +++ b/bin/core/src/api/read/repo.rs @@ -3,10 +3,10 @@ use async_trait::async_trait; use monitor_client::{ api::read::*, entities::{ + permission::PermissionLevel, repo::{Repo, RepoActionState, RepoListItem}, resource::AddFilters, user::User, - PermissionLevel, }, }; use mungos::mongodb::bson::{doc, Document}; diff --git a/bin/core/src/api/read/server.rs b/bin/core/src/api/read/server.rs index 45b0dd6a8..26baa1e63 100644 --- a/bin/core/src/api/read/server.rs +++ b/bin/core/src/api/read/server.rs @@ -5,6 +5,7 @@ use monitor_client::{ api::read::*, entities::{ deployment::ContainerSummary, + permission::PermissionLevel, resource::AddFilters, server::{ docker_image::ImageSummary, docker_network::DockerNetwork, @@ -12,7 +13,6 @@ use monitor_client::{ ServerListItem, ServerStatus, }, user::User, - PermissionLevel, }, }; use mungos::{ diff --git a/bin/core/src/api/read/update.rs b/bin/core/src/api/read/update.rs index cbe2f5424..f368ea113 100644 --- a/bin/core/src/api/read/update.rs +++ b/bin/core/src/api/read/update.rs @@ -9,12 +9,12 @@ use monitor_client::{ build::Build, builder::Builder, deployment::Deployment, + permission::PermissionLevel, procedure::Procedure, repo::Repo, server::Server, update::{ResourceTarget, Update, UpdateListItem}, user::User, - PermissionLevel, }, }; use mungos::{ diff --git a/bin/core/src/api/write/alerter.rs b/bin/core/src/api/write/alerter.rs index 09602d187..08206d6b9 100644 --- a/bin/core/src/api/write/alerter.rs +++ b/bin/core/src/api/write/alerter.rs @@ -7,8 +7,9 @@ use monitor_client::{ entities::{ alerter::{Alerter, AlerterInfo}, monitor_timestamp, + permission::PermissionLevel, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ @@ -20,8 +21,8 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, make_update, remove_from_recently_viewed, - resource::StateResource, + add_update, create_permission, make_update, + remove_from_recently_viewed, resource::StateResource, }, state::State, }; @@ -44,9 +45,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), config: config.into(), @@ -64,6 +62,8 @@ impl Resolve for State { .to_string(); let alerter: Alerter = self.get_resource(&alerter_id).await?; + create_permission(&user, &alerter, PermissionLevel::Update).await; + let mut update = make_update(&alerter, Operation::CreateAlerter, &user); @@ -108,9 +108,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description, config, tags: Default::default(), @@ -128,6 +125,8 @@ impl Resolve for State { .to_string(); let alerter: Alerter = self.get_resource(&alerter_id).await?; + create_permission(&user, &alerter, PermissionLevel::Update).await; + let mut update = make_update(&alerter, Operation::CreateAlerter, &user); diff --git a/bin/core/src/api/write/build.rs b/bin/core/src/api/write/build.rs index 8891cc131..7b0392441 100644 --- a/bin/core/src/api/write/build.rs +++ b/bin/core/src/api/write/build.rs @@ -7,10 +7,12 @@ use monitor_client::{ entities::{ build::Build, builder::Builder, - monitor_timestamp, to_monitor_name, + monitor_timestamp, + permission::PermissionLevel, + to_monitor_name, update::{Log, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ @@ -22,7 +24,7 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, empty_or_only_spaces, make_update, + add_update, create_permission, empty_or_only_spaces, make_update, remove_from_recently_viewed, resource::StateResource, update_update, }, @@ -48,9 +50,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), config: config.into(), @@ -68,6 +67,8 @@ impl Resolve for State { .to_string(); let build: Build = self.get_resource(&build_id).await?; + create_permission(&user, &build, PermissionLevel::Update).await; + let mut update = make_update(&build, Operation::CreateBuild, &user); @@ -115,9 +116,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description, tags, config, @@ -135,6 +133,8 @@ impl Resolve for State { .to_string(); let build: Build = self.get_resource(&build_id).await?; + create_permission(&user, &build, PermissionLevel::Update).await; + let mut update = make_update(&build, Operation::CreateBuild, &user); diff --git a/bin/core/src/api/write/builder.rs b/bin/core/src/api/write/builder.rs index 0fa20df2a..76d2df09c 100644 --- a/bin/core/src/api/write/builder.rs +++ b/bin/core/src/api/write/builder.rs @@ -5,9 +5,10 @@ use monitor_client::{ entities::{ builder::Builder, monitor_timestamp, + permission::PermissionLevel, update::{Log, ResourceTarget, Update}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ @@ -19,7 +20,8 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, remove_from_recently_viewed, resource::StateResource, + add_update, create_permission, remove_from_recently_viewed, + resource::StateResource, }, state::State, }; @@ -36,9 +38,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), config: config.into(), @@ -55,6 +54,7 @@ impl Resolve for State { .context("inserted_id is not ObjectId")? .to_string(); let builder: Builder = self.get_resource(&builder_id).await?; + create_permission(&user, &builder, PermissionLevel::Update).await; let update = Update { target: ResourceTarget::Builder(builder_id), operation: Operation::CreateBuilder, @@ -104,9 +104,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description, tags: Default::default(), config, @@ -123,6 +120,7 @@ impl Resolve for State { .context("inserted_id is not ObjectId")? .to_string(); let builder: Builder = self.get_resource(&builder_id).await?; + create_permission(&user, &builder, PermissionLevel::Update).await; let update = Update { target: ResourceTarget::Builder(builder_id), operation: Operation::CreateBuilder, diff --git a/bin/core/src/api/write/deployment.rs b/bin/core/src/api/write/deployment.rs index 02643c541..77bf5551c 100644 --- a/bin/core/src/api/write/deployment.rs +++ b/bin/core/src/api/write/deployment.rs @@ -7,11 +7,12 @@ use monitor_client::{ build::Build, deployment::{Deployment, DeploymentImage, DockerContainerState}, monitor_timestamp, + permission::PermissionLevel, server::Server, to_monitor_name, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ @@ -24,9 +25,10 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, empty_or_only_spaces, get_deployment_state, - make_update, periphery_client, remove_from_recently_viewed, - resource::StateResource, update_update, + add_update, create_permission, empty_or_only_spaces, + get_deployment_state, make_update, periphery_client, + remove_from_recently_viewed, resource::StateResource, + update_update, }, state::{action_states, State}, }; @@ -60,9 +62,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), config: config.into(), @@ -80,25 +79,21 @@ impl Resolve for State { .to_string(); let deployment: Deployment = self.get_resource(&deployment_id).await?; - let update = Update { - target: ResourceTarget::Deployment(deployment_id), - operation: Operation::CreateDeployment, - start_ts, - end_ts: Some(monitor_timestamp()), - operator: user.id.clone(), - success: true, - logs: vec![ - Log::simple( - "create deployment", - format!( - "created deployment\nid: {}\nname: {}", - deployment.id, deployment.name - ), - ), - Log::simple("config", format!("{:#?}", deployment.config)), - ], - ..Default::default() - }; + create_permission(&user, &deployment, PermissionLevel::Update) + .await; + + let mut update = + make_update(&deployment, Operation::CreateDeployment, &user); + update.push_simple_log( + "create deployment", + format!( + "created deployment\nid: {}\nname: {}", + deployment.id, deployment.name + ), + ); + update + .push_simple_log("config", format!("{:#?}", deployment.config)); + update.finalize(); add_update(update).await?; @@ -128,14 +123,14 @@ impl Resolve for State { .await?; if !config.server_id.is_empty() { let _: Server = self.get_resource_check_permissions(&config.server_id, &user, PermissionLevel::Update) - .await - .context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?; + .await + .context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?; } if let DeploymentImage::Build { build_id, .. } = &config.image { if !build_id.is_empty() { let _: Build = self.get_resource_check_permissions(build_id, &user, PermissionLevel::Read) - .await - .context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?; + .await + .context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?; } } let start_ts = monitor_timestamp(); @@ -143,9 +138,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description, tags, config, @@ -163,25 +155,22 @@ impl Resolve for State { .to_string(); let deployment: Deployment = self.get_resource(&deployment_id).await?; - let update = Update { - target: ResourceTarget::Deployment(deployment_id), - operation: Operation::CreateDeployment, - start_ts, - end_ts: Some(monitor_timestamp()), - operator: user.id.clone(), - success: true, - logs: vec![ - Log::simple( - "create deployment", - format!( - "created deployment\nid: {}\nname: {}", - deployment.id, deployment.name - ), - ), - Log::simple("config", format!("{:#?}", deployment.config)), - ], - ..Default::default() - }; + + create_permission(&user, &deployment, PermissionLevel::Update) + .await; + + let mut update = + make_update(&deployment, Operation::CreateDeployment, &user); + update.push_simple_log( + "create deployment", + format!( + "created deployment\nid: {}\nname: {}", + deployment.id, deployment.name + ), + ); + update + .push_simple_log("config", format!("{:#?}", deployment.config)); + update.finalize(); add_update(update).await?; diff --git a/bin/core/src/api/write/permissions.rs b/bin/core/src/api/write/permissions.rs index 3f41d2cc2..81ccc31c2 100644 --- a/bin/core/src/api/write/permissions.rs +++ b/bin/core/src/api/write/permissions.rs @@ -5,11 +5,7 @@ use monitor_client::{ UpdateUserPermissions, UpdateUserPermissionsOnTarget, }, entities::{ - alerter::Alerter, monitor_timestamp, - procedure::Procedure, - repo::Repo, - server::Server, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, Operation, @@ -23,7 +19,7 @@ use resolver_api::Resolve; use crate::{ db::db_client, - helpers::{add_update, get_user, resource::StateResource}, + helpers::{add_update, get_user}, state::State, }; @@ -43,7 +39,6 @@ impl Resolve for State { if !admin.admin { return Err(anyhow!("this method is admin only")); } - let user = find_one_by_id(&db_client().await.users, &user_id) .await .context("failed to query mongo for user")? @@ -81,7 +76,6 @@ impl Resolve for State { "update permissions for {} ({})\nenabled: {enabled:?}\ncreate servers: {create_servers:?}\ncreate builds: {create_builds:?}", user.username, user.id, - ), )], start_ts, @@ -111,7 +105,6 @@ impl Resolve for State { if !admin.admin { return Err(anyhow!("this method is admin only")); } - let user = get_user(&user_id).await?; if user.admin { return Err(anyhow!( @@ -121,143 +114,23 @@ impl Resolve for State { if !user.enabled { return Err(anyhow!("user not enabled")); } - let log_text = match &target { - ResourceTarget::System(_) => { - return Err(anyhow!("target can not be system")) - } - ResourceTarget::Build(id) => { - let build = find_one_by_id(&db_client().await.builds, id) - .await - .context("failed at find build query")? - .ok_or(anyhow!("failed to find a build with id {id}"))?; - - update_one_by_id( - &db_client().await.builds, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on build {}", - user.username, permission, build.name - ) - } - ResourceTarget::Builder(id) => { - let builder = find_one_by_id(&db_client().await.builders, id) - .await - .context("failed at find builder query")? - .with_context(|| { - format!("failed to find a builder with id {id}") - })?; - - update_one_by_id( - &db_client().await.builders, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on builder {}", - user.username, permission, builder.name - ) - } - ResourceTarget::Deployment(id) => { - let deployment = - find_one_by_id(&db_client().await.deployments, id) - .await - .context("failed at find deployment query")? - .with_context(|| { - format!("failed to find a deployment with id {id}") - })?; - - update_one_by_id( - &db_client().await.deployments, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on deployment {}", - user.username, permission, deployment.name - ) - } - ResourceTarget::Server(id) => { - // find_one_by_id(&db_client().await.servers, id) - let server: Server = self.get_resource(id).await?; - - update_one_by_id( - &db_client().await.servers, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on server {}", - user.username, permission, server.name - ) - } - ResourceTarget::Repo(id) => { - let repo: Repo = self.get_resource(id).await?; - - update_one_by_id( - &db_client().await.repos, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on repo {}", - user.username, permission, repo.name - ) - } - ResourceTarget::Alerter(id) => { - let alerter: Alerter = self.get_resource(id).await?; - update_one_by_id( - &db_client().await.alerters, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on alerter {}", - user.username, permission, alerter.name - ) - } - ResourceTarget::Procedure(id) => { - let procedure: Procedure = self.get_resource(id).await?; - update_one_by_id( - &db_client().await.procedures, - id, - mungos::update::Update::Set(doc! { - format!("permissions.{}", user_id): permission.to_string() - }), - None, - ) - .await?; - format!( - "user {} given {} permissions on procedure {}", - user.username, permission, procedure.id - ) - } - }; + let (variant, id) = target.extract_variant_id(); + db_client().await.permissions.update_one( + doc! { "user_id": &user.id, "target.type": variant.as_ref(), "target.id": id }, + doc! { + "$set": { + "user_id": &user.id, + "target.type": variant.as_ref(), + "target.id": id, + "level": permission.as_ref(), + } + }, + None + ).await?; + let log_text = format!( + "user {} given {} permissions on {target:?}", + user.username, permission, + ); let mut update = Update { operation: Operation::UpdateUserPermissionsOnTarget, start_ts, diff --git a/bin/core/src/api/write/procedure.rs b/bin/core/src/api/write/procedure.rs index 4bc4408c2..02e321966 100644 --- a/bin/core/src/api/write/procedure.rs +++ b/bin/core/src/api/write/procedure.rs @@ -3,8 +3,9 @@ use async_trait::async_trait; use monitor_client::{ api::write::*, entities::{ - monitor_timestamp, procedure::Procedure, to_monitor_name, - update::Log, user::User, Operation, PermissionLevel, + monitor_timestamp, permission::PermissionLevel, + procedure::Procedure, to_monitor_name, update::Log, user::User, + Operation, }, }; use mungos::{ @@ -16,8 +17,9 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, make_update, remove_from_recently_viewed, - resource::StateResource, update_update, + add_update, create_permission, make_update, + remove_from_recently_viewed, resource::StateResource, + update_update, }, state::{action_states, State}, }; @@ -35,9 +37,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), info: Default::default(), @@ -56,6 +55,9 @@ impl Resolve for State { let procedure: Procedure = self.get_resource(&procedure_id).await?; + create_permission(&user, &procedure, PermissionLevel::Update) + .await; + let mut update = make_update(&procedure, Operation::CreateProcedure, &user); @@ -103,9 +105,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description, tags, config, @@ -124,6 +123,9 @@ impl Resolve for State { let procedure: Procedure = self.get_resource(&procedure_id).await?; + create_permission(&user, &procedure, PermissionLevel::Update) + .await; + let mut update = make_update(&procedure, Operation::CreateProcedure, &user); diff --git a/bin/core/src/api/write/repo.rs b/bin/core/src/api/write/repo.rs index 9ed45e040..dbf054c66 100644 --- a/bin/core/src/api/write/repo.rs +++ b/bin/core/src/api/write/repo.rs @@ -4,12 +4,13 @@ use monitor_client::{ api::{execute, write::*}, entities::{ monitor_timestamp, + permission::PermissionLevel, repo::Repo, server::Server, to_monitor_name, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ @@ -22,7 +23,7 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, make_update, periphery_client, + add_update, create_permission, make_update, periphery_client, remove_from_recently_viewed, resource::StateResource, update_update, }, @@ -40,12 +41,12 @@ impl Resolve for State { if let Some(server_id) = &config.server_id { if !server_id.is_empty() { let _: Server = self.get_resource_check_permissions( - server_id, - &user, - PermissionLevel::Update, - ) - .await - .context("cannot create repo on this server. user must have update permissions on the server.")?; + server_id, + &user, + PermissionLevel::Update, + ) + .await + .context("cannot create repo on this server. user must have update permissions on the server.")?; } } let start_ts = monitor_timestamp(); @@ -53,9 +54,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), config: config.into(), @@ -74,6 +72,8 @@ impl Resolve for State { let repo: Repo = self.get_resource(&repo_id).await?; + create_permission(&user, &repo, PermissionLevel::Update).await; + let update = Update { target: ResourceTarget::Repo(repo_id), operation: Operation::CreateRepo, @@ -134,21 +134,18 @@ impl Resolve for State { .await?; if !config.server_id.is_empty() { let _: Server = self.get_resource_check_permissions( - &config.server_id, - &user, - PermissionLevel::Update, - ) - .await - .context("cannot create repo on this server. user must have update permissions on the server.")?; + &config.server_id, + &user, + PermissionLevel::Update, + ) + .await + .context("cannot create repo on this server. user must have update permissions on the server.")?; } let start_ts = monitor_timestamp(); let repo = Repo { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description, tags, config, @@ -165,6 +162,7 @@ impl Resolve for State { .context("inserted_id is not ObjectId")? .to_string(); let repo: Repo = self.get_resource(&repo_id).await?; + create_permission(&user, &repo, PermissionLevel::Update).await; let update = Update { target: ResourceTarget::Repo(repo_id), operation: Operation::CreateRepo, diff --git a/bin/core/src/api/write/server.rs b/bin/core/src/api/write/server.rs index 05dbe6058..d2ebef590 100644 --- a/bin/core/src/api/write/server.rs +++ b/bin/core/src/api/write/server.rs @@ -4,10 +4,11 @@ use monitor_client::{ api::write::*, entities::{ monitor_timestamp, + permission::PermissionLevel, server::Server, update::{Log, ResourceTarget, Update, UpdateStatus}, user::User, - Operation, PermissionLevel, + Operation, }, }; use mungos::{ @@ -20,8 +21,8 @@ use resolver_api::Resolve; use crate::{ db::db_client, helpers::{ - add_update, cache::server_status_cache, make_update, - periphery_client, remove_from_recently_viewed, + add_update, cache::server_status_cache, create_permission, + make_update, periphery_client, remove_from_recently_viewed, resource::StateResource, update_update, }, monitor::update_cache_for_server, @@ -45,9 +46,6 @@ impl Resolve for State { id: Default::default(), name, updated_at: start_ts, - permissions: [(user.id.clone(), PermissionLevel::Update)] - .into_iter() - .collect(), description: Default::default(), tags: Default::default(), config: config.into(), @@ -64,6 +62,7 @@ impl Resolve for State { .context("inserted_id is not ObjectId")? .to_string(); let server: Server = self.get_resource(&server_id).await?; + create_permission(&user, &server, PermissionLevel::Update).await; let update = Update { target: ResourceTarget::Server(server_id), operation: Operation::CreateServer, diff --git a/bin/core/src/api/write/tag.rs b/bin/core/src/api/write/tag.rs index 6b8ed3ec9..c6c4ad96f 100644 --- a/bin/core/src/api/write/tag.rs +++ b/bin/core/src/api/write/tag.rs @@ -7,9 +7,9 @@ use monitor_client::{ }, entities::{ alerter::Alerter, build::Build, builder::Builder, - deployment::Deployment, procedure::Procedure, repo::Repo, - server::Server, tag::CustomTag, update::ResourceTarget, - user::User, PermissionLevel, + deployment::Deployment, permission::PermissionLevel, + procedure::Procedure, repo::Repo, server::Server, tag::CustomTag, + update::ResourceTarget, user::User, }, }; use mungos::{ diff --git a/bin/core/src/db.rs b/bin/core/src/db.rs index 4f8426cc2..0bd9fde3d 100644 --- a/bin/core/src/db.rs +++ b/bin/core/src/db.rs @@ -6,6 +6,7 @@ use monitor_client::entities::{ build::Build, builder::Builder, deployment::Deployment, + permission::Permission, procedure::Procedure, repo::Repo, server::{stats::SystemStatsRecord, Server}, @@ -34,6 +35,7 @@ pub async fn db_client() -> &'static DbClient { pub struct DbClient { pub users: Collection, + pub permissions: Collection, pub api_keys: Collection, pub tags: Collection, pub updates: Collection, @@ -88,6 +90,7 @@ impl DbClient { let client = DbClient { users: User::collection(&db, true).await?, + permissions: Permission::collection(&db, true).await?, api_keys: ApiKey::collection(&db, true).await?, tags: CustomTag::collection(&db, true).await?, updates: Update::collection(&db, true).await?, diff --git a/bin/core/src/helpers/mod.rs b/bin/core/src/helpers/mod.rs index 718a6251c..20e6fb348 100644 --- a/bin/core/src/helpers/mod.rs +++ b/bin/core/src/helpers/mod.rs @@ -4,6 +4,7 @@ use anyhow::{anyhow, Context}; use monitor_client::entities::{ deployment::{Deployment, DockerContainerState}, monitor_timestamp, + permission::{Permission, PermissionLevel}, server::{Server, ServerStatus}, tag::CustomTag, update::{ResourceTarget, Update, UpdateListItem}, @@ -223,3 +224,31 @@ pub fn periphery_client( Ok(client) } + +pub async fn create_permission( + user: &User, + target: impl Into, + level: PermissionLevel, +) { + // No need to actually create permissions for admins + if user.admin { + return; + } + let target: ResourceTarget = target.into(); + if let Err(e) = db_client() + .await + .permissions + .insert_one( + Permission { + id: Default::default(), + user_id: user.id.clone(), + target: target.clone(), + level, + }, + None, + ) + .await + { + warn!("failed to create permission for {target:?} | {e:#}"); + }; +} diff --git a/bin/core/src/helpers/resource.rs b/bin/core/src/helpers/resource.rs index 05011fcbc..dff46f6c8 100644 --- a/bin/core/src/helpers/resource.rs +++ b/bin/core/src/helpers/resource.rs @@ -3,32 +3,26 @@ use std::str::FromStr; use anyhow::{anyhow, Context}; use async_trait::async_trait; use futures::future::join_all; -use monitor_client::{ - entities::{ - alerter::{ - Alerter, AlerterConfig, AlerterListItem, AlerterListItemInfo, - }, - build::{Build, BuildListItem, BuildListItemInfo}, - builder::{ - Builder, BuilderConfig, BuilderListItem, BuilderListItemInfo, - }, - deployment::{ - Deployment, DeploymentImage, DeploymentListItem, - DeploymentListItemInfo, - }, - procedure::{ - Procedure, ProcedureListItem, ProcedureListItemInfo, - }, - repo::{Repo, RepoInfo, RepoListItem}, - server::{Server, ServerListItem, ServerListItemInfo}, - update::ResourceTargetVariant, - user::User, - PermissionLevel, +use monitor_client::entities::{ + alerter::{ + Alerter, AlerterConfig, AlerterListItem, AlerterListItemInfo, }, - permissioned::Permissioned, + build::{Build, BuildListItem, BuildListItemInfo}, + builder::{ + Builder, BuilderConfig, BuilderListItem, BuilderListItemInfo, + }, + deployment::{ + Deployment, DeploymentImage, DeploymentListItem, + DeploymentListItemInfo, + }, + permission::PermissionLevel, + procedure::{Procedure, ProcedureListItem, ProcedureListItemInfo}, + repo::{Repo, RepoInfo, RepoListItem}, + server::{Server, ServerListItem, ServerListItemInfo}, + update::ResourceTargetVariant, + user::User, }; use mungos::{ - aggregate::aggregate_collect, by_id::{find_one_by_id, update_one_by_id}, find::find_collect, mongodb::{ @@ -44,12 +38,13 @@ use super::cache::{deployment_status_cache, server_status_cache}; #[async_trait] pub trait StateResource< - T: Send + Sync + Unpin + Serialize + DeserializeOwned + Permissioned, + T: Send + Sync + Unpin + Serialize + DeserializeOwned, > { type ListItem: Serialize + Send; fn name() -> &'static str; + fn resource_target_variant(&self) -> ResourceTargetVariant; async fn coll(&self) -> &Collection; async fn to_list_item( &self, @@ -72,7 +67,8 @@ pub trait StateResource< permission_level: PermissionLevel, ) -> anyhow::Result { let resource = self.get_resource(id).await?; - let permissions = resource.get_user_permissions(&user.id); + let permissions = + self.get_user_permission_on_resource(&user.id, id).await?; if user.admin || permissions >= permission_level { Ok(resource) } else { @@ -88,40 +84,29 @@ pub trait StateResource< user_id: &str, resource_id: &str, ) -> anyhow::Result { - let resource = self.get_resource(resource_id).await?; - Ok(resource.get_user_permissions(user_id)) + get_user_permission_on_resource( + user_id, + self.resource_target_variant(), + resource_id, + ) + .await } async fn get_resource_ids_for_non_admin( &self, user_id: &str, ) -> anyhow::Result> { - use mungos::aggregate::AggStage::*; - aggregate_collect( - self.coll().await, - [ - Match(doc! { - format!("permissions.{}", user_id): { "$in": ["update", "execute", "read"] } - }), - Project(doc! { "_id": 1 }), - ], None) - .await - .with_context(|| format!("failed to get {} ids for non admin | aggregation", Self::name()))? - .into_iter() - .map(|d| { - let id = d - .get("_id") - .context("no _id field")? - .as_object_id() - .context("_id not ObjectId")? - .to_string(); - anyhow::Ok(id) - }) - .collect::>>() - .with_context(|| format!( - "failed to get {} ids for non admin | extract id from document", - Self::name() - )) + let permissions = find_collect( + &db_client().await.permissions, + doc! { "user_id": user_id, "target.type": self.resource_target_variant().as_ref() }, + None, + ) + .await + .context("failed to query permissions on db")? + .into_iter() + .map(|p| p.target.extract_variant_id().1.to_string()) + .collect(); + Ok(permissions) } async fn list_resources_for_user( @@ -130,10 +115,13 @@ pub trait StateResource< user: &User, ) -> anyhow::Result> { if !user.admin { - filters.insert( - format!("permissions.{}", user.id), - doc! { "$in": ["read", "execute", "update"] }, - ); + let ids = self + .get_resource_ids_for_non_admin(&user.id) + .await? + .into_iter() + .flat_map(|id| ObjectId::from_str(&id)) + .collect::>(); + filters.insert("_id", doc! { "$in": ids }); } let list = find_collect(self.coll().await, filters, None) .await @@ -221,6 +209,10 @@ impl StateResource for State { "server" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Server + } + async fn coll(&self) -> &Collection { &db_client().await.servers } @@ -261,6 +253,10 @@ impl StateResource for State { "deployment" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Deployment + } + async fn coll(&self) -> &Collection { &db_client().await.deployments } @@ -314,6 +310,10 @@ impl StateResource for State { "build" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Build + } + async fn coll(&self) -> &Collection { &db_client().await.builds } @@ -346,6 +346,10 @@ impl StateResource for State { "repo" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Repo + } + async fn coll(&self) -> &Collection { &db_client().await.repos } @@ -377,6 +381,10 @@ impl StateResource for State { "builder" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Builder + } + async fn coll(&self) -> &Collection { &db_client().await.builders } @@ -418,6 +426,10 @@ impl StateResource for State { "alerter" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Alerter + } + async fn coll(&self) -> &Collection { &db_client().await.alerters } @@ -454,6 +466,10 @@ impl StateResource for State { "procedure" } + fn resource_target_variant(&self) -> ResourceTargetVariant { + ResourceTargetVariant::Procedure + } + async fn coll(&self) -> &Collection { &db_client().await.procedures } @@ -476,3 +492,26 @@ impl StateResource for State { }) } } + +pub async fn get_user_permission_on_resource( + user_id: &str, + resource_variant: ResourceTargetVariant, + resource_id: &str, +) -> anyhow::Result { + let permission = db_client() + .await + .permissions + .find_one( + doc! { + "user_id": user_id, + "target.type": resource_variant.as_ref(), + "target.id": resource_id + }, + None, + ) + .await + .context("failed to query permissions table")? + .map(|permission| permission.level) + .unwrap_or_default(); + Ok(permission) +} diff --git a/bin/core/src/ws.rs b/bin/core/src/ws.rs index eb3d802eb..0aaffd6cf 100644 --- a/bin/core/src/ws.rs +++ b/bin/core/src/ws.rs @@ -11,18 +11,8 @@ use axum::{ use futures::{SinkExt, StreamExt}; use monitor_client::{ entities::{ - alerter::Alerter, - build::Build, - builder::Builder, - deployment::Deployment, - procedure::Procedure, - repo::Repo, - server::Server, - update::{ResourceTarget, ResourceTargetVariant}, - user::User, - PermissionLevel, + permission::PermissionLevel, update::ResourceTarget, user::User, }, - permissioned::Permissioned, ws::WsLoginMessage, }; use mungos::by_id::find_one_by_id; @@ -33,8 +23,10 @@ use tokio_util::sync::CancellationToken; use crate::{ auth::{auth_api_key_check_enabled, auth_jwt_check_enabled}, db::db_client, - helpers::{channel::update_channel, resource::StateResource}, - state::State, + helpers::{ + channel::update_channel, + resource::get_user_permission_on_resource, + }, }; pub fn router() -> Router { @@ -207,67 +199,12 @@ async fn user_can_see_update( if user.admin { return Ok(()); } - let (permissions, target) = match update_target { - ResourceTarget::Server(server_id) => { - let resource: Server = State.get_resource(server_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Server, - ) - } - ResourceTarget::Deployment(deployment_id) => { - let resource: Deployment = - State.get_resource(deployment_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Deployment, - ) - } - ResourceTarget::Build(build_id) => { - let resource: Build = State.get_resource(build_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Build, - ) - } - ResourceTarget::Builder(builder_id) => { - let resource: Builder = State.get_resource(builder_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Builder, - ) - } - ResourceTarget::Repo(repo_id) => { - let resource: Repo = State.get_resource(repo_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Repo, - ) - } - ResourceTarget::Alerter(alerter_id) => { - let resource: Alerter = State.get_resource(alerter_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Alerter, - ) - } - ResourceTarget::Procedure(prodecure_id) => { - let resource: Procedure = - State.get_resource(prodecure_id).await?; - ( - resource.get_user_permissions(&user.id), - ResourceTargetVariant::Procedure, - ) - } - ResourceTarget::System(_) => { - return Err(anyhow!( - "user not admin, can't recieve system updates" - )) - } - }; - if permissions != PermissionLevel::None { + let (variant, id) = update_target.extract_variant_id(); + let permissions = + get_user_permission_on_resource(&user.id, variant, id).await?; + if permissions > PermissionLevel::None { Ok(()) } else { - Err(anyhow!("user does not have permissions on {target}")) + Err(anyhow!("user does not have permissions on {variant} {id}")) } } diff --git a/bin/migrator/src/legacy/v0/build.rs b/bin/migrator/src/legacy/v0/build.rs index 09653c980..433ac274a 100644 --- a/bin/migrator/src/legacy/v0/build.rs +++ b/bin/migrator/src/legacy/v0/build.rs @@ -193,11 +193,11 @@ impl TryFrom for monitor_client::entities::build::Build { id: value.id, name: value.name, description: value.description, - permissions: value - .permissions - .into_iter() - .map(|(id, p)| (id, p.into())) - .collect(), + // permissions: value + // .permissions + // .into_iter() + // .map(|(id, p)| (id, p.into())) + // .collect(), updated_at: unix_from_monitor_ts(&value.updated_at)?, tags: Vec::new(), info: BuildInfo { diff --git a/bin/migrator/src/legacy/v0/deployment.rs b/bin/migrator/src/legacy/v0/deployment.rs index 405dbd8cc..43a9ef630 100644 --- a/bin/migrator/src/legacy/v0/deployment.rs +++ b/bin/migrator/src/legacy/v0/deployment.rs @@ -327,11 +327,11 @@ impl TryFrom id: value.id, name: value.name, description: value.description, - permissions: value - .permissions - .into_iter() - .map(|(id, p)| (id, p.into())) - .collect(), + // permissions: value + // .permissions + // .into_iter() + // .map(|(id, p)| (id, p.into())) + // .collect(), updated_at: unix_from_monitor_ts(&value.updated_at)?, tags: Vec::new(), info: (), diff --git a/bin/migrator/src/legacy/v0/mod.rs b/bin/migrator/src/legacy/v0/mod.rs index b6e1a37d2..28ea5b661 100644 --- a/bin/migrator/src/legacy/v0/mod.rs +++ b/bin/migrator/src/legacy/v0/mod.rs @@ -238,10 +238,10 @@ impl Default for &PermissionLevel { } impl From - for monitor_client::entities::PermissionLevel + for monitor_client::entities::permission::PermissionLevel { fn from(value: PermissionLevel) -> Self { - use monitor_client::entities::PermissionLevel::*; + use monitor_client::entities::permission::PermissionLevel::*; match value { PermissionLevel::None => None, PermissionLevel::Read => Read, diff --git a/bin/migrator/src/legacy/v0/server.rs b/bin/migrator/src/legacy/v0/server.rs index 79811447e..121e18b6d 100644 --- a/bin/migrator/src/legacy/v0/server.rs +++ b/bin/migrator/src/legacy/v0/server.rs @@ -293,11 +293,11 @@ impl TryFrom for monitor_client::entities::server::Server { id: value.id, name: value.name, description: value.description, - permissions: value - .permissions - .into_iter() - .map(|(id, p)| (id, p.into())) - .collect(), + // permissions: value + // .permissions + // .into_iter() + // .map(|(id, p)| (id, p.into())) + // .collect(), updated_at: unix_from_monitor_ts(&value.updated_at)?, tags: Vec::new(), info: (), diff --git a/client/core/rs/src/api/write/permissions.rs b/client/core/rs/src/api/write/permissions.rs index dd6b673c4..8e4e977f9 100644 --- a/client/core/rs/src/api/write/permissions.rs +++ b/client/core/rs/src/api/write/permissions.rs @@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize}; use typeshare::typeshare; use crate::entities::{ + permission::PermissionLevel, update::{ResourceTarget, Update}, - PermissionLevel, }; use super::MonitorWriteRequest; diff --git a/client/core/rs/src/entities/mod.rs b/client/core/rs/src/entities/mod.rs index 4d5f0ebc7..e7d157c0e 100644 --- a/client/core/rs/src/entities/mod.rs +++ b/client/core/rs/src/entities/mod.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use anyhow::{anyhow, Context}; use async_timing_util::unix_timestamp_ms; use serde::{Deserialize, Serialize}; @@ -12,6 +10,7 @@ pub mod api_key; pub mod build; pub mod builder; pub mod deployment; +pub mod permission; pub mod procedure; pub mod repo; pub mod resource; @@ -28,8 +27,6 @@ pub type U64 = u64; pub type MongoDocument = mungos::mongodb::bson::Document; #[typeshare(serialized_as = "MongoIdObj")] pub type MongoId = String; -#[typeshare] -pub type PermissionsMap = HashMap; pub fn all_logs_success(logs: &[update::Log]) -> bool { for log in logs { @@ -296,38 +293,6 @@ pub enum Timelength { ThirtyDays, } -#[typeshare] -#[derive( - Serialize, - Deserialize, - Debug, - Display, - EnumString, - Hash, - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Default, -)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum PermissionLevel { - #[default] - None, - Read, - Execute, - Update, -} - -impl Default for &PermissionLevel { - fn default() -> Self { - &PermissionLevel::None - } -} - #[typeshare] #[derive( Serialize, diff --git a/client/core/rs/src/entities/permission.rs b/client/core/rs/src/entities/permission.rs new file mode 100644 index 000000000..8f606691c --- /dev/null +++ b/client/core/rs/src/entities/permission.rs @@ -0,0 +1,61 @@ +use mongo_indexed::derive::MongoIndexed; +use mungos::mongodb::bson::{ + doc, serde_helpers::hex_string_as_object_id, Document, +}; +use serde::{Deserialize, Serialize}; +use strum::{AsRefStr, Display, EnumString}; +use typeshare::typeshare; + +use super::{update::ResourceTarget, MongoId}; + +#[typeshare] +#[derive(Debug, Clone, Serialize, Deserialize, MongoIndexed)] +// To query for all permissions on a target +#[doc_index(doc! { "target.type": 1, "target.id": 1 })] +// Only one permission allowed per user / target +#[unique_doc_index(doc! { "user_id": 1, "target.type": 1, "target.id": 1 })] +pub struct Permission { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + pub id: MongoId, + #[index] + pub user_id: String, + pub target: ResourceTarget, + #[serde(default)] + pub level: PermissionLevel, +} + +#[typeshare] +#[derive( + Serialize, + Deserialize, + Debug, + Display, + EnumString, + AsRefStr, + Hash, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, +)] +pub enum PermissionLevel { + #[default] + None, + Read, + Execute, + Update, +} + +impl Default for &PermissionLevel { + fn default() -> Self { + &PermissionLevel::None + } +} diff --git a/client/core/rs/src/entities/resource.rs b/client/core/rs/src/entities/resource.rs index 1ce890dcf..a94e47f77 100644 --- a/client/core/rs/src/entities/resource.rs +++ b/client/core/rs/src/entities/resource.rs @@ -8,7 +8,7 @@ use typeshare::typeshare; use crate::entities::{MongoId, I64}; -use super::{update::ResourceTargetVariant, PermissionsMap}; +use super::update::ResourceTargetVariant; #[typeshare] #[derive(Serialize, Deserialize, Debug, Clone, Builder)] @@ -28,10 +28,6 @@ pub struct Resource { #[builder(default)] pub description: String, - #[serde(default)] - #[builder(setter(skip))] - pub permissions: PermissionsMap, - #[serde(default)] #[builder(setter(skip))] pub updated_at: I64, diff --git a/client/core/rs/src/entities/update.rs b/client/core/rs/src/entities/update.rs index b574feef9..deb3f4628 100644 --- a/client/core/rs/src/entities/update.rs +++ b/client/core/rs/src/entities/update.rs @@ -5,7 +5,7 @@ use mungos::mongodb::bson::{ doc, serde_helpers::hex_string_as_object_id, Document, }; use serde::{Deserialize, Serialize}; -use strum::{Display, EnumString}; +use strum::{AsRefStr, Display, EnumString}; use typeshare::typeshare; use crate::entities::{ @@ -151,6 +151,7 @@ impl Log { Copy, Display, EnumString, + AsRefStr, PartialEq, Eq )] @@ -166,6 +167,25 @@ pub enum ResourceTarget { Procedure(String), } +impl ResourceTarget { + pub fn extract_variant_id( + &self, + ) -> (ResourceTargetVariant, &String) { + let variant: ResourceTargetVariant = self.into(); + let id = match &self { + ResourceTarget::System(id) => id, + ResourceTarget::Build(id) => id, + ResourceTarget::Builder(id) => id, + ResourceTarget::Deployment(id) => id, + ResourceTarget::Server(id) => id, + ResourceTarget::Repo(id) => id, + ResourceTarget::Alerter(id) => id, + ResourceTarget::Procedure(id) => id, + }; + (variant, id) + } +} + impl Default for ResourceTarget { fn default() -> Self { Self::System("system".to_string()) diff --git a/client/core/rs/src/lib.rs b/client/core/rs/src/lib.rs index be940cd04..04e687112 100644 --- a/client/core/rs/src/lib.rs +++ b/client/core/rs/src/lib.rs @@ -5,7 +5,6 @@ use serde::Deserialize; pub mod api; pub mod busy; pub mod entities; -pub mod permissioned; pub mod ws; mod request; diff --git a/client/core/rs/src/permissioned.rs b/client/core/rs/src/permissioned.rs deleted file mode 100644 index a24fcf52e..000000000 --- a/client/core/rs/src/permissioned.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::entities::{ - resource::Resource, PermissionLevel, PermissionsMap, -}; - -pub trait Permissioned { - fn permissions_map(&self) -> &PermissionsMap; - - fn get_user_permissions(&self, user_id: &str) -> PermissionLevel { - *self.permissions_map().get(user_id).unwrap_or_default() - } -} - -impl Permissioned for Resource { - fn permissions_map(&self) -> &PermissionsMap { - &self.permissions - } -}