mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
Add check that people can message others in guild.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use super::get_collection;
|
||||
use super::{get_collection, MemberPermissions};
|
||||
|
||||
use bson::doc;
|
||||
use mongodb::options::{FindOneOptions, FindOptions};
|
||||
use mongodb::options::FindOptions;
|
||||
|
||||
pub fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
|
||||
let col = get_collection("members");
|
||||
@@ -79,23 +79,51 @@ pub fn find_mutual_groups(user_id: &str, target_id: &str) -> Vec<String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_mutual_connection(user_id: &str, target_id: &str) -> bool {
|
||||
let col = get_collection("guilds");
|
||||
if let Ok(result) = col.find_one(
|
||||
pub fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bool) -> bool {
|
||||
let mut doc = doc! { "_id": 1 };
|
||||
|
||||
if with_permission {
|
||||
doc.insert("default_permissions", 1);
|
||||
}
|
||||
|
||||
let opt = FindOptions::builder().projection(doc);
|
||||
|
||||
if let Ok(result) = get_collection("guilds").find(
|
||||
doc! {
|
||||
"$and": [
|
||||
{ "members": { "$elemMatch": { "id": user_id } } },
|
||||
{ "members": { "$elemMatch": { "id": target_id } } },
|
||||
]
|
||||
},
|
||||
FindOneOptions::builder()
|
||||
.projection(doc! { "_id": 1 }) // ? TODO: fetch permissions
|
||||
.build(),
|
||||
) {
|
||||
if result.is_some() {
|
||||
true
|
||||
if with_permission {
|
||||
opt.build()
|
||||
} else {
|
||||
opt.limit(1).build()
|
||||
},
|
||||
) {
|
||||
if with_permission {
|
||||
for item in result {
|
||||
// ? logic should match permissions.rs#calculate
|
||||
if let Ok(guild) = item {
|
||||
if guild.get_str("owner").unwrap() == user_id {
|
||||
return true;
|
||||
}
|
||||
|
||||
let permissions = guild.get_i32("default_permissions").unwrap() as u32;
|
||||
|
||||
if MemberPermissions([ permissions ]).get_send_direct_messages() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
} else {
|
||||
if result.count() > 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -19,7 +19,7 @@ pub enum Relationship {
|
||||
SELF = 6,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, TryFromPrimitive)]
|
||||
#[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)]
|
||||
#[repr(u32)]
|
||||
pub enum Permission {
|
||||
Access = 1,
|
||||
@@ -37,7 +37,7 @@ pub enum Permission {
|
||||
|
||||
bitfield! {
|
||||
pub struct MemberPermissions(MSB0 [u32]);
|
||||
u8;
|
||||
u32;
|
||||
pub get_access, set_access: 31;
|
||||
pub get_create_invite, set_create_invite: 30;
|
||||
pub get_kick_members, set_kick_members: 29;
|
||||
@@ -148,6 +148,7 @@ impl PermissionCalculator {
|
||||
let mut permissions: u32 = 0;
|
||||
if let Some(guild) = &self.guild {
|
||||
if let Some(_member) = &self.member {
|
||||
// ? logic should match mutual.rs#has_mutual_connection
|
||||
if guild.owner == self.user.id {
|
||||
return u32::MAX;
|
||||
}
|
||||
@@ -162,9 +163,7 @@ impl PermissionCalculator {
|
||||
if let Some(arr) = &channel.recipients {
|
||||
let mut other_user = "";
|
||||
for item in arr {
|
||||
if item == &self.user.id {
|
||||
permissions = 177;
|
||||
} else {
|
||||
if item != &self.user.id {
|
||||
other_user = item;
|
||||
}
|
||||
}
|
||||
@@ -173,12 +172,16 @@ impl PermissionCalculator {
|
||||
let relationship =
|
||||
get_relationship_internal(&self.user.id, &other_user, &relationships);
|
||||
|
||||
if relationship == Relationship::Blocked
|
||||
if relationship == Relationship::Friend {
|
||||
permissions = 177;
|
||||
} else if relationship == Relationship::Blocked
|
||||
|| relationship == Relationship::BlockedOther
|
||||
{
|
||||
permissions = 1;
|
||||
} else if has_mutual_connection(&self.user.id, other_user) {
|
||||
} else if has_mutual_connection(&self.user.id, other_user, true) {
|
||||
permissions = 177;
|
||||
} else {
|
||||
permissions = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,6 +431,10 @@ pub fn send_message(
|
||||
let permissions = with_permissions!(user, target);
|
||||
|
||||
if !permissions.get_send_messages() {
|
||||
if target.channel_type == 0 {
|
||||
return Some(Response::LackingPermission(Permission::SendDirectMessages));
|
||||
}
|
||||
|
||||
return Some(Response::LackingPermission(Permission::SendMessages));
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@ impl<'a> rocket::response::Responder<'a> for Permission {
|
||||
rocket::response::Response::build()
|
||||
.header(ContentType::JSON)
|
||||
.sized_body(Cursor::new(format!(
|
||||
"{{\"error\":\"Lacking {:?} permission.\"}}",
|
||||
self
|
||||
"{{\"error\":\"Lacking permission: {:?}.\",\"permission\":{}}}",
|
||||
self,
|
||||
self as u32,
|
||||
)))
|
||||
.ok()
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ pub fn dm(user: UserRef, target: UserRef) -> Response {
|
||||
).is_ok() {
|
||||
Response::Success(json!({ "id": id.to_string() }))
|
||||
} else {
|
||||
Response::InternalServerError(json!({ "error": "Failed to create new chanel." }))
|
||||
Response::InternalServerError(json!({ "error": "Failed to create new channel." }))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user