Moves API token authentication from ApplicationController into ArvadosApiToken Rack...
[arvados.git] / services / api / app / controllers / application_controller.rb
index ab6ec9ce1401df7a7c7bb2791a563b26c379337d..033eccda92644483c80e928ccca982527833a9dc 100644 (file)
@@ -1,9 +1,9 @@
 class ApplicationController < ActionController::Base
   include CurrentApiClient
+  include ThemesForRails::ActionController
 
   respond_to :json
   protect_from_forgery
-  around_filter :thread_with_auth_info, :except => [:render_error, :render_not_found]
 
   before_filter :remote_ip
   before_filter :require_auth_scope_all, :except => :render_not_found
@@ -20,6 +20,8 @@ class ApplicationController < ActionController::Base
                                                    :render_error,
                                                    :render_not_found]
 
+  theme :select_theme
+
   attr_accessor :resource_attrs
 
   def index
@@ -36,22 +38,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 +120,14 @@ class ApplicationController < ActionController::Base
   end
 
   def load_filters_param
+    @filters ||= []
     if params[:filters].is_a? Array
-      @filters = params[:filters]
+      @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
@@ -166,6 +164,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?
@@ -244,7 +255,7 @@ class ApplicationController < ActionController::Base
       end
     else
       @offset = 0
-    end      
+    end
 
     orders = []
     if params[:order]
@@ -318,60 +329,6 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  def thread_with_auth_info
-    Thread.current[:request_starttime] = Time.now
-    Thread.current[:api_url_base] = root_url.sub(/\/$/,'') + '/arvados/v1'
-    begin
-      user = nil
-      api_client = nil
-      api_client_auth = nil
-      supplied_token =
-        params[:api_token] ||
-        params[:oauth_token] ||
-        request.headers["Authorization"].andand.match(/OAuth2 ([a-z0-9]+)/).andand[1]
-      if supplied_token
-        api_client_auth = ApiClientAuthorization.
-          includes(:api_client, :user).
-          where('api_token=? and (expires_at is null or expires_at > CURRENT_TIMESTAMP)', supplied_token).
-          first
-        if api_client_auth.andand.user
-          session[:user_id] = api_client_auth.user.id
-          session[:api_client_uuid] = api_client_auth.api_client.andand.uuid
-          session[:api_client_authorization_id] = api_client_auth.id
-          user = api_client_auth.user
-          api_client = api_client_auth.api_client
-        end
-      elsif session[:user_id]
-        user = User.find(session[:user_id]) rescue nil
-        api_client = ApiClient.
-          where('uuid=?',session[:api_client_uuid]).
-          first rescue nil
-        if session[:api_client_authorization_id] then
-          api_client_auth = ApiClientAuthorization.
-            find session[:api_client_authorization_id]
-        end
-      end
-      Thread.current[:api_client_ip_address] = remote_ip
-      Thread.current[:api_client_authorization] = api_client_auth
-      Thread.current[:api_client_uuid] = api_client.andand.uuid
-      Thread.current[:api_client] = api_client
-      Thread.current[:user] = user
-      if api_client_auth
-        api_client_auth.last_used_at = Time.now
-        api_client_auth.last_used_by_ip_address = remote_ip
-        api_client_auth.save validate: false
-      end
-      yield
-    ensure
-      Thread.current[:api_client_ip_address] = nil
-      Thread.current[:api_client_authorization] = nil
-      Thread.current[:api_client_uuid] = nil
-      Thread.current[:api_client] = nil
-      Thread.current[:user] = nil
-    end
-  end
-  # /Authentication
-
   def model_class
     controller_name.classify.constantize
   end
@@ -433,7 +390,9 @@ class ApplicationController < ActionController::Base
       :items => @objects.as_api_response(nil)
     }
     if @objects.respond_to? :except
-      @object_list[:items_available] = @objects.except(:limit).except(:offset).count
+      @object_list[:items_available] = @objects.
+        except(:limit).except(:offset).
+        count(:id, distinct: true)
     end
     render json: @object_list
   end
@@ -456,7 +415,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
@@ -475,4 +434,8 @@ class ApplicationController < ActionController::Base
     end
     super *opts
   end
+
+  def select_theme
+    return Rails.configuration.arvados_theme
+  end
 end