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
before_filter :catch_redirect_hint
before_filter :load_where_param, :only => :index
+ before_filter :load_filters_param, :only => :index
before_filter :find_objects_for_index, :only => :index
before_filter :find_object_by_uuid, :except => [:index, :create,
:render_error,
:render_error,
:render_not_found]
+ theme :select_theme
+
attr_accessor :resource_attrs
def index
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
@where = params[:where]
elsif params[:where].is_a? String
begin
- @where = Oj.load(params[:where], symbol_keys: true)
+ @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
+
+ 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 find_objects_for_index
@objects ||= model_class.readable_by(current_user)
- if !@where.empty?
+ apply_where_limit_order_params
+ end
+
+ def apply_where_limit_order_params
+ if @filters.is_a? Array and @filters.any?
+ cond_out = []
+ param_out = []
+ @filters.each do |attr, operator, operand|
+ if !model_class.searchable_columns(operator).index attr.to_s
+ raise ArgumentError.new("Invalid attribute '#{attr}' in condition")
+ end
+ case operator.downcase
+ when '=', '<', '<=', '>', '>=', 'like'
+ if operand.is_a? String
+ cond_out << "#{table_name}.#{attr} #{operator} ?"
+ if (# any operator that operates on value rather than
+ # representation:
+ operator.match(/[<=>]/) and
+ model_class.attribute_column(attr).type == :datetime)
+ operand = Time.parse operand
+ end
+ param_out << operand
+ end
+ when 'in'
+ if operand.is_a? Array
+ 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?
+ @objects = @objects.where(cond_out.join(' AND '), *param_out)
+ end
+ end
+ 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
end
else
@offset = 0
- end
+ end
orders = []
if params[:order]
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
: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
def self._index_requires_parameters
{
+ filters: { type: 'array', required: false },
where: { type: 'object', required: false },
order: { type: 'string', required: false }
}
end
-
+
def client_accepts_plain_text_stream
(request.headers['Accept'].split(' ') &
['text/plain', '*/*']).count > 0
end
super *opts
end
+
+ def select_theme
+ return Rails.configuration.arvados_theme
+ end
end