Merge remote-tracking branch 'origin/master' into 2035-arv-mount-tags-folders
authorPeter Amstutz <peter.amstutz@curoverse.com>
Thu, 1 May 2014 20:26:09 +0000 (16:26 -0400)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Thu, 1 May 2014 20:26:09 +0000 (16:26 -0400)
Conflicts:
services/api/app/controllers/application_controller.rb

1  2 
services/api/app/controllers/application_controller.rb
services/api/app/controllers/arvados/v1/schema_controller.rb
services/api/lib/load_param.rb

index 8501c8690f9159d6ca89802bc5724052ca499b33,4b5a27d99621d4d25e4c66fcb30581fadace4186..30027c8c78c9db764bb1744541cb5bfd563bcf05
@@@ -1,32 -1,25 +1,39 @@@
 +module ApiTemplateOverride
 +  def allowed_to_render?(fieldset, field, model, options)
 +    if options[:select]
 +      return options[:select].include? field.to_s
 +    end
 +    super
 +  end
 +end
 +
 +class ActsAsApi::ApiTemplate
 +  prepend ApiTemplateOverride
 +end
 +
+ require 'load_param'
+ require 'record_filters'
  class ApplicationController < ActionController::Base
    include CurrentApiClient
    include ThemesForRails::ActionController
+   include LoadParam
+   include RecordFilters
+   ERROR_ACTIONS = [:render_error, :render_not_found]
  
 +
    respond_to :json
    protect_from_forgery
-   around_filter :thread_with_auth_info, :except => [:render_error, :render_not_found]
  
+   before_filter :respond_with_json_by_default
    before_filter :remote_ip
-   before_filter :require_auth_scope, :except => :render_not_found
-   before_filter :catch_redirect_hint
+   before_filter :load_read_auths
+   before_filter :require_auth_scope, except: ERROR_ACTIONS
  
-   before_filter :find_object_by_uuid, :except => [:index, :create,
-                                                   :render_error,
-                                                   :render_not_found]
+   before_filter :catch_redirect_hint
+   before_filter(:find_object_by_uuid,
+                 except: [:index, :create] + ERROR_ACTIONS)
    before_filter :load_limit_offset_order_params, only: [:index, :owned_items]
    before_filter :load_where_param, only: [:index, :owned_items]
    before_filter :load_filters_param, only: [:index, :owned_items]
  
    attr_accessor :resource_attrs
  
-   DEFAULT_LIMIT = 100
    def index
 -    @objects.uniq!(&:id)
 +    @objects.uniq!(&:id) if @select.nil? or @select.include? "id"
      if params[:eager] and params[:eager] != '0' and params[:eager] != 0 and params[:eager] != ''
        @objects.each(&:eager_load_associations)
      end
index 0000000000000000000000000000000000000000,e01063d1530a89a8e5918510a01a0523a5fc9d8f..14dbf1eb1f2be31d9d62935ef124009f79739c6c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,88 +1,105 @@@
+ # Mixin module for reading out query parameters from request params.
+ #
+ # Expects:
+ #   +params+ Hash
+ # Sets:
+ #   @where, @filters, @limit, @offset, @orders
+ module LoadParam
+   # Default limit on number of rows to return in a single query.
+   DEFAULT_LIMIT = 100
+   # Load params[:where] into @where
+   def load_where_param
+     if params[:where].nil? or params[:where] == ""
+       @where = {}
+     elsif params[:where].is_a? Hash
+       @where = params[:where]
+     elsif params[:where].is_a? String
+       begin
+         @where = Oj.load(params[:where])
+         raise unless @where.is_a? Hash
+       rescue
+         raise ArgumentError.new("Could not parse \"where\" param as an object")
+       end
+     end
+     @where = @where.with_indifferent_access
+   end
+   # Load params[:filters] into @filters
+   def load_filters_param
+     @filters ||= []
+     if params[:filters].is_a? Array
+       @filters += params[:filters]
+     elsif params[:filters].is_a? String and !params[:filters].empty?
+       begin
+         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
+     end
+   end
+   def default_orders
+     ["#{table_name}.modified_at desc"]
+   end
+   # Load params[:limit], params[:offset] and params[:order]
+   # into @limit, @offset, @orders
+   def load_limit_offset_order_params
+     if params[:limit]
+       unless params[:limit].to_s.match(/^\d+$/)
+         raise ArgumentError.new("Invalid value for limit parameter")
+       end
+       @limit = params[:limit].to_i
+     else
+       @limit = DEFAULT_LIMIT
+     end
+     if params[:offset]
+       unless params[:offset].to_s.match(/^\d+$/)
+         raise ArgumentError.new("Invalid value for offset parameter")
+       end
+       @offset = params[:offset].to_i
+     else
+       @offset = 0
+     end
+     @orders = []
+     if params[:order]
+       params[:order].split(',').each do |order|
+         attr, direction = order.strip.split " "
+         direction ||= 'asc'
+         if attr.match /^[a-z][_a-z0-9]+$/ and
+             model_class.columns.collect(&:name).index(attr) and
+             ['asc','desc'].index direction.downcase
+           @orders << "#{table_name}.#{attr} #{direction.downcase}"
+         end
+       end
+     end
+     if @orders.empty?
+       @orders << default_orders
+     end
++
++    case params[:select]
++    when Array
++      @select = params[:select]
++    when String
++      begin
++        @select = Oj.load params[:select]
++        raise unless @select.is_a? Array
++      rescue
++        raise ArgumentError.new("Could not parse \"select\" param as an array")
++      end
++    end
++
++    if params[:distinct].is_a? String
++      @distinct = params[:distinct]
++      @orders.select! { |o| @select.include? o } if @select
++    end
+   end
+ end