2872: Fix bookmark bar causing spurious window width.
[arvados.git] / apps / workbench / app / controllers / application_controller.rb
index c1e82eb621617f807187833827b2d7c0036a6c21..48b508a4a6e305d51764c6fd5ef4f94d43b76cfb 100644 (file)
@@ -118,7 +118,7 @@ class ApplicationController < ActionController::Base
     respond_to do |f|
       f.json { render json: @object.attributes.merge(href: url_for(@object)) }
       f.html {
-        if request.method == 'GET'
+        if request.method.in? ['GET', 'HEAD']
           render
         else
           redirect_to params[:return_to] || @object
@@ -191,6 +191,24 @@ class ApplicationController < ActionController::Base
     show
   end
 
+  # Clone the given object, merging any attribute values supplied as
+  # with a create action.
+  def copy
+    @new_resource_attrs ||= params[model_class.to_s.underscore.singularize]
+    @new_resource_attrs ||= {}
+    @object = @object.dup
+    @object.update_attributes @new_resource_attrs
+    if not @new_resource_attrs[:name] and @object.respond_to? :name
+      if @object.name and @object.name != ''
+        @object.name = "Copy of #{@object.name}"
+      else
+        @object.name = "Copy of unnamed #{@object.class_for_display.downcase}"
+      end
+    end
+    @object.save!
+    show
+  end
+
   def destroy
     if @object.destroy
       respond_to do |f|
@@ -237,7 +255,7 @@ class ApplicationController < ActionController::Base
   def redirect_to_login
     respond_to do |f|
       f.html {
-        if request.method == 'GET'
+        if request.method.in? ['GET', 'HEAD']
           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."
@@ -307,7 +325,7 @@ class ApplicationController < ActionController::Base
         # call to verify its authenticity.
         if verify_api_token
           session[:arvados_api_token] = params[:api_token]
-          if !request.format.json? and request.method == 'GET'
+          if !request.format.json? and request.method.in? ['GET', 'HEAD']
             # Repeat this request with api_token in the (new) session
             # cookie instead of the query string.  This prevents API
             # tokens from appearing in (and being inadvisedly copied
@@ -350,8 +368,18 @@ class ApplicationController < ActionController::Base
   end
 
   def thread_with_mandatory_api_token
-    thread_with_api_token do
-      yield
+    thread_with_api_token(true) do
+      if Thread.current[:arvados_api_token]
+        yield
+      elsif session[:arvados_api_token]
+        # Expired session. Clear it before refreshing login so that,
+        # if this login procedure fails, we end up showing the "please
+        # log in" page instead of getting stuck in a redirect loop.
+        session.delete :arvados_api_token
+        redirect_to_login
+      else
+        render 'users/welcome'
+      end
     end
   end
 
@@ -385,7 +413,10 @@ class ApplicationController < ActionController::Base
   end
 
   def check_user_agreements
-    if current_user && !current_user.is_active && current_user.is_invited
+    if current_user && !current_user.is_active
+      if not current_user.is_invited
+        return render 'users/inactive'
+      end
       signatures = UserAgreement.signatures
       @signed_ua_uuids = UserAgreement.signatures.map &:head_uuid
       @required_user_agreements = UserAgreement.all.map do |ua|
@@ -470,14 +501,19 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  helper_method :my_folders
-  def my_folders
-    return @my_folders if @my_folders
-    @my_folders = []
+  helper_method :all_projects
+  def all_projects
+    @all_projects ||= Group.filter([['group_class','in',['project','folder']]])
+  end
+
+  helper_method :my_projects
+  def my_projects
+    return @my_projects if @my_projects
+    @my_projects = []
     root_of = {}
-    Group.filter([['group_class','=','folder']]).each do |g|
+    all_projects.each do |g|
       root_of[g.uuid] = g.owner_uuid
-      @my_folders << g
+      @my_projects << g
     end
     done = false
     while not done
@@ -491,11 +527,27 @@ class ApplicationController < ActionController::Base
         end
       end
     end
-    @my_folders = @my_folders.select do |g|
+    @my_projects = @my_projects.select do |g|
       root_of[g.uuid] == current_user.uuid
     end
   end
 
+  helper_method :projects_shared_with_me
+  def projects_shared_with_me
+    my_project_uuids = my_projects.collect &:uuid
+    all_projects.reject { |x| x.uuid.in? my_project_uuids }
+  end
+
+  helper_method :recent_jobs_and_pipelines
+  def recent_jobs_and_pipelines
+    in_my_projects = ['owner_uuid','in',my_projects.collect(&:uuid)]
+    (Job.limit(10).filter([in_my_projects]) |
+     PipelineInstance.limit(10).filter([in_my_projects])).
+      sort_by do |x|
+      x.finished_at || x.started_at || x.created_at rescue x.created_at
+    end
+  end
+
   helper_method :get_object
   def get_object uuid
     if @get_object.nil? and @objects
@@ -506,4 +558,34 @@ class ApplicationController < ActionController::Base
     @get_object ||= {}
     @get_object[uuid]
   end
+
+  helper_method :project_breadcrumbs
+  def project_breadcrumbs
+    crumbs = []
+    current = @name_link || @object
+    while current
+      if current.is_a?(Group) and current.group_class.in?(['project','folder'])
+        crumbs.prepend current
+      end
+      if current.is_a? Link
+        current = Group.find?(current.tail_uuid)
+      else
+        current = Group.find?(current.owner_uuid)
+      end
+    end
+    crumbs
+  end
+
+  helper_method :current_project_uuid
+  def current_project_uuid
+    if @object.is_a? Group and @object.group_class.in?(['project','folder'])
+      @object.uuid
+    elsif @name_link.andand.tail_uuid
+      @name_link.tail_uuid
+    elsif @object and resource_class_for_uuid(@object.owner_uuid) == Group
+      @object.owner_uuid
+    else
+      nil
+    end
+  end
 end