9799: Permit read access to containers via container requests. Move Log- and Containe...
authorTom Clegg <tom@curoverse.com>
Sat, 27 Aug 2016 01:45:17 +0000 (21:45 -0400)
committerTom Clegg <tom@curoverse.com>
Wed, 31 Aug 2016 02:01:53 +0000 (22:01 -0400)
services/api/app/models/arvados_model.rb
services/api/app/models/container.rb
services/api/app/models/log.rb
services/api/lib/eventbus.rb

index 16f03430f718fc471a6f47529a4504ac745f7e22..304be0bfb168d94059ddcfb681cbfda29152ffbc 100644 (file)
@@ -228,15 +228,6 @@ class ArvadosModel < ActiveRecord::Base
       sql_params += [user_uuids, user_uuids]
     end
 
-    if sql_table == "logs" and users_list.any?
-      # Link head points to the object described by this row
-      sql_conds += ["#{sql_table}.object_uuid IN #{permitted_uuids}"]
-
-      # This object described by this row is owned by this user, or owned by a group readable by this user
-      sql_conds += ["#{sql_table}.object_owner_uuid in (?)"]
-      sql_params += [uuid_list]
-    end
-
     # Link head points to this row, or to the owner of this row (the
     # thing to be read)
     #
index 4c770083786934abdafe9461f51ee03646396415..ae4d9837fe79bc819da052fe9e266e86488a18a4 100644 (file)
@@ -76,6 +76,17 @@ class Container < ArvadosModel
     end
   end
 
+  def self.readable_by *users_list
+    if users_list.select { |u| u.is_admin }.any?
+      return self
+    end
+    user_uuids = users_list.map { |u| u.uuid }
+    uuid_list = user_uuids + users_list.flat_map { |u| u.groups_i_can(:read) }
+    permitted_uuids = "(SELECT head_uuid FROM links WHERE link_class='permission' AND tail_uuid IN (?))"
+    joins(:container_requests).where("container_requests.uuid IN #{permitted_uuids} OR container_requests.owner_uuid IN (?)",
+                                     uuid_list, uuid_list)
+  end
+
   protected
 
   def fill_field_defaults
index b10a491163dc3c905c8ec52e120a6f263904457e..7a8b50a6c416de35c79b0cf7a280fd9dc74d819a 100644 (file)
@@ -53,6 +53,18 @@ class Log < ArvadosModel
     self
   end
 
+  def self.readable_by *users_list
+    if users_list.select { |u| u.is_admin }.any?
+      return self
+    end
+    user_uuids = users_list.map { |u| u.uuid }
+    uuid_list = user_uuids + users_list.flat_map { |u| u.groups_i_can(:read) }
+    permitted_uuids = "(SELECT head_uuid FROM links WHERE link_class='permission' AND tail_uuid IN (?))"
+    joins("LEFT JOIN container_requests ON container_requests.container_uuid=logs.object_uuid").
+      where("logs.object_uuid IN #{permitted_uuids} OR container_requests.uuid IN (?)  OR container_requests.owner_uuid IN (?) OR logs.object_uuid IN (?) OR logs.object_owner_uuid IN (?)",
+            uuid_list, uuid_list, uuid_list, uuid_list, uuid_list)
+  end
+
   protected
 
   def permission_to_create
index e7f2bb13108e327d533a673caae31bdb8e7f09e6..16bb030941c3033ebf32cb972a645eb821a063d3 100644 (file)
@@ -143,7 +143,7 @@ class EventBus
         #
         # Note: find_each implies order('id asc'), which is what we
         # want.
-        logs.select(:id).find_each do |l|
+        logs.select('logs.id').find_each do |l|
           if not ws.sent_ids.include?(l.id)
             # only send if not a duplicate
             ws.send(Log.find(l.id).as_api_response.to_json)