From 21ffea0f9f05ee4116878206e59b1e67c37bd032 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 20 Oct 2023 18:16:55 +0100 Subject: [PATCH] fix(core/database): store member during permission query --- .../core/database/src/models/servers/model.rs | 78 +++++++++++++++++-- crates/core/database/src/util/idempotency.rs | 2 +- crates/core/database/src/util/permissions.rs | 12 ++- 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/crates/core/database/src/models/servers/model.rs b/crates/core/database/src/models/servers/model.rs index 45f63bd2..3af796eb 100644 --- a/crates/core/database/src/models/servers/model.rs +++ b/crates/core/database/src/models/servers/model.rs @@ -455,9 +455,12 @@ impl SystemMessageChannels { mod tests { use std::collections::HashMap; - use revolt_permissions::OverrideField; + use revolt_permissions::{calculate_server_permissions, ChannelPermission, OverrideField}; - use crate::{Role, Server, User}; + use crate::{ + util::permissions::DatabasePermissionQuery, Channel, Member, MemberCompositeKey, Role, + Server, User, + }; #[async_std::test] async fn permissions() { @@ -474,12 +477,26 @@ mod tests { .await .unwrap(); - let server = Server { + let server_id = ulid::Ulid::new().to_string(); + + let channel = Channel::TextChannel { id: ulid::Ulid::new().to_string(), - owner: owner.id, + server: server_id.clone(), + name: "Channel".to_string(), + description: None, + icon: None, + last_message_id: None, + default_permissions: None, + role_permissions: HashMap::new(), + nsfw: false, + }; + + let server = Server { + id: server_id, + owner: owner.id.clone(), name: "My Server".to_string(), description: None, - channels: vec![], + channels: vec![channel.id()], categories: None, system_messages: None, roles: HashMap::from([ @@ -488,7 +505,7 @@ mod tests { Role { name: "Moderator".to_string(), permissions: OverrideField { - a: 545270208, + a: 545270208, // TODO: explicit ..Default::default() }, colour: None, @@ -516,7 +533,56 @@ mod tests { discoverable: false, }; + // TODO: proper creation + db.insert_channel(&channel).await.unwrap(); server.create(&db).await.unwrap(); + + db.insert_member(&Member { + id: MemberCompositeKey { + user: owner.id.clone(), + server: server.id.clone(), + }, + roles: vec!["01FBF9DNHSRPVTWFMNB3JNB8FK".to_string()], + ..Default::default() + }) + .await + .unwrap(); + + db.insert_member(&Member { + id: MemberCompositeKey { + user: moderator.id.clone(), + server: server.id.clone(), + }, + roles: vec!["01F9HFTSBWTNA2F4TMSV7VM3FG".to_string()], + ..Default::default() + }) + .await + .unwrap(); + + db.insert_member(&Member { + id: MemberCompositeKey { + user: user.id.clone(), + server: server.id.clone(), + }, + ..Default::default() + }) + .await + .unwrap(); + + let mut query = DatabasePermissionQuery::new(&db, &owner).server(&server); + assert!(calculate_server_permissions(&mut query) + .await + .has_channel_permission(ChannelPermission::GrantAllSafe)); + + let mut query = DatabasePermissionQuery::new(&db, &moderator).server(&server); + assert!(calculate_server_permissions(&mut query) + .await + .has_channel_permission(ChannelPermission::BanMembers)); + + let mut query = DatabasePermissionQuery::new(&db, &user).server(&server); + assert!(!calculate_server_permissions(&mut query) + .await + .has_channel_permission(ChannelPermission::BanMembers)); }); } } diff --git a/crates/core/database/src/util/idempotency.rs b/crates/core/database/src/util/idempotency.rs index 548e2d98..e12fe2f5 100644 --- a/crates/core/database/src/util/idempotency.rs +++ b/crates/core/database/src/util/idempotency.rs @@ -1,6 +1,6 @@ use std::num::NonZeroUsize; -use revolt_result::{create_error, Error, Result}; +use revolt_result::{create_error, Result}; use async_std::sync::Mutex; use once_cell::sync::Lazy; diff --git a/crates/core/database/src/util/permissions.rs b/crates/core/database/src/util/permissions.rs index b875ed47..68fbfda9 100644 --- a/crates/core/database/src/util/permissions.rs +++ b/crates/core/database/src/util/permissions.rs @@ -120,11 +120,15 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { if let Some(server) = &self.server { if self.member.is_some() { true + } else if let Ok(member) = self + .database + .fetch_member(&server.id, &self.perspective.id) + .await + { + self.member = Some(Cow::Owned(member)); + true } else { - self.database - .fetch_member(&server.id, &self.perspective.id) - .await - .is_ok() + false } } else { false