Merge branch '2388-bogus-token-error-page'
[arvados.git] / services / api / app / controllers / application_controller.rb
index a47bfb57a572217a30dca8effe49b332ceee7f2e..4b13fca1de45757292592e80152700efe8c83954 100644 (file)
@@ -1,5 +1,6 @@
 class ApplicationController < ActionController::Base
   include CurrentApiClient
+  include ThemesForRails::ActionController
 
   respond_to :json
   protect_from_forgery
@@ -20,6 +21,8 @@ class ApplicationController < ActionController::Base
                                                    :render_error,
                                                    :render_not_found]
 
+  theme :select_theme
+
   attr_accessor :resource_attrs
 
   def index
@@ -36,22 +39,16 @@ class ApplicationController < ActionController::Base
 
   def create
     @object = model_class.new resource_attrs
-    if @object.save
-      show
-    else
-      raise "Save failed"
-    end
+    @object.save!
+    show
   end
 
   def update
     attrs_to_update = resource_attrs.reject { |k,v|
       [:kind, :etag, :href].index k
     }
-    if @object.update_attributes attrs_to_update
-      show
-    else
-      raise "Update failed"
-    end
+    @object.update_attributes! attrs_to_update
+    show
   end
 
   def destroy
@@ -124,12 +121,14 @@ class ApplicationController < ActionController::Base
   end
 
   def load_filters_param
+    @filters ||= []
     if params[:filters].is_a? Array
-      @filters = params[:filters]
-    elsif params[:filters].is_a? String
+      @filters += params[:filters]
+    elsif params[:filters].is_a? String and !params[:filters].empty?
       begin
-        @filters = Oj.load params[:filters]
-        raise unless @filters.is_a? Array
+        f = Oj.load params[:filters]
+        raise unless f.is_a? Array
+        @filters += f
       rescue
         raise ArgumentError.new("Could not parse \"filters\" param as an array")
       end
@@ -146,7 +145,7 @@ class ApplicationController < ActionController::Base
       cond_out = []
       param_out = []
       @filters.each do |attr, operator, operand|
-        if !model_class.searchable_columns.index attr.to_s
+        if !model_class.searchable_columns(operator).index attr.to_s
           raise ArgumentError.new("Invalid attribute '#{attr}' in condition")
         end
         case operator.downcase
@@ -166,6 +165,19 @@ class ApplicationController < ActionController::Base
             cond_out << "#{table_name}.#{attr} IN (?)"
             param_out << operand
           end
+        when 'is_a'
+          operand = [operand] unless operand.is_a? Array
+          cond = []
+          operand.each do |op|
+              cl = ArvadosModel::kind_class op
+              if cl
+                cond << "#{table_name}.#{attr} like ?"
+                param_out << cl.uuid_like_pattern
+              else
+                cond << "1=0"
+              end
+          end
+          cond_out << cond.join(' OR ')
         end
       end
       if cond_out.any?
@@ -175,13 +187,12 @@ class ApplicationController < ActionController::Base
     if @where.is_a? Hash and @where.any?
       conditions = ['1=1']
       @where.each do |attr,value|
-        if attr == :any
+        if attr.to_s == 'any'
           if value.is_a?(Array) and
               value.length == 2 and
-              value[0] == 'contains' and
-              model_class.columns.collect(&:name).index('name') then
+              value[0] == 'contains' then
             ilikes = []
-            model_class.searchable_columns.each do |column|
+            model_class.searchable_columns('ilike').each do |column|
               ilikes << "#{table_name}.#{column} ilike ?"
               conditions << "%#{value[1]}%"
             end
@@ -222,15 +233,31 @@ class ApplicationController < ActionController::Base
           where(*conditions)
       end
     end
+
     if params[:limit]
       begin
-        @objects = @objects.limit(params[:limit].to_i)
+        @limit = params[:limit].to_i
       rescue
         raise ArgumentError.new("Invalid value for limit parameter")
       end
     else
-      @objects = @objects.limit(100)
+      @limit = 100
     end
+    @objects = @objects.limit(@limit)
+
+    orders = []
+
+    if params[:offset]
+      begin
+        @objects = @objects.offset(params[:offset].to_i)
+        @offset = params[:offset].to_i
+      rescue
+        raise ArgumentError.new("Invalid value for limit parameter")
+      end
+    else
+      @offset = 0
+    end
+
     orders = []
     if params[:order]
       params[:order].split(',').each do |order|
@@ -325,6 +352,9 @@ class ApplicationController < ActionController::Base
           session[:api_client_authorization_id] = api_client_auth.id
           user = api_client_auth.user
           api_client = api_client_auth.api_client
+        else
+          # Token seems valid, but points to a non-existent (deleted?) user.
+          api_client_auth = nil
         end
       elsif session[:user_id]
         user = User.find(session[:user_id]) rescue nil
@@ -413,12 +443,14 @@ class ApplicationController < ActionController::Base
       :kind  => "arvados##{(@response_resource_name || resource_name).camelize(:lower)}List",
       :etag => "",
       :self_link => "",
-      :next_page_token => "",
-      :next_link => "",
+      :offset => @offset,
+      :limit => @limit,
       :items => @objects.as_api_response(nil)
     }
     if @objects.respond_to? :except
-      @object_list[:items_available] = @objects.except(:limit).count
+      @object_list[:items_available] = @objects.
+        except(:limit).except(:offset).
+        count(:id, distinct: true)
     end
     render json: @object_list
   end
@@ -441,7 +473,7 @@ class ApplicationController < ActionController::Base
       order: { type: 'string', required: false }
     }
   end
-  
+
   def client_accepts_plain_text_stream
     (request.headers['Accept'].split(' ') &
      ['text/plain', '*/*']).count > 0
@@ -460,4 +492,8 @@ class ApplicationController < ActionController::Base
     end
     super *opts
   end
+
+  def select_theme
+    return Rails.configuration.arvados_theme
+  end
 end