Merge branch '0000-ruby-client-config'
[arvados.git] / services / api / app / controllers / arvados / v1 / collections_controller.rb
index 9198f583d3f11db63d2359440b6a981c0bf7d746..8db93c36c2171fa310e6939ae00ddd830dd06ee7 100644 (file)
@@ -6,12 +6,8 @@ class Arvados::V1::CollectionsController < ApplicationController
     # exist) giving the current user (or specified owner_uuid)
     # permission to read it.
     owner_uuid = resource_attrs.delete(:owner_uuid) || current_user.uuid
-    owner_kind = if owner_uuid.match(/-(\w+)-/)[1] == User.uuid_prefix
-                   'arvados#user'
-                 else
-                   'arvados#group'
-                 end
     unless current_user.can? write: owner_uuid
+      logger.warn "User #{current_user.andand.uuid} tried to set collection owner_uuid to #{owner_uuid}"
       raise ArvadosModel::PermissionDeniedError
     end
     act_as_system_user do
@@ -35,9 +31,7 @@ class Arvados::V1::CollectionsController < ApplicationController
           owner_uuid: owner_uuid,
           link_class: 'permission',
           name: 'can_read',
-          head_kind: 'arvados#collection',
           head_uuid: @object.uuid,
-          tail_kind: owner_kind,
           tail_uuid: owner_uuid
         }
         ActiveRecord::Base.transaction do
@@ -50,6 +44,10 @@ class Arvados::V1::CollectionsController < ApplicationController
     show
   end
 
+  def show
+    render json: @object.as_api_response(:with_data)
+  end
+
   def collection_uuid(uuid)
     m = /([a-f0-9]{32}(\+[0-9]+)?)(\+.*)?/.match(uuid)
     if m
@@ -60,21 +58,20 @@ class Arvados::V1::CollectionsController < ApplicationController
   end
 
   def script_param_edges(visited, sp)
-    if sp and not sp.empty?
-      case sp
-      when Hash
-        sp.each do |k, v|
-          script_param_edges(visited, v)
-        end
-      when Array
-        sp.each do |v|
-          script_param_edges(visited, v)
-        end
-      else
-        m = collection_uuid(sp)
-        if m
-          generate_provenance_edges(visited, m)
-        end
+    case sp
+    when Hash
+      sp.each do |k, v|
+        script_param_edges(visited, v)
+      end
+    when Array
+      sp.each do |v|
+        script_param_edges(visited, v)
+      end
+    when String
+      return if sp.empty?
+      m = collection_uuid(sp)
+      if m
+        generate_provenance_edges(visited, m)
       end
     end
   end
@@ -87,11 +84,11 @@ class Arvados::V1::CollectionsController < ApplicationController
       return ""
     end
 
-    #puts "visiting #{uuid}"
+    logger.debug "visiting #{uuid}"
 
     if m  
       # uuid is a collection
-      Collection.where(uuid: uuid).each do |c|
+      Collection.readable_by(current_user).where(uuid: uuid).each do |c|
         visited[uuid] = c.as_api_response
         visited[uuid][:files] = []
         c.files.each do |f|
@@ -99,11 +96,11 @@ class Arvados::V1::CollectionsController < ApplicationController
         end
       end
 
-      Job.where(output: uuid).each do |job|
+      Job.readable_by(current_user).where(output: uuid).each do |job|
         generate_provenance_edges(visited, job.uuid)
       end
 
-      Job.where(log: uuid).each do |job|
+      Job.readable_by(current_user).where(log: uuid).each do |job|
         generate_provenance_edges(visited, job.uuid)
       end
       
@@ -111,7 +108,7 @@ class Arvados::V1::CollectionsController < ApplicationController
       # uuid is something else
       rsc = ArvadosModel::resource_class_for_uuid uuid
       if rsc == Job
-        Job.where(uuid: uuid).each do |job|
+        Job.readable_by(current_user).where(uuid: uuid).each do |job|
           visited[uuid] = job.as_api_response
           script_param_edges(visited, job.script_parameters)
         end
@@ -122,7 +119,9 @@ class Arvados::V1::CollectionsController < ApplicationController
       end
     end
 
-    Link.where(head_uuid: uuid, link_class: "provenance").each do |link|
+    Link.readable_by(current_user).
+      where(head_uuid: uuid, link_class: "provenance").
+      each do |link|
       visited[link.uuid] = link.as_api_response
       generate_provenance_edges(visited, link.tail_uuid)
     end
@@ -136,6 +135,65 @@ class Arvados::V1::CollectionsController < ApplicationController
     render json: visited
   end
 
+  def generate_used_by_edges(visited, uuid)
+    m = collection_uuid(uuid)
+    uuid = m if m
+
+    if not uuid or uuid.empty? or visited[uuid]
+      return ""
+    end
+
+    logger.debug "visiting #{uuid}"
+
+    if m  
+      # uuid is a collection
+      Collection.readable_by(current_user).where(uuid: uuid).each do |c|
+        visited[uuid] = c.as_api_response
+        visited[uuid][:files] = []
+        c.files.each do |f|
+          visited[uuid][:files] << f
+        end
+      end
+
+      if uuid == "d41d8cd98f00b204e9800998ecf8427e+0"
+        # special case for empty collection
+        return
+      end
+
+      Job.readable_by(current_user).where(["jobs.script_parameters like ?", "%#{uuid}%"]).each do |job|
+        generate_used_by_edges(visited, job.uuid)
+      end
+      
+    else
+      # uuid is something else
+      rsc = ArvadosModel::resource_class_for_uuid uuid
+      if rsc == Job
+        Job.readable_by(current_user).where(uuid: uuid).each do |job|
+          visited[uuid] = job.as_api_response
+          generate_used_by_edges(visited, job.output)
+        end
+      elsif rsc != nil
+        rsc.where(uuid: uuid).each do |r|
+          visited[uuid] = r.as_api_response
+        end
+      end
+    end
+
+    Link.readable_by(current_user).
+      where(tail_uuid: uuid, link_class: "provenance").
+      each do |link|
+      visited[link.uuid] = link.as_api_response
+      generate_used_by_edges(visited, link.head_uuid)
+    end
+
+    #puts "finished #{uuid}"
+  end
+
+  def used_by
+    visited = {}
+    generate_used_by_edges(visited, @object[:uuid])
+    render json: visited
+  end
 
   protected
   def find_object_by_uuid