From a6105f70294f108f278ba5dd520564f59cc3de1e Mon Sep 17 00:00:00 2001
From: Miroslav Prasil <miroslav@prasil.info>
Date: Mon, 21 May 2018 17:31:46 +0100
Subject: [PATCH] Let find_by_uuid_and_user return indirect collection (#26)

---
 src/db/models/collection.rs | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs
index e9143adb..ecc704e7 100644
--- a/src/db/models/collection.rs
+++ b/src/db/models/collection.rs
@@ -2,7 +2,7 @@ use serde_json::Value as JsonValue;
 
 use uuid::Uuid;
 
-use super::{Organization, UserOrganization};
+use super::{Organization, UserOrganization, UserOrgType};
 
 #[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
 #[table_name = "collections"]
@@ -103,11 +103,26 @@ impl Collection {
     }
 
     pub fn find_by_uuid_and_user(uuid: &str, user_uuid: &str, conn: &DbConn) -> Option<Self> {
-        users_collections::table.inner_join(collections::table)
-            .filter(users_collections::collection_uuid.eq(uuid))
-            .filter(users_collections::user_uuid.eq(user_uuid))
-            .select(collections::all_columns)
-            .first::<Self>(&**conn).ok()
+        collections::table
+        .left_join(users_collections::table.on(
+            users_collections::collection_uuid.eq(collections::uuid).and(
+                users_collections::user_uuid.eq(user_uuid)
+            )
+        ))
+        .left_join(users_organizations::table.on(
+            collections::org_uuid.eq(users_organizations::org_uuid).and(
+                users_organizations::user_uuid.eq(user_uuid)
+            )
+        ))
+        .filter(collections::uuid.eq(uuid))
+        .filter(
+            users_collections::collection_uuid.eq(uuid).or( // Directly accessed collection
+                users_organizations::access_all.eq(true).or( // access_all in Organization
+                    users_organizations::type_.le(UserOrgType::Admin as i32) // Org admin or owner
+                )
+            )
+        ).select(collections::all_columns)
+        .first::<Self>(&**conn).ok()
     }
 
     pub fn is_writable_by_user(&self, user_uuid: &str, conn: &DbConn) -> bool {