Add check that people can message others in guild.

This commit is contained in:
Paul Makles
2020-04-12 12:16:00 +01:00
parent 2063eeac3d
commit d9db42cc09
5 changed files with 57 additions and 21 deletions

View File

@@ -1,7 +1,7 @@
use super::get_collection; use super::{get_collection, MemberPermissions};
use bson::doc; 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> { pub fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
let col = get_collection("members"); 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 { pub fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bool) -> bool {
let col = get_collection("guilds"); let mut doc = doc! { "_id": 1 };
if let Ok(result) = col.find_one(
if with_permission {
doc.insert("default_permissions", 1);
}
let opt = FindOptions::builder().projection(doc);
if let Ok(result) = get_collection("guilds").find(
doc! { doc! {
"$and": [ "$and": [
{ "members": { "$elemMatch": { "id": user_id } } }, { "members": { "$elemMatch": { "id": user_id } } },
{ "members": { "$elemMatch": { "id": target_id } } }, { "members": { "$elemMatch": { "id": target_id } } },
] ]
}, },
FindOneOptions::builder() if with_permission {
.projection(doc! { "_id": 1 }) // ? TODO: fetch permissions opt.build()
.build(),
) {
if result.is_some() {
true
} else { } 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 false
} else {
if result.count() > 0 {
true
} else {
false
}
} }
} else { } else {
false false

View File

@@ -19,7 +19,7 @@ pub enum Relationship {
SELF = 6, SELF = 6,
} }
#[derive(Debug, PartialEq, Eq, TryFromPrimitive)] #[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)]
#[repr(u32)] #[repr(u32)]
pub enum Permission { pub enum Permission {
Access = 1, Access = 1,
@@ -37,7 +37,7 @@ pub enum Permission {
bitfield! { bitfield! {
pub struct MemberPermissions(MSB0 [u32]); pub struct MemberPermissions(MSB0 [u32]);
u8; u32;
pub get_access, set_access: 31; pub get_access, set_access: 31;
pub get_create_invite, set_create_invite: 30; pub get_create_invite, set_create_invite: 30;
pub get_kick_members, set_kick_members: 29; pub get_kick_members, set_kick_members: 29;
@@ -148,6 +148,7 @@ impl PermissionCalculator {
let mut permissions: u32 = 0; let mut permissions: u32 = 0;
if let Some(guild) = &self.guild { if let Some(guild) = &self.guild {
if let Some(_member) = &self.member { if let Some(_member) = &self.member {
// ? logic should match mutual.rs#has_mutual_connection
if guild.owner == self.user.id { if guild.owner == self.user.id {
return u32::MAX; return u32::MAX;
} }
@@ -162,9 +163,7 @@ impl PermissionCalculator {
if let Some(arr) = &channel.recipients { if let Some(arr) = &channel.recipients {
let mut other_user = ""; let mut other_user = "";
for item in arr { for item in arr {
if item == &self.user.id { if item != &self.user.id {
permissions = 177;
} else {
other_user = item; other_user = item;
} }
} }
@@ -173,12 +172,16 @@ impl PermissionCalculator {
let relationship = let relationship =
get_relationship_internal(&self.user.id, &other_user, &relationships); 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 || relationship == Relationship::BlockedOther
{ {
permissions = 1; 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; permissions = 177;
} else {
permissions = 1;
} }
} }
} }

View File

@@ -431,6 +431,10 @@ pub fn send_message(
let permissions = with_permissions!(user, target); let permissions = with_permissions!(user, target);
if !permissions.get_send_messages() { if !permissions.get_send_messages() {
if target.channel_type == 0 {
return Some(Response::LackingPermission(Permission::SendDirectMessages));
}
return Some(Response::LackingPermission(Permission::SendMessages)); return Some(Response::LackingPermission(Permission::SendMessages));
} }

View File

@@ -50,8 +50,9 @@ impl<'a> rocket::response::Responder<'a> for Permission {
rocket::response::Response::build() rocket::response::Response::build()
.header(ContentType::JSON) .header(ContentType::JSON)
.sized_body(Cursor::new(format!( .sized_body(Cursor::new(format!(
"{{\"error\":\"Lacking {:?} permission.\"}}", "{{\"error\":\"Lacking permission: {:?}.\",\"permission\":{}}}",
self self,
self as u32,
))) )))
.ok() .ok()
} }

View File

@@ -157,7 +157,7 @@ pub fn dm(user: UserRef, target: UserRef) -> Response {
).is_ok() { ).is_ok() {
Response::Success(json!({ "id": id.to_string() })) Response::Success(json!({ "id": id.to_string() }))
} else { } else {
Response::InternalServerError(json!({ "error": "Failed to create new chanel." })) Response::InternalServerError(json!({ "error": "Failed to create new channel." }))
} }
} }
} else { } else {