From beeb7e7a95eaa8d9444cba2a8eeb801e5fe639ec Mon Sep 17 00:00:00 2001
From: Paul Makles <paulmakles@gmail.com>
Date: Sat, 11 Apr 2020 22:06:09 +0100
Subject: [PATCH] Don't allow banned users to view or use invites.

---
 src/guards/guild.rs | 34 ++++++++++++++++++++++++++--------
 src/routes/guild.rs |  8 ++++----
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/src/guards/guild.rs b/src/guards/guild.rs
index 9ca04cf..386149d 100644
--- a/src/guards/guild.rs
+++ b/src/guards/guild.rs
@@ -94,15 +94,33 @@ pub fn get_member(guild_id: &String, member: &String) -> Option<Member> {
     }
 }
 
-pub fn get_invite(code: &String) -> Option<(String, String, Invite)> {
-    if let Ok(result) = database::get_collection("guilds").find_one(
-        doc! {
-            "invites": {
-                "$elemMatch": {
-                    "code": &code
-                }
+pub fn get_invite<U: Into<Option<String>>>(
+    code: &String,
+    user: U,
+) -> Option<(String, String, Invite)> {
+    let mut doc = doc! {
+        "invites": {
+            "$elemMatch": {
+                "code": &code
             }
-        },
+        }
+    };
+
+    if let Some(user_id) = user.into() {
+        doc.insert(
+            "bans",
+            doc! {
+                "$not": {
+                    "$elemMatch": {
+                        "id": user_id
+                    }
+                }
+            },
+        );
+    }
+
+    if let Ok(result) = database::get_collection("guilds").find_one(
+        doc,
         FindOneOptions::builder()
             .projection(doc! {
                 "_id": 1,
diff --git a/src/routes/guild.rs b/src/routes/guild.rs
index 1e0e74b..ee79711 100644
--- a/src/routes/guild.rs
+++ b/src/routes/guild.rs
@@ -245,7 +245,7 @@ pub fn create_invite(
 pub fn remove_invite(user: UserRef, target: GuildRef, code: String) -> Option<Response> {
     let (permissions, _) = with_permissions!(user, target);
 
-    if let Some((guild_id, _, invite)) = get_invite(&code) {
+    if let Some((guild_id, _, invite)) = get_invite(&code, None) {
         if invite.creator != user.id {
             if !permissions.get_manage_server() {
                 return Some(Response::LackingPermission(Permission::ManageServer));
@@ -303,8 +303,8 @@ pub fn fetch_invites(user: UserRef, target: GuildRef) -> Option<Response> {
 
 /// view an invite before joining
 #[get("/join/<code>", rank = 1)]
-pub fn fetch_invite(_user: UserRef, code: String) -> Response {
-    if let Some((guild_id, name, invite)) = get_invite(&code) {
+pub fn fetch_invite(user: UserRef, code: String) -> Response {
+    if let Some((guild_id, name, invite)) = get_invite(&code, user.id) {
         if let Some(channel) = ChannelRef::from(invite.channel) {
             Response::Success(json!({
                 "guild": {
@@ -327,7 +327,7 @@ pub fn fetch_invite(_user: UserRef, code: String) -> Response {
 /// join a guild using an invite
 #[post("/join/<code>", rank = 1)]
 pub fn use_invite(user: UserRef, code: String) -> Response {
-    if let Some((guild_id, _, invite)) = get_invite(&code) {
+    if let Some((guild_id, _, invite)) = get_invite(&code, Some(user.id.clone())) {
         if let Ok(result) = database::get_collection("members").find_one(
             doc! {
                 "_id.guild": &guild_id,
-- 
GitLab