X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/43c411ec1441ee1710dc33389d7451f7414a170f..b54435b16c3f6b22d4526d543c276c314143d124:/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 07b7a2a1df..f431be2bb5 100644 --- a/apps/workbench/app/controllers/application_controller.rb +++ b/apps/workbench/app/controllers/application_controller.rb @@ -1,9 +1,11 @@ class ApplicationController < ActionController::Base protect_from_forgery + around_filter :thread_clear around_filter :thread_with_api_token, :except => [:render_exception, :render_not_found] before_filter :find_object_by_uuid, :except => [:index, :render_exception, :render_not_found] + before_filter :check_user_agreements, :except => [:render_exception, :render_not_found] - unless Rails.application.config.consider_all_requests_local + begin rescue_from Exception, :with => :render_exception rescue_from ActiveRecord::RecordNotFound, @@ -12,7 +14,7 @@ class ApplicationController < ActionController::Base :with => :render_not_found rescue_from ActionController::UnknownController, :with => :render_not_found - rescue_from ActionController::UnknownAction, + rescue_from ::AbstractController::ActionNotFound, :with => :render_not_found end @@ -32,7 +34,7 @@ class ApplicationController < ActionController::Base def render_exception(e) logger.error e.inspect logger.error e.backtrace.collect { |x| x + "\n" }.join('') if e.backtrace - if @object and @object.errors and @object.errors.full_messages + if @object.andand.errors.andand.full_messages.andand.any? @errors = @object.errors.full_messages else @errors = [e.inspect] @@ -51,6 +53,7 @@ class ApplicationController < ActionController::Base @objects ||= model_class.all respond_to do |f| f.json { render json: @objects } + f.html { render } end end @@ -60,33 +63,87 @@ class ApplicationController < ActionController::Base end respond_to do |f| f.json { render json: @object } - f.html { render } + f.html { + if request.method == 'GET' + render + else + redirect_to params[:return_to] || @object + end + } + end + end + + def render_content + if !@object + return render_not_found("object not found") + end + end + + def new + @object = model_class.new + end + + def update + updates = params[@object.class.to_s.underscore.singularize.to_sym] + updates.keys.each do |attr| + if @object.send(attr).is_a? Hash and updates[attr].is_a? String + updates[attr] = Oj.load updates[attr] + end + end + if @object.update_attributes updates + show + else + self.render_error status: 422 + end + end + + def create + @object ||= model_class.new params[model_class.to_s.singularize.to_sym] + @object.save! + redirect_to(params[:return_to] || @object) + end + + def destroy + if @object.destroy + redirect_to(params[:return_to] || :back) + else + self.render_error status: 422 end end def current_user if Thread.current[:arvados_api_token] - @current_user ||= User.current + Thread.current[:user] ||= User.current else logger.error "No API token in Thread" return nil end end - protected - def model_class controller_name.classify.constantize end + protected + def find_object_by_uuid if params[:id] and params[:id].match /\D/ params[:uuid] = params.delete :id end - @object = model_class.where(uuid: params[:uuid]).first + if params[:uuid].is_a? String + @object = model_class.find(params[:uuid]) + else + @object = model_class.where(uuid: params[:uuid]).first + end + end + + def thread_clear + Thread.current[:arvados_api_token] = nil + Thread.current[:user] = nil + yield end - def thread_with_api_token + def thread_with_api_token(login_optional = false) begin try_redirect_to_login = true if params[:api_token] @@ -120,16 +177,29 @@ class ApplicationController < ActionController::Base rescue ArvadosApiClient::NotLoggedInException try_redirect_to_login = true end + else + logger.debug "No token received, session is #{session.inspect}" end if try_redirect_to_login - respond_to do |f| - f.html { - redirect_to $arvados_api_client.arvados_login_url(return_to: request.url) - } - f.json { - @errors = ['No API token supplied -- can\'t really do anything.'] - self.render_error status: 422 - } + 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 + else + # login is optional for this route so go on to the regular controller + Thread.current[:arvados_api_token] = nil + yield end end ensure @@ -138,6 +208,12 @@ class ApplicationController < ActionController::Base end end + def thread_with_optional_api_token + thread_with_api_token(true) do + yield + end + end + def verify_api_token begin Link.where(uuid: 'just-verifying-my-api-token') @@ -153,4 +229,28 @@ 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 end