class ApplicationController < ActionController::Base
+ include ArvadosApiClientHelper
+
respond_to :html, :json, :js
protect_from_forgery
+
+ ERROR_ACTIONS = [:render_error, :render_not_found]
+
around_filter :thread_clear
- around_filter :thread_with_mandatory_api_token, :except => [:render_exception, :render_not_found]
+ around_filter :thread_with_mandatory_api_token, except: ERROR_ACTIONS
around_filter :thread_with_optional_api_token
- before_filter :find_object_by_uuid, :except => [:index, :render_exception, :render_not_found]
- before_filter :check_user_agreements, :except => [:render_exception, :render_not_found]
- before_filter :check_user_notifications, :except => [:render_exception, :render_not_found]
+ before_filter :check_user_agreements, except: ERROR_ACTIONS
+ before_filter :check_user_notifications, except: ERROR_ACTIONS
+ before_filter :find_object_by_uuid, except: [:index] + ERROR_ACTIONS
theme :select_theme
begin
self.render_error status: 404
end
+ def render_index
+ respond_to do |f|
+ f.json { render json: @objects }
+ f.html {
+ if params['tab_pane']
+ comparable = self.respond_to? :compare
+ render(partial: 'show_' + params['tab_pane'].downcase,
+ locals: { comparable: comparable, objects: @objects })
+ else
+ render
+ end
+ }
+ f.js { render }
+ end
+ end
+
def index
+ @limit ||= 200
if params[:limit]
- limit = params[:limit].to_i
- else
- limit = 200
+ @limit = params[:limit].to_i
end
+ @offset ||= 0
if params[:offset]
- offset = params[:offset].to_i
- else
- offset = 0
+ @offset = params[:offset].to_i
end
- @objects ||= model_class.limit(limit).offset(offset).all
- respond_to do |f|
- f.json { render json: @objects }
- f.html { render }
- f.js { render }
+ @filters ||= []
+ if params[:filters]
+ filters = params[:filters]
+ if filters.is_a? String
+ filters = Oj.load filters
+ end
+ @filters += filters
end
+
+ @objects ||= model_class
+ @objects = @objects.filter(@filters).limit(@limit).offset(@offset).all
+ render_index
end
def show
return render_not_found("object not found")
end
respond_to do |f|
- f.json { render json: @object }
+ f.json { render json: @object.attributes.merge(href: url_for(@object)) }
f.html {
- if request.method == 'GET'
- render
+ if params['tab_pane']
+ comparable = self.respond_to? :compare
+ render(partial: 'show_' + params['tab_pane'].downcase,
+ locals: { comparable: comparable, objects: @objects })
else
- redirect_to params[:return_to] || @object
+ if request.method == 'GET'
+ render
+ else
+ redirect_to params[:return_to] || @object
+ end
end
}
f.js { render }
end
def update
- updates = params[@object.class.to_s.underscore.singularize.to_sym]
- updates.keys.each do |attr|
+ @updates ||= params[@object.class.to_s.underscore.singularize.to_sym]
+ @updates.keys.each do |attr|
if @object.send(attr).is_a? Hash
- if updates[attr].is_a? String
- updates[attr] = Oj.load updates[attr]
+ if @updates[attr].is_a? String
+ @updates[attr] = Oj.load @updates[attr]
end
if params[:merge] || params["merge_#{attr}".to_sym]
# Merge provided Hash with current Hash, instead of
# replacing.
- updates[attr] = @object.send(attr).with_indifferent_access.
- deep_merge(updates[attr].with_indifferent_access)
+ @updates[attr] = @object.send(attr).with_indifferent_access.
+ deep_merge(@updates[attr].with_indifferent_access)
end
end
end
- if @object.update_attributes updates
+ if @object.update_attributes @updates
show
else
self.render_error status: 422
end
def create
- @object ||= model_class.new params[model_class.to_s.underscore.singularize]
- @object.save!
-
- respond_to do |f|
- f.json { render json: @object }
- f.html {
- redirect_to(params[:return_to] || @object)
- }
- f.js { render }
+ @new_resource_attrs ||= params[model_class.to_s.underscore.singularize]
+ @new_resource_attrs ||= {}
+ @new_resource_attrs.reject! { |k,v| k.to_s == 'uuid' }
+ @object ||= model_class.new @new_resource_attrs, params["options"]
+ if @object.save
+ respond_to do |f|
+ f.json { render json: @object.attributes.merge(href: url_for(@object)) }
+ f.html {
+ redirect_to @object
+ }
+ f.js { render }
+ end
+ else
+ self.render_error status: 422
end
end
end
def current_user
+ return Thread.current[:user] if Thread.current[:user]
+
if Thread.current[:arvados_api_token]
- Thread.current[:user] ||= User.current
+ if session[:user]
+ if session[:user][:is_active] != true
+ Thread.current[:user] = User.current
+ else
+ Thread.current[:user] = User.new(session[:user])
+ end
+ else
+ Thread.current[:user] = User.current
+ end
else
logger.error "No API token in Thread"
return nil
end
protected
-
+
+ def redirect_to_login
+ respond_to do |f|
+ f.html {
+ if request.method == 'GET'
+ redirect_to arvados_api_client.arvados_login_url(return_to: request.url)
+ else
+ flash[:error] = "Either you are not logged in, or your session has timed out. I can't automatically log you in and re-attempt this request."
+ redirect_to :back
+ end
+ }
+ f.json {
+ @errors = ['You do not seem to be logged in. You did not supply an API token with this request, and your session (if any) has timed out.']
+ self.render_error status: 422
+ }
+ end
+ false # For convenience to return from callbacks
+ end
+
+ def using_specific_api_token(api_token)
+ start_values = {}
+ [:arvados_api_token, :user].each do |key|
+ start_values[key] = Thread.current[key]
+ end
+ Thread.current[:arvados_api_token] = api_token
+ Thread.current[:user] = nil
+ begin
+ yield
+ ensure
+ start_values.each_key { |key| Thread.current[key] = start_values[key] }
+ end
+ end
+
def find_object_by_uuid
if params[:id] and params[:id].match /\D/
params[:uuid] = params.delete :id
end
- if params[:uuid].is_a? String
- @object = model_class.find(params[:uuid])
+ if not model_class
+ @object = nil
+ elsif params[:uuid].is_a? String
+ if params[:uuid].empty?
+ @object = nil
+ else
+ @object = model_class.find(params[:uuid])
+ end
else
@object = model_class.where(uuid: params[:uuid]).first
end
# call to verify its authenticity.
if verify_api_token
session[:arvados_api_token] = params[:api_token]
+ u = User.current
+ session[:user] = {
+ email: u.email,
+ first_name: u.first_name,
+ last_name: u.last_name,
+ is_active: u.is_active,
+ is_admin: u.is_admin,
+ prefs: u.prefs
+ }
if !request.format.json? and request.method == 'GET'
# Repeat this request with api_token in the (new) session
# cookie instead of the query string. This prevents API
end
if try_redirect_to_login
unless login_optional
- respond_to do |f|
- f.html {
- if request.method == 'GET'
- redirect_to $arvados_api_client.arvados_login_url(return_to: request.url)
- else
- flash[:error] = "Either you are not logged in, or your session has timed out. I can't automatically log you in and re-attempt this request."
- redirect_to :back
- end
- }
- f.json {
- @errors = ['You do not seem to be logged in. You did not supply an API token with this request, and your session (if any) has timed out.']
- self.render_error status: 422
- }
- end
+ redirect_to_login
else
# login is optional for this route so go on to the regular controller
Thread.current[:arvados_api_token] = nil
}
def check_user_notifications
+ return if params['tab_pane']
+
@notification_count = 0
@notifications = []
@notification_count = ''
end
end
+
+ helper_method :my_folders
+ def my_folders
+ return @my_folders if @my_folders
+ @my_folders = []
+ root_of = {}
+ Group.filter([['group_class','=','folder']]).each do |g|
+ root_of[g.uuid] = g.owner_uuid
+ @my_folders << g
+ end
+ done = false
+ while not done
+ done = true
+ root_of = root_of.each_with_object({}) do |(child, parent), h|
+ if root_of[parent]
+ h[child] = root_of[parent]
+ done = false
+ else
+ h[child] = parent
+ end
+ end
+ end
+ @my_folders = @my_folders.select do |g|
+ root_of[g.uuid] == current_user.uuid
+ end
+ end
end