Do not check for user agreement signature before showing user agreement.
[arvados.git] / apps / workbench / app / controllers / application_controller.rb
index 3cae2dcbd7021a164da41f583049584be632939d..f431be2bb5114b78e61385c962db813000e9993a 100644 (file)
@@ -3,6 +3,7 @@ class ApplicationController < ActionController::Base
   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]
 
   begin
     rescue_from Exception,
@@ -13,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
 
@@ -62,7 +63,13 @@ 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
 
@@ -77,7 +84,13 @@ class ApplicationController < ActionController::Base
   end
 
   def update
-    if @object.update_attributes params[@object.class.to_s.underscore.singularize.to_sym]
+    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
@@ -87,7 +100,7 @@ class ApplicationController < ActionController::Base
   def create
     @object ||= model_class.new params[model_class.to_s.singularize.to_sym]
     @object.save!
-    redirect_to @object
+    redirect_to(params[:return_to] || @object)
   end
 
   def destroy
@@ -117,7 +130,11 @@ class ApplicationController < ActionController::Base
     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
@@ -126,7 +143,7 @@ class ApplicationController < ActionController::Base
     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]
@@ -164,19 +181,25 @@ class ApplicationController < ActionController::Base
         logger.debug "No token received, session is #{session.inspect}"
       end
       if try_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
-          }
+        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
@@ -185,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')
@@ -200,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