Skip to content

Commit

Permalink
feat: track which invite a user joined with #292
Browse files Browse the repository at this point in the history
Signed-off-by: maxgorovenko <[email protected]>
  • Loading branch information
maxgorovenko committed Nov 8, 2024
1 parent 705e517 commit 10ce7f2
Show file tree
Hide file tree
Showing 17 changed files with 232 additions and 120 deletions.
11 changes: 10 additions & 1 deletion crates/bonfire/src/events/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> = user
.relations
Expand Down Expand Up @@ -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
},
Expand Down
8 changes: 6 additions & 2 deletions crates/core/database/src/models/messages/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 10 additions & 2 deletions crates/core/database/src/models/server_members/model.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand All @@ -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<String>,

/// Member's nickname
#[serde(skip_serializing_if = "Option::is_none")]
pub nickname: Option<String>,
Expand Down Expand Up @@ -69,6 +73,7 @@ impl Default for Member {
avatar: None,
roles: vec![],
timeout: None,
used_invite: None,
}
}
}
Expand All @@ -81,6 +86,7 @@ impl Member {
server: &Server,
user: &User,
channels: Option<Vec<Channel>>,
used_invite: Option<String>,
) -> Result<(Member, Vec<Channel>)> {
if db.fetch_ban(&server.id, &user.id).await.is_ok() {
return Err(create_error!(Banned));
Expand All @@ -95,6 +101,7 @@ impl Member {
server: server.id.to_string(),
user: user.id.to_string(),
},
used_invite,
..Default::default()
};

Expand Down Expand Up @@ -164,6 +171,7 @@ impl Member {
db: &Database,
partial: PartialMember,
remove: Vec<FieldsMember>,
perspective_permissions: Option<PermissionValue>,
) -> Result<()> {
for field in &remove {
self.remove_field(field);
Expand All @@ -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())
Expand Down
66 changes: 47 additions & 19 deletions crates/core/database/src/util/bridge/v0.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -617,16 +619,28 @@ impl From<crate::ServerBan> for ServerBan {
}
}

impl From<crate::Member> 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<PermissionValue>) -> 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
}
}

Expand All @@ -639,20 +653,33 @@ impl From<Member> for crate::Member {
avatar: value.avatar.map(|f| f.into()),
roles: value.roles,
timeout: value.timeout,
used_invite: value.used_invite,
}
}
}

impl From<crate::PartialMember> 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<PermissionValue>) -> 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
}
}

Expand All @@ -665,6 +692,7 @@ impl From<PartialMember> for crate::PartialMember {
avatar: value.avatar.map(|f| f.into()),
roles: value.roles,
timeout: value.timeout,
used_invite: value.used_invite,
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/core/models/src/v0/server_members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,

/// Member's nickname
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub nickname: Option<String>,
Expand Down
2 changes: 2 additions & 0 deletions crates/core/permissions/src/models/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion crates/core/permissions/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion crates/delta/src/routes/bots/invite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Loading

0 comments on commit 10ce7f2

Please sign in to comment.