From 95aad8092b70261d86ca107c2adf16c4ae794047 Mon Sep 17 00:00:00 2001
From: Paul Makles <paulmakles@gmail.com>
Date: Fri, 10 Apr 2020 15:35:00 +0100
Subject: [PATCH] Display mutual connections when fetching user.

---
 src/database/mutual.rs      | 86 ++++++++++++++++++++++++++++++++++---
 src/database/permissions.rs |  2 +-
 src/routes/user.rs          |  9 +++-
 3 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/src/database/mutual.rs b/src/database/mutual.rs
index 0067e28..b6a7726 100644
--- a/src/database/mutual.rs
+++ b/src/database/mutual.rs
@@ -1,17 +1,91 @@
 use super::get_collection;
 
 use bson::doc;
-use mongodb::options::FindOneOptions;
+use mongodb::options::{FindOptions, FindOneOptions};
 
-/*pub struct MutualGuild {
+pub fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
+    let col = get_collection("guilds");
+    if let Ok(result) = col.find(
+        doc! {
+            "$and": [
+                { "members": { "$elemMatch": { "id": user_id   } } },
+                { "members": { "$elemMatch": { "id": target_id } } },
+            ]
+        },
+        FindOptions::builder()
+            .projection(doc! { "_id": 1 })
+            .build(),
+    ) {
+        let mut results = vec![];
 
+        for doc in result {
+            if let Ok(guild) = doc {
+                results.push(guild.get_str("_id").unwrap().to_string());
+            }
+        }
+
+        results
+    } else {
+        vec![]
+    }
 }
 
-pub fn find_mutual_guilds(user_id: String, target_id: String) -> Vec<> {
+pub fn find_mutual_friends(user_id: &str, target_id: &str) -> Vec<String> {
+    let col = get_collection("users");
+    if let Ok(result) = col.find(
+        doc! {
+            "$and": [
+                { "relations": { "$elemMatch": { "id": user_id,   "status": 0 } } },
+                { "relations": { "$elemMatch": { "id": target_id, "status": 0 } } },
+            ]
+        },
+        FindOptions::builder()
+            .projection(doc! { "_id": 1 })
+            .build(),
+    ) {
+        let mut results = vec![];
 
-}*/
+        for doc in result {
+            if let Ok(user) = doc {
+                results.push(user.get_str("_id").unwrap().to_string());
+            }
+        }
+
+        results
+    } else {
+        vec![]
+    }
+}
+
+pub fn find_mutual_groups(user_id: &str, target_id: &str) -> Vec<String> {
+    let col = get_collection("channels");
+    if let Ok(result) = col.find(
+        doc! {
+            "type": 1,
+            "$and": [
+                { "recipients": user_id },
+                { "recipients": target_id },
+            ]
+        },
+        FindOptions::builder()
+            .projection(doc! { "_id": 1 })
+            .build(),
+    ) {
+        let mut results = vec![];
+
+        for doc in result {
+            if let Ok(group) = doc {
+                results.push(group.get_str("_id").unwrap().to_string());
+            }
+        }
 
-pub fn has_mutual_connection(user_id: String, target_id: String) -> bool {
+        results
+    } else {
+        vec![]
+    }
+}
+
+pub fn has_mutual_connection(user_id: &str, target_id: &str) -> bool {
     let col = get_collection("guilds");
     if let Ok(result) = col.find_one(
         doc! {
@@ -21,7 +95,7 @@ pub fn has_mutual_connection(user_id: String, target_id: String) -> bool {
             ]
         },
         FindOneOptions::builder()
-            .projection(doc! { "_id": 1 })
+            .projection(doc! { "_id": 1 }) // ? TODO: fetch permissions
             .build(),
     ) {
         if result.is_some() {
diff --git a/src/database/permissions.rs b/src/database/permissions.rs
index 0c20185..13d812a 100644
--- a/src/database/permissions.rs
+++ b/src/database/permissions.rs
@@ -173,7 +173,7 @@ impl PermissionCalculator {
                             || relationship == Relationship::BlockedOther
                         {
                             permissions = 1;
-                        } else if has_mutual_connection(self.user.id, other_user.to_string()) {
+                        } else if has_mutual_connection(&self.user.id, other_user) {
                             permissions = 177;
                         }
                     }
diff --git a/src/routes/user.rs b/src/routes/user.rs
index 1535633..631ed21 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -1,5 +1,5 @@
 use super::Response;
-use crate::database::{self, get_relationship, get_relationship_internal, Relationship};
+use crate::database::{self, get_relationship, get_relationship_internal, Relationship, mutual};
 use crate::guards::auth::UserRef;
 use crate::routes::channel;
 
@@ -32,7 +32,12 @@ pub fn user(user: UserRef, target: UserRef) -> Response {
     Response::Success(json!({
         "id": target.id,
         "username": target.username,
-        "relationship": get_relationship(&user, &target) as u8
+        "relationship": get_relationship(&user, &target) as u8,
+        "mutual": {
+            "guilds": mutual::find_mutual_guilds(&user.id, &target.id),
+            "friends": mutual::find_mutual_friends(&user.id, &target.id),
+            "groups": mutual::find_mutual_groups(&user.id, &target.id),
+        }
     }))
 }
 
-- 
GitLab