X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/ab3f9742f002e3af4339c17eede2b6ee99df83b2..3c6f8001fb5d63ef92da36e662ac58396f18a9d0:/apps/workbench/app/controllers/application_controller.rb diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb index 5b8276a9e0..e94428e92d 100644 --- a/apps/workbench/app/controllers/application_controller.rb +++ b/apps/workbench/app/controllers/application_controller.rb @@ -1,8 +1,13 @@ class ApplicationController < ActionController::Base + respond_to :html, :json, :js protect_from_forgery around_filter :thread_clear - around_filter :thread_with_api_token, :except => [:render_exception, :render_not_found] + around_filter :thread_with_mandatory_api_token, :except => [:render_exception, :render_not_found] + 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] + theme :select_theme begin rescue_from Exception, @@ -25,8 +30,12 @@ class ApplicationController < ActionController::Base def render_error(opts) respond_to do |f| - f.html { render opts.merge(controller: 'application', action: 'error') } + # json must come before html here, so it gets used as the + # default format when js is requested by the client. This lets + # ajax:error callback parse the response correctly, even though + # the browser can't. f.json { render opts.merge(json: {success: false, errors: @errors}) } + f.html { render opts.merge(controller: 'application', action: 'error') } end end @@ -36,7 +45,7 @@ class ApplicationController < ActionController::Base if @object.andand.errors.andand.full_messages.andand.any? @errors = @object.errors.full_messages else - @errors = [e.inspect] + @errors = [e.to_s] end self.render_error status: 422 end @@ -47,12 +56,12 @@ class ApplicationController < ActionController::Base self.render_error status: 404 end - def index - @objects ||= model_class.all + @objects ||= model_class.limit(200).all respond_to do |f| f.json { render json: @objects } f.html { render } + f.js { render } end end @@ -69,6 +78,7 @@ class ApplicationController < ActionController::Base redirect_to params[:return_to] || @object end } + f.js { render } end end @@ -97,14 +107,26 @@ class ApplicationController < ActionController::Base end def create - @object ||= model_class.new params[model_class.to_s.singularize.to_sym] + @object ||= model_class.new params[model_class.to_s.underscore.singularize] @object.save! - redirect_to(params[:return_to] || @object) + respond_to do |f| + f.json { render json: @object } + f.html { + redirect_to(params[:return_to] || @object) + } + f.js { render } + end end def destroy if @object.destroy - redirect_to(params[:return_to] || :back) + respond_to do |f| + f.json { render json: @object } + f.html { + redirect_to(params[:return_to] || :back) + } + f.js { render } + end else self.render_error status: 422 end @@ -123,6 +145,19 @@ class ApplicationController < ActionController::Base controller_name.classify.constantize end + def breadcrumb_page_name + (@breadcrumb_page_name || + (@object.friendly_link_name if @object.respond_to? :friendly_link_name)) + end + + def index_pane_list + %w(Recent) + end + + def show_pane_list + %w(Attributes Metadata JSON API) + end + protected def find_object_by_uuid @@ -139,7 +174,9 @@ class ApplicationController < ActionController::Base def thread_clear Thread.current[:arvados_api_token] = nil Thread.current[:user] = nil + Rails.cache.delete_matched(/^request_#{Thread.current.object_id}_/) yield + Rails.cache.delete_matched(/^request_#{Thread.current.object_id}_/) end def thread_with_api_token(login_optional = false) @@ -207,12 +244,25 @@ class ApplicationController < ActionController::Base end end - def thread_with_optional_api_token - thread_with_api_token(true) do + def thread_with_mandatory_api_token + thread_with_api_token do yield end end + # This runs after thread_with_mandatory_api_token in the filter chain. + def thread_with_optional_api_token + if Thread.current[:arvados_api_token] + # We are already inside thread_with_mandatory_api_token. + yield + else + # We skipped thread_with_mandatory_api_token. Use the optional version. + thread_with_api_token(true) do + yield + end + end + end + def verify_api_token begin Link.where(uuid: 'just-verifying-my-api-token') @@ -228,4 +278,90 @@ class ApplicationController < ActionController::Base self.render_error status: 401 end end + + def check_user_agreements + if current_user && !current_user.is_active && current_user.is_invited + signatures = UserAgreement.signatures + @signed_ua_uuids = UserAgreement.signatures.map &:head_uuid + @required_user_agreements = UserAgreement.all.map do |ua| + if not @signed_ua_uuids.index ua.uuid + Collection.find(ua.uuid) + end + end.compact + if @required_user_agreements.empty? + # No agreements to sign. Perhaps we just need to ask? + current_user.activate + if !current_user.is_active + logger.warn "#{current_user.uuid.inspect}: " + + "No user agreements to sign, but activate failed!" + end + end + if !current_user.is_active + render 'user_agreements/index' + end + end + true + end + + def select_theme + return Rails.configuration.arvados_theme + end + + @@notification_tests = [] + + @@notification_tests.push lambda { |controller, current_user| + AuthorizedKey.limit(1).where(authorized_user_uuid: current_user.uuid).each do + return nil + end + return lambda { |view| + view.render partial: 'notifications/ssh_key_notification' + } + } + + @@notification_tests.push lambda { |controller, current_user| + Job.limit(1).where(created_by: current_user.uuid).each do + return nil + end + return lambda { |view| + view.render partial: 'notifications/jobs_notification' + } + } + + @@notification_tests.push lambda { |controller, current_user| + Collection.limit(1).where(created_by: current_user.uuid).each do + return nil + end + return lambda { |view| + view.render partial: 'notifications/collections_notification' + } + } + + @@notification_tests.push lambda { |controller, current_user| + PipelineInstance.limit(1).where(created_by: current_user.uuid).each do + return nil + end + return lambda { |view| + view.render partial: 'notifications/pipelines_notification' + } + } + + def check_user_notifications + @notification_count = 0 + @notifications = [] + + if current_user + @showallalerts = false + @@notification_tests.each do |t| + a = t.call(self, current_user) + if a + @notification_count += 1 + @notifications.push a + end + end + end + + if @notification_count == 0 + @notification_count = '' + end + end end