From 10ce7f2a622de13802c4392ca0cc0948ba0d7c6d Mon Sep 17 00:00:00 2001 From: maxgorovenko Date: Fri, 8 Nov 2024 20:44:47 +0100 Subject: [PATCH] feat: track which invite a user joined with #292 Signed-off-by: maxgorovenko --- crates/bonfire/src/events/impl.rs | 11 +- .../database/src/models/messages/model.rs | 8 +- .../src/models/server_members/model.rs | 12 +- crates/core/database/src/util/bridge/v0.rs | 66 +++++++---- crates/core/models/src/v0/server_members.rs | 4 + crates/core/permissions/src/models/channel.rs | 2 + crates/core/permissions/src/models/mod.rs | 2 +- crates/delta/src/routes/bots/invite.rs | 2 +- .../delta/src/routes/channels/message_pin.rs | 99 +++++++++------- .../delta/src/routes/channels/message_send.rs | 2 +- .../src/routes/channels/message_unpin.rs | 107 +++++++++++------- .../delta/src/routes/invites/invite_join.rs | 5 +- .../delta/src/routes/servers/member_edit.rs | 5 +- .../servers/member_experimental_query.rs | 8 +- .../delta/src/routes/servers/member_fetch.rs | 9 +- .../src/routes/servers/member_fetch_all.rs | 8 +- .../delta/src/routes/servers/server_create.rs | 2 +- 17 files changed, 232 insertions(+), 120 deletions(-) diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 426c7e586..acb9c68bf 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -99,6 +99,10 @@ impl State { let user = self.clone_user(); self.cache.is_bot = user.bot.is_some(); + // Load Channel permissions + let mut query = DatabasePermissionQuery::new(db, &user); + let permissions = calculate_channel_permissions(&mut query).await; + // Find all relationships to the user. let mut user_ids: HashSet = user .relations @@ -245,7 +249,12 @@ impl State { None }, members: if fields.contains(&ReadyPayloadFields::Members) { - Some(members.into_iter().map(Into::into).collect()) + Some( + members + .into_iter() + .map(|m| m.into(Some(permissions))) + .collect(), + ) } else { None }, diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index e813fa94f..ea5af1ae6 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -7,11 +7,12 @@ use revolt_models::v0::{ self, BulkMessageResponse, DataMessageSend, Embed, MessageAuthor, MessageFlags, MessageSort, MessageWebhook, PushNotification, ReplyIntent, SendableEmbed, Text, RE_MENTION, }; -use revolt_permissions::{ChannelPermission, PermissionValue}; +use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionValue}; use revolt_result::Result; use ulid::Ulid; use validator::Validate; +use crate::util::permissions::DatabasePermissionQuery; use crate::{ events::client::EventV1, tasks::{self, ack::AckEvent}, @@ -592,6 +593,9 @@ impl Message { .map(|msg| msg.into_model(None, None)) .collect(); + let mut query = DatabasePermissionQuery::new(db, perspective); + let permissions = calculate_channel_permissions(&mut query).await; + if let Some(true) = include_users { let user_ids = messages .iter() @@ -643,7 +647,7 @@ impl Message { db.fetch_members(&server_id, &user_ids) .await? .into_iter() - .map(Into::into) + .map(|m| m.into(Some(permissions))) .collect(), ) } else { diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index 88f953cf8..0af4fbd35 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -1,5 +1,5 @@ use iso8601_timestamp::Timestamp; -use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; +use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionValue}; use revolt_result::{create_error, Result}; use crate::{ @@ -17,6 +17,10 @@ auto_derived_partial!( /// Time at which this user joined the server pub joined_at: Timestamp, + /// Invite used by member to join server + #[serde(skip_serializing_if = "Option::is_none")] + pub used_invite: Option, + /// Member's nickname #[serde(skip_serializing_if = "Option::is_none")] pub nickname: Option, @@ -69,6 +73,7 @@ impl Default for Member { avatar: None, roles: vec![], timeout: None, + used_invite: None, } } } @@ -81,6 +86,7 @@ impl Member { server: &Server, user: &User, channels: Option>, + used_invite: Option, ) -> Result<(Member, Vec)> { if db.fetch_ban(&server.id, &user.id).await.is_ok() { return Err(create_error!(Banned)); @@ -95,6 +101,7 @@ impl Member { server: server.id.to_string(), user: user.id.to_string(), }, + used_invite, ..Default::default() }; @@ -164,6 +171,7 @@ impl Member { db: &Database, partial: PartialMember, remove: Vec, + perspective_permissions: Option, ) -> Result<()> { for field in &remove { self.remove_field(field); @@ -175,7 +183,7 @@ impl Member { EventV1::ServerMemberUpdate { id: self.id.clone().into(), - data: partial.into(), + data: partial.into(perspective_permissions), clear: remove.into_iter().map(|field| field.into()).collect(), } .p(self.id.server.clone()) diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index f6d96b142..c5fa596d0 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -1,5 +1,7 @@ use revolt_models::v0::*; -use revolt_permissions::{calculate_user_permissions, UserPermission}; +use revolt_permissions::{ + calculate_user_permissions, ChannelPermission, PermissionValue, UserPermission, +}; use crate::{util::permissions::DatabasePermissionQuery, Database, FileUsedFor}; @@ -617,16 +619,28 @@ impl From for ServerBan { } } -impl From for Member { - fn from(value: crate::Member) -> Self { - Member { - id: value.id.into(), - joined_at: value.joined_at, - nickname: value.nickname, - avatar: value.avatar.map(|f| f.into()), - roles: value.roles, - timeout: value.timeout, +impl crate::Member { + pub fn into(self, perspective_permissions: Option) -> Member { + let mut m = Member { + id: self.id.into(), + joined_at: self.joined_at, + nickname: self.nickname, + avatar: self.avatar.map(|f| f.into()), + roles: self.roles, + timeout: self.timeout, + used_invite: self.used_invite, + }; + + match perspective_permissions { + Some(permissions) => { + if !permissions.has_channel_permission(ChannelPermission::ViewInvitation) { + m.used_invite = None; + } + } + None => {} } + + m } } @@ -639,20 +653,33 @@ impl From for crate::Member { avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, + used_invite: value.used_invite, } } } -impl From for PartialMember { - fn from(value: crate::PartialMember) -> Self { - PartialMember { - id: value.id.map(|id| id.into()), - joined_at: value.joined_at, - nickname: value.nickname, - avatar: value.avatar.map(|f| f.into()), - roles: value.roles, - timeout: value.timeout, +impl crate::PartialMember { + pub fn into(self, perspective_permissions: Option) -> PartialMember { + let mut pm = PartialMember { + id: self.id.map(|id| id.into()), + joined_at: self.joined_at, + nickname: self.nickname, + avatar: self.avatar.map(|f| f.into()), + roles: self.roles, + timeout: self.timeout, + used_invite: self.used_invite, + }; + + match perspective_permissions { + Some(permissions) => { + if !permissions.has_channel_permission(ChannelPermission::ViewInvitation) { + pm.used_invite = None; + } + } + None => {} } + + pm } } @@ -665,6 +692,7 @@ impl From for crate::PartialMember { avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, + used_invite: value.used_invite, } } } diff --git a/crates/core/models/src/v0/server_members.rs b/crates/core/models/src/v0/server_members.rs index 5b26b88a2..65cd8fc5e 100644 --- a/crates/core/models/src/v0/server_members.rs +++ b/crates/core/models/src/v0/server_members.rs @@ -41,6 +41,10 @@ auto_derived_partial!( /// Time at which this user joined the server pub joined_at: Timestamp, + /// Invite used by member to join server + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub used_invite: Option, + /// Member's nickname #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub nickname: Option, diff --git a/crates/core/permissions/src/models/channel.rs b/crates/core/permissions/src/models/channel.rs index 17762b1ed..4b1e6fd79 100644 --- a/crates/core/permissions/src/models/channel.rs +++ b/crates/core/permissions/src/models/channel.rs @@ -51,6 +51,8 @@ pub enum ChannelPermission { ChangeAvatar = 1 << 12, /// Remove other's avatars below their ranking RemoveAvatars = 1 << 13, + /// View member's invitation + ViewInvitation = 1 << 14, // % 7 bits reserved diff --git a/crates/core/permissions/src/models/mod.rs b/crates/core/permissions/src/models/mod.rs index 330fe7562..93322f8ef 100644 --- a/crates/core/permissions/src/models/mod.rs +++ b/crates/core/permissions/src/models/mod.rs @@ -8,7 +8,7 @@ pub use server::*; pub use user::*; /// Holds a permission value to manipulate. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Copy)] pub struct PermissionValue(u64); impl PermissionValue { diff --git a/crates/delta/src/routes/bots/invite.rs b/crates/delta/src/routes/bots/invite.rs index 120c36dab..06c061241 100644 --- a/crates/delta/src/routes/bots/invite.rs +++ b/crates/delta/src/routes/bots/invite.rs @@ -42,7 +42,7 @@ pub async fn invite_bot( .await .throw_if_lacking_channel_permission(ChannelPermission::ManageServer)?; - Member::create(db, &server, &bot_user, None) + Member::create(db, &server, &bot_user, None, None) .await .map(|_| EmptyResponse) } diff --git a/crates/delta/src/routes/channels/message_pin.rs b/crates/delta/src/routes/channels/message_pin.rs index 5dc318f87..249eb3477 100644 --- a/crates/delta/src/routes/channels/message_pin.rs +++ b/crates/delta/src/routes/channels/message_pin.rs @@ -1,5 +1,6 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, PartialMessage, SystemMessage, User + util::{permissions::DatabasePermissionQuery, reference::Reference}, + Database, PartialMessage, SystemMessage, User, }; use revolt_models::v0::MessageAuthor; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -28,30 +29,37 @@ pub async fn message_pin( let mut message = msg.as_message_in_channel(db, channel.id()).await?; if message.pinned.unwrap_or_default() { - return Err(create_error!(AlreadyPinned)) + return Err(create_error!(AlreadyPinned)); } - message.update(db, PartialMessage { - pinned: Some(true), - ..Default::default() - }, vec![]).await?; + message + .update( + db, + PartialMessage { + pinned: Some(true), + ..Default::default() + }, + vec![], + ) + .await?; SystemMessage::MessagePinned { id: message.id.clone(), - by: user.id.clone() + by: user.id.clone(), } .into_message(channel.id().to_string()) .send( db, MessageAuthor::System { username: &user.username, - avatar: user.avatar.as_ref().map(|file| file.id.as_ref()) + avatar: user.avatar.as_ref().map(|file| file.id.as_ref()), }, None, None, &channel, - false - ).await?; + false, + ) + .await?; Ok(EmptyResponse) } @@ -59,7 +67,11 @@ pub async fn message_pin( #[cfg(test)] mod test { use crate::{rocket, util::test::TestHarness}; - use revolt_database::{events::client::EventV1, util::{idempotency::IdempotencyKey, reference::Reference}, Member, Message, Server}; + use revolt_database::{ + events::client::EventV1, + util::{idempotency::IdempotencyKey, reference::Reference}, + Member, Message, Server, + }; use revolt_models::v0::{self, SystemMessage}; use rocket::http::{Header, Status}; @@ -75,39 +87,47 @@ mod test { ..Default::default() }, &user, - true - ).await.expect("Failed to create test server"); + true, + ) + .await + .expect("Failed to create test server"); - let (member, channels) = Member::create(&harness.db, &server, &user, Some(channels)).await.expect("Failed to create member"); + let (member, channels) = Member::create(&harness.db, &server, &user, Some(channels), None) + .await + .expect("Failed to create member"); let channel = &channels[0]; let message = Message::create_from_api( &harness.db, channel.clone(), v0::DataMessageSend { - content:Some("Test message".to_string()), + content: Some("Test message".to_string()), nonce: None, attachments: None, replies: None, embeds: None, masquerade: None, interactions: None, - flags: None + flags: None, }, v0::MessageAuthor::User(&user.clone().into(&harness.db, Some(&user)).await), Some(user.clone().into(&harness.db, Some(&user)).await), - Some(member.into()), + Some(member.into(None)), user.limits().await, IdempotencyKey::unchecked_from_string("0".to_string()), false, - false + false, ) .await .expect("Failed to create message"); let response = harness .client - .post(format!("/channels/{}/messages/{}/pin", channel.id(), &message.id)) + .post(format!( + "/channels/{}/messages/{}/pin", + channel.id(), + &message.id + )) .header(Header::new("x-session-token", session.token.to_string())) .dispatch() .await; @@ -115,34 +135,37 @@ mod test { assert_eq!(response.status(), Status::NoContent); drop(response); - harness.wait_for_event(channel.id(), |event| { - match event { - EventV1::Message(message) => { - match &message.system { - Some(SystemMessage::MessagePinned { by, .. }) => { - assert_eq!(by, &user.id); + harness + .wait_for_event(channel.id(), |event| match event { + EventV1::Message(message) => match &message.system { + Some(SystemMessage::MessagePinned { by, .. }) => { + assert_eq!(by, &user.id); - true - }, - _ => false + true } + _ => false, }, - _ => false - } - }).await; + _ => false, + }) + .await; - harness.wait_for_event(channel.id(), |event| { - match event { - EventV1::MessageUpdate { id, channel: channel_id, data, .. } => { + harness + .wait_for_event(channel.id(), |event| match event { + EventV1::MessageUpdate { + id, + channel: channel_id, + data, + .. + } => { assert_eq!(id, &message.id); assert_eq!(channel_id, channel.id()); assert_eq!(data.pinned, Some(true)); true - }, - _ => false - } - }).await; + } + _ => false, + }) + .await; let updated_message = Reference::from_unchecked(message.id) .as_message(&harness.db) diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index 93a290579..d5ebd4ede 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -88,7 +88,7 @@ pub async fn message_send( let model_member: Option = query .member_ref() .as_ref() - .map(|member| member.clone().into_owned().into()); + .map(|member| member.clone().into_owned().into(Some(permissions))); Ok(Json( Message::create_from_api( diff --git a/crates/delta/src/routes/channels/message_unpin.rs b/crates/delta/src/routes/channels/message_unpin.rs index 4084fc119..b5b3e2bed 100644 --- a/crates/delta/src/routes/channels/message_unpin.rs +++ b/crates/delta/src/routes/channels/message_unpin.rs @@ -1,5 +1,6 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, FieldsMessage, PartialMessage, SystemMessage, User + util::{permissions::DatabasePermissionQuery, reference::Reference}, + Database, FieldsMessage, PartialMessage, SystemMessage, User, }; use revolt_models::v0::MessageAuthor; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -28,27 +29,30 @@ pub async fn message_unpin( let mut message = msg.as_message_in_channel(db, channel.id()).await?; if !message.pinned.unwrap_or_default() { - return Err(create_error!(NotPinned)) + return Err(create_error!(NotPinned)); } - message.update(db, PartialMessage::default(), vec![FieldsMessage::Pinned]).await?; + message + .update(db, PartialMessage::default(), vec![FieldsMessage::Pinned]) + .await?; SystemMessage::MessageUnpinned { id: message.id.clone(), - by: user.id.clone() + by: user.id.clone(), } .into_message(channel.id().to_string()) .send( db, MessageAuthor::System { username: &user.username, - avatar: user.avatar.as_ref().map(|file| file.id.as_ref()) + avatar: user.avatar.as_ref().map(|file| file.id.as_ref()), }, None, None, &channel, - false - ).await?; + false, + ) + .await?; Ok(EmptyResponse) } @@ -56,7 +60,11 @@ pub async fn message_unpin( #[cfg(test)] mod test { use crate::{rocket, util::test::TestHarness}; - use revolt_database::{events::client::EventV1, util::{idempotency::IdempotencyKey, reference::Reference}, Member, Message, PartialMessage, Server}; + use revolt_database::{ + events::client::EventV1, + util::{idempotency::IdempotencyKey, reference::Reference}, + Member, Message, PartialMessage, Server, + }; use revolt_models::v0::{self, FieldsMessage, SystemMessage}; use rocket::http::{Header, Status}; @@ -72,50 +80,65 @@ mod test { ..Default::default() }, &user, - true - ).await.expect("Failed to create test server"); + true, + ) + .await + .expect("Failed to create test server"); let channel = &channels[0]; - Member::create(&harness.db, &server, &user, Some(channels.clone())).await.expect("Failed to create member"); - let member = Reference::from_unchecked(user.id.clone()).as_member(&harness.db, &server.id).await.expect("Failed to get member"); + Member::create(&harness.db, &server, &user, Some(channels.clone()), None) + .await + .expect("Failed to create member"); + let member = Reference::from_unchecked(user.id.clone()) + .as_member(&harness.db, &server.id) + .await + .expect("Failed to get member"); let message = Message::create_from_api( &harness.db, channel.clone(), v0::DataMessageSend { - content:Some("Test message".to_string()), + content: Some("Test message".to_string()), nonce: None, attachments: None, replies: None, embeds: None, masquerade: None, interactions: None, - flags: None + flags: None, }, v0::MessageAuthor::User(&user.clone().into(&harness.db, Some(&user)).await), Some(user.clone().into(&harness.db, Some(&user)).await), - Some(member.into()), + Some(member.into(None)), user.limits().await, IdempotencyKey::unchecked_from_string("0".to_string()), false, - false + false, ) .await .expect("Failed to create message"); - harness.db.update_message( - &message.id, - &PartialMessage { - pinned: Some(true), - ..Default::default() - }, - vec![] - ).await.expect("Failed to update message"); + harness + .db + .update_message( + &message.id, + &PartialMessage { + pinned: Some(true), + ..Default::default() + }, + vec![], + ) + .await + .expect("Failed to update message"); let response = harness .client - .delete(format!("/channels/{}/messages/{}/pin", channel.id(), &message.id)) + .delete(format!( + "/channels/{}/messages/{}/pin", + channel.id(), + &message.id + )) .header(Header::new("x-session-token", session.token.to_string())) .dispatch() .await; @@ -123,33 +146,31 @@ mod test { assert_eq!(response.status(), Status::NoContent); drop(response); - harness.wait_for_event(channel.id(), |event| { - match event { - EventV1::Message(message) => { - match &message.system { - Some(SystemMessage::MessageUnpinned { by, .. }) => { - assert_eq!(by, &user.id); + harness + .wait_for_event(channel.id(), |event| match event { + EventV1::Message(message) => match &message.system { + Some(SystemMessage::MessageUnpinned { by, .. }) => { + assert_eq!(by, &user.id); - true - }, - _ => false + true } + _ => false, }, - _ => false - } - }).await; + _ => false, + }) + .await; - harness.wait_for_event(channel.id(), |event| { - match event { + harness + .wait_for_event(channel.id(), |event| match event { EventV1::MessageUpdate { id, clear, .. } => { assert_eq!(&message.id, id); assert_eq!(clear, &[FieldsMessage::Pinned]); true - }, - _ => false - } - }).await; + } + _ => false, + }) + .await; let updated_message = Reference::from_unchecked(message.id) .as_message(&harness.db) diff --git a/crates/delta/src/routes/invites/invite_join.rs b/crates/delta/src/routes/invites/invite_join.rs index 2fa872d3f..984c9cc3d 100644 --- a/crates/delta/src/routes/invites/invite_join.rs +++ b/crates/delta/src/routes/invites/invite_join.rs @@ -21,9 +21,10 @@ pub async fn join( let invite = target.as_invite(db).await?; match &invite { - Invite::Server { server, .. } => { + Invite::Server { server, code, .. } => { let server = db.fetch_server(server).await?; - let (_, channels) = Member::create(db, &server, &user, None).await?; + let (_, channels) = + Member::create(db, &server, &user, None, Some(code.to_string())).await?; Ok(Json(InviteJoinResponse::Server { channels: channels.into_iter().map(|c| c.into()).collect(), diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index b10a9a3e1..55eca4694 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -6,7 +6,7 @@ use revolt_database::{ }; use revolt_models::v0; -use revolt_permissions::{calculate_server_permissions, ChannelPermission}; +use revolt_permissions::{calculate_server_permissions, ChannelPermission, PermissionValue}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; use validator::Validate; @@ -152,8 +152,9 @@ pub async fn edit( remove .map(|v| v.into_iter().map(Into::into).collect()) .unwrap_or_default(), + Some(permissions), ) .await?; - Ok(Json(member.into())) + Ok(Json(member.into(Some(permissions)))) } diff --git a/crates/delta/src/routes/servers/member_experimental_query.rs b/crates/delta/src/routes/servers/member_experimental_query.rs index 125b8db9a..8ee75a44f 100644 --- a/crates/delta/src/routes/servers/member_experimental_query.rs +++ b/crates/delta/src/routes/servers/member_experimental_query.rs @@ -4,7 +4,7 @@ use revolt_database::{ Database, Member, User, }; use revolt_models::v0; -use revolt_permissions::PermissionQuery; +use revolt_permissions::{calculate_channel_permissions, PermissionQuery}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; use serde::{Deserialize, Serialize}; @@ -49,6 +49,7 @@ pub async fn member_experimental_query( return Err(create_error!(NotFound)); } + let permissions = calculate_channel_permissions(&mut query).await; let mut members = db.fetch_all_members(&server.id).await?; let mut user_ids = vec![]; @@ -85,7 +86,10 @@ pub async fn member_experimental_query( // Take the first ten and return them let (members, users): (Vec, Vec) = zipped_vec.into_iter().take(10).unzip(); Ok(Json(MemberQueryResponse { - members: members.into_iter().map(Into::into).collect(), + members: members + .into_iter() + .map(|m| m.into(Some(permissions))) + .collect(), users: join_all( users .into_iter() diff --git a/crates/delta/src/routes/servers/member_fetch.rs b/crates/delta/src/routes/servers/member_fetch.rs index b1f39740b..701c68571 100644 --- a/crates/delta/src/routes/servers/member_fetch.rs +++ b/crates/delta/src/routes/servers/member_fetch.rs @@ -3,7 +3,7 @@ use revolt_database::{ Database, User, }; use revolt_models::v0; -use revolt_permissions::PermissionQuery; +use revolt_permissions::{calculate_channel_permissions, PermissionQuery}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; @@ -24,6 +24,7 @@ pub async fn fetch( if !query.are_we_a_member().await { return Err(create_error!(NotFound)); } + let permissions = calculate_channel_permissions(&mut query).await; let member = member.as_member(db, &server.id).await?; if let Some(true) = roles { @@ -34,9 +35,11 @@ pub async fn fetch( .filter(|(k, _)| member.roles.contains(k)) .map(|(k, v)| (k, v.into())) .collect(), - member: member.into(), + member: member.into(Some(permissions)), })) } else { - Ok(Json(v0::MemberResponse::Member(member.into()))) + Ok(Json(v0::MemberResponse::Member( + member.into(Some(permissions)), + ))) } } diff --git a/crates/delta/src/routes/servers/member_fetch_all.rs b/crates/delta/src/routes/servers/member_fetch_all.rs index 299976686..742bb87ed 100644 --- a/crates/delta/src/routes/servers/member_fetch_all.rs +++ b/crates/delta/src/routes/servers/member_fetch_all.rs @@ -3,7 +3,7 @@ use revolt_database::{ Database, User, }; use revolt_models::v0; -use revolt_permissions::PermissionQuery; +use revolt_permissions::{calculate_channel_permissions, PermissionQuery}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; @@ -24,6 +24,7 @@ pub async fn fetch_all( return Err(create_error!(NotFound)); } + let permissions = calculate_channel_permissions(&mut query).await; let mut members = db.fetch_all_members(&server.id).await?; let user_ids: Vec = members @@ -45,7 +46,10 @@ pub async fn fetch_all( } Ok(Json(v0::AllMemberResponse { - members: members.into_iter().map(Into::into).collect(), + members: members + .into_iter() + .map(|m| m.into(Some(permissions))) + .collect(), users, })) } diff --git a/crates/delta/src/routes/servers/server_create.rs b/crates/delta/src/routes/servers/server_create.rs index 82f0a8aaf..db799cefe 100644 --- a/crates/delta/src/routes/servers/server_create.rs +++ b/crates/delta/src/routes/servers/server_create.rs @@ -30,7 +30,7 @@ pub async fn create_server( user.can_acquire_server(db).await?; let (server, channels) = Server::create(db, data, &user, true).await?; - let (_, channels) = Member::create(db, &server, &user, Some(channels)).await?; + let (_, channels) = Member::create(db, &server, &user, Some(channels), None).await?; Ok(Json(v0::CreateServerLegacyResponse { server: server.into(),