10028: when an "is_a" filter is used while fetching contents, do not search in all...
[arvados.git] / services / api / app / controllers / arvados / v1 / groups_controller.rb
index eae6dca8c0332ae820fbedbb3965f3112453dfb9..d6adbf08516a7c2c199cb240017b5e64ede195be 100644 (file)
@@ -61,10 +61,34 @@ class Arvados::V1::GroupsController < ApplicationController
     request_orders = @orders.clone
     @orders = []
 
-    [Group,
-     Job, PipelineInstance, PipelineTemplate,
+    request_filters = @filters
+
+    klasses = [Group,
+     Job, PipelineInstance, PipelineTemplate, ContainerRequest, Workflow,
      Collection,
-     Human, Specimen, Trait].each do |klass|
+     Human, Specimen, Trait]
+
+    table_names = klasses.map(&:table_name)
+    request_filters.each do |col, op, val|
+      if col.index('.') && !table_names.include?(col.split('.', 2)[0])
+        raise ArgumentError.new("Invalid attribute '#{col}' in filter")
+      end
+    end
+
+    wanted_klasses = []
+    request_filters.each do |col,op,val|
+      if op == 'is_a'
+        (val.is_a?(Array) ? val : [val]).each do |type|
+          type = type.split('#')[-1]
+          type[0] = type[0].capitalize
+          wanted_klasses << type
+        end
+      end
+    end
+
+    klasses.each do |klass|
+      next if wanted_klasses.any? and !wanted_klasses.include?(klass.to_s)
+
       # If the currently requested orders specifically match the
       # table_name for the current klass, apply that order.
       # Otherwise, order by recency.
@@ -81,6 +105,16 @@ class Arvados::V1::GroupsController < ApplicationController
         where_conds[:group_class] = "project"
       end
 
+      @filters = request_filters.map do |col, op, val|
+        if !col.index('.')
+          [col, op, val]
+        elsif (col = col.split('.', 2))[0] == klass.table_name
+          [col[1], op, val]
+        else
+          nil
+        end
+      end.compact
+
       @objects = klass.readable_by(*@read_users).
         order(request_order).where(where_conds)
       @limit = limit_all - all_objects.count