2809: Merge branch 'master' into 2809-workbench-rails4 refs #2809
authorTom Clegg <tom@curoverse.com>
Thu, 15 May 2014 18:19:06 +0000 (14:19 -0400)
committerTom Clegg <tom@curoverse.com>
Thu, 15 May 2014 18:19:06 +0000 (14:19 -0400)
Conflicts:
apps/workbench/app/models/arvados_api_client.rb

51 files changed:
apps/workbench/Gemfile
apps/workbench/Gemfile.lock
apps/workbench/app/assets/javascripts/api_client_authorizations.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/authorized_keys.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/folders.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/groups.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/humans.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/job_tasks.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/jobs.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/keep_disks.js.coffee
apps/workbench/app/assets/javascripts/links.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/logs.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/nodes.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/pipeline_instances.js
apps/workbench/app/assets/javascripts/pipeline_templates.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/repositories.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/sessions.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/specimens.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/traits.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/user_agreements.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/users.js.coffee [deleted file]
apps/workbench/app/assets/javascripts/virtual_machines.js.coffee [deleted file]
apps/workbench/app/controllers/actions_controller.rb
apps/workbench/app/controllers/application_controller.rb
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/controllers/sessions_controller.rb
apps/workbench/app/controllers/users_controller.rb
apps/workbench/app/helpers/arvados_api_client_helper.rb [new file with mode: 0644]
apps/workbench/app/models/arvados_api_client.rb
apps/workbench/app/models/arvados_base.rb
apps/workbench/app/models/arvados_resource_list.rb
apps/workbench/app/models/collection.rb
apps/workbench/app/models/group.rb
apps/workbench/app/models/user.rb
apps/workbench/app/models/user_agreement.rb
apps/workbench/app/views/layouts/application.html.erb
apps/workbench/app/views/links/_recent.html.erb
apps/workbench/app/views/users/_show_admin.html.erb
apps/workbench/app/views/users/welcome.html.erb
apps/workbench/app/views/websocket/index.html.erb
apps/workbench/config/application.default.yml
apps/workbench/config/application.rb
apps/workbench/config/environments/development.rb.example
apps/workbench/config/environments/production.rb.example
apps/workbench/config/environments/test.rb.example
apps/workbench/config/initializers/zzz_arvados_api_client.rb [deleted file]
apps/workbench/config/load_config.rb [moved from apps/workbench/config/initializers/zza_load_config.rb with 100% similarity]
apps/workbench/config/routes.rb
apps/workbench/test/integration/users_test.rb
apps/workbench/test/test_helper.rb
doc/install/install-workbench-app.html.textile.liquid

index bcbe3ef36fd40d85c02f1302383a9acef2942b81..754d5c60437c8d1844902fd1d250ae0af92f2336 100644 (file)
@@ -1,6 +1,7 @@
 source 'https://rubygems.org'
 
-gem 'rails', '~> 3.2.0'
+gem 'rails', '~> 4.1.0'
+gem 'minitest', '>= 5.0.0'
 
 # Bundle edge Rails instead:
 # gem 'rails', :git => 'git://github.com/rails/rails.git'
@@ -11,11 +12,17 @@ gem 'multi_json'
 gem 'oj'
 gem 'sass'
 
+# Note: keeping this out of the "group :assets" section "may" allow us
+# to use Coffescript for UJS responses. It also prevents a
+# warning/problem when running tests: "WARN: tilt autoloading
+# 'coffee_script' in a non thread-safe way; explicit require
+# 'coffee_script' suggested."
+gem 'coffee-rails'
+
 # Gems used only for assets and not required
 # in production environments by default.
 group :assets do
-  gem 'sass-rails',   '~> 3.2.0'
-  gem 'coffee-rails', '~> 3.2.0'
+  gem 'sass-rails'
 
   # See https://github.com/sstephenson/execjs#readme for more supported runtimes
   gem 'therubyracer', :platforms => :ruby
@@ -64,5 +71,8 @@ gem 'RedCloth'
 
 gem 'piwik_analytics'
 gem 'httpclient'
-gem 'themes_for_rails'
+
+# This fork has Rails 4 compatible routes
+gem 'themes_for_rails', git: 'https://github.com/holtkampw/themes_for_rails', ref: '1fd2d7897d75ae0d6375f4c390df87b8e91ad417'
+
 gem "deep_merge", :require => 'deep_merge/rails_compat'
index 8e748326a1582871efbef261ed72d2288fe70a87..173be13cc3e312a64d8a10a5e183cb81f72957bf 100644 (file)
@@ -1,41 +1,48 @@
+GIT
+  remote: https://github.com/holtkampw/themes_for_rails
+  revision: 1fd2d7897d75ae0d6375f4c390df87b8e91ad417
+  ref: 1fd2d7897d75ae0d6375f4c390df87b8e91ad417
+  specs:
+    themes_for_rails (0.5.1)
+      rails (>= 3.0.0)
+
 GEM
   remote: https://rubygems.org/
   specs:
     RedCloth (4.2.9)
-    actionmailer (3.2.15)
-      actionpack (= 3.2.15)
+    actionmailer (4.1.1)
+      actionpack (= 4.1.1)
+      actionview (= 4.1.1)
       mail (~> 2.5.4)
-    actionpack (3.2.15)
-      activemodel (= 3.2.15)
-      activesupport (= 3.2.15)
-      builder (~> 3.0.0)
+    actionpack (4.1.1)
+      actionview (= 4.1.1)
+      activesupport (= 4.1.1)
+      rack (~> 1.5.2)
+      rack-test (~> 0.6.2)
+    actionview (4.1.1)
+      activesupport (= 4.1.1)
+      builder (~> 3.1)
       erubis (~> 2.7.0)
-      journey (~> 1.0.4)
-      rack (~> 1.4.5)
-      rack-cache (~> 1.2)
-      rack-test (~> 0.6.1)
-      sprockets (~> 2.2.1)
-    activemodel (3.2.15)
-      activesupport (= 3.2.15)
-      builder (~> 3.0.0)
-    activerecord (3.2.15)
-      activemodel (= 3.2.15)
-      activesupport (= 3.2.15)
-      arel (~> 3.0.2)
-      tzinfo (~> 0.3.29)
-    activeresource (3.2.15)
-      activemodel (= 3.2.15)
-      activesupport (= 3.2.15)
-    activesupport (3.2.15)
-      i18n (~> 0.6, >= 0.6.4)
-      multi_json (~> 1.0)
+    activemodel (4.1.1)
+      activesupport (= 4.1.1)
+      builder (~> 3.1)
+    activerecord (4.1.1)
+      activemodel (= 4.1.1)
+      activesupport (= 4.1.1)
+      arel (~> 5.0.0)
+    activesupport (4.1.1)
+      i18n (~> 0.6, >= 0.6.9)
+      json (~> 1.7, >= 1.7.7)
+      minitest (~> 5.1)
+      thread_safe (~> 0.1)
+      tzinfo (~> 1.1)
     andand (1.3.3)
-    arel (3.0.2)
+    arel (5.0.1.20140414130214)
     bootstrap-sass (3.1.0.1)
       sass (~> 3.2)
     bootstrap-x-editable-rails (1.5.1.1)
       railties (>= 3.0)
-    builder (3.0.4)
+    builder (3.2.2)
     capistrano (2.15.5)
       highline
       net-scp (>= 1.0.0)
@@ -51,13 +58,13 @@ GEM
     childprocess (0.5.1)
       ffi (~> 1.0, >= 1.0.11)
     cliver (0.3.2)
-    coffee-rails (3.2.2)
+    coffee-rails (4.0.1)
       coffee-script (>= 2.2.0)
-      railties (~> 3.2.0)
+      railties (>= 4.0.0, < 5.0)
     coffee-script (2.2.0)
       coffee-script-source
       execjs
-    coffee-script-source (1.6.3)
+    coffee-script-source (1.7.0)
     commonjs (0.2.7)
     daemon_controller (1.1.7)
     deep_merge (1.0.1)
@@ -68,8 +75,7 @@ GEM
     highline (1.6.20)
     hike (1.2.3)
     httpclient (2.3.4.1)
-    i18n (0.6.5)
-    journey (1.0.4)
+    i18n (0.6.9)
     jquery-rails (3.0.4)
       railties (>= 3.0, < 5.0)
       thor (>= 0.14, < 2.0)
@@ -83,9 +89,10 @@ GEM
     mail (2.5.4)
       mime-types (~> 1.16)
       treetop (~> 1.4.8)
-    mime-types (1.25)
+    mime-types (1.25.1)
     mini_portile (0.5.2)
-    multi_json (1.8.2)
+    minitest (5.3.3)
+    multi_json (1.10.0)
     net-scp (1.1.2)
       net-ssh (>= 2.6.5)
     net-sftp (2.1.2)
@@ -109,41 +116,36 @@ GEM
       cliver (~> 0.3.1)
       multi_json (~> 1.0)
       websocket-driver (>= 0.2.0)
-    polyglot (0.3.3)
-    rack (1.4.5)
-    rack-cache (1.2)
-      rack (>= 0.4)
-    rack-ssl (1.3.3)
-      rack
+    polyglot (0.3.4)
+    rack (1.5.2)
     rack-test (0.6.2)
       rack (>= 1.0)
-    rails (3.2.15)
-      actionmailer (= 3.2.15)
-      actionpack (= 3.2.15)
-      activerecord (= 3.2.15)
-      activeresource (= 3.2.15)
-      activesupport (= 3.2.15)
-      bundler (~> 1.0)
-      railties (= 3.2.15)
-    railties (3.2.15)
-      actionpack (= 3.2.15)
-      activesupport (= 3.2.15)
-      rack-ssl (~> 1.3.2)
+    rails (4.1.1)
+      actionmailer (= 4.1.1)
+      actionpack (= 4.1.1)
+      actionview (= 4.1.1)
+      activemodel (= 4.1.1)
+      activerecord (= 4.1.1)
+      activesupport (= 4.1.1)
+      bundler (>= 1.3.0, < 2.0)
+      railties (= 4.1.1)
+      sprockets-rails (~> 2.0)
+    railties (4.1.1)
+      actionpack (= 4.1.1)
+      activesupport (= 4.1.1)
       rake (>= 0.8.7)
-      rdoc (~> 3.4)
-      thor (>= 0.14.6, < 2.0)
-    rake (10.1.0)
-    rdoc (3.12.2)
-      json (~> 1.4)
+      thor (>= 0.18.1, < 2.0)
+    rake (10.3.1)
     ref (1.0.5)
     rubyzip (1.1.0)
     rvm-capistrano (1.5.1)
       capistrano (~> 2.15.4)
     sass (3.2.12)
-    sass-rails (3.2.6)
-      railties (~> 3.2.0)
-      sass (>= 3.1.10)
-      tilt (~> 1.3)
+    sass-rails (4.0.3)
+      railties (>= 4.0.0, < 5.0)
+      sass (~> 3.2.0)
+      sprockets (~> 2.8, <= 2.11.0)
+      sprockets-rails (~> 2.0)
     selenium-webdriver (2.40.0)
       childprocess (>= 0.5.0)
       multi_json (~> 1.0)
@@ -155,23 +157,27 @@ GEM
     simplecov-html (0.7.1)
     simplecov-rcov (0.2.3)
       simplecov (>= 0.4.1)
-    sprockets (2.2.2)
+    sprockets (2.11.0)
       hike (~> 1.2)
       multi_json (~> 1.0)
       rack (~> 1.0)
       tilt (~> 1.1, != 1.3.0)
+    sprockets-rails (2.1.3)
+      actionpack (>= 3.0)
+      activesupport (>= 3.0)
+      sprockets (~> 2.8)
     sqlite3 (1.3.8)
-    themes_for_rails (0.5.1)
-      rails (>= 3.0.0)
     therubyracer (0.12.0)
       libv8 (~> 3.16.14.0)
       ref
-    thor (0.18.1)
+    thor (0.19.1)
+    thread_safe (0.3.3)
     tilt (1.4.1)
     treetop (1.4.15)
       polyglot
       polyglot (>= 0.3.1)
-    tzinfo (0.3.38)
+    tzinfo (1.1.0)
+      thread_safe (~> 0.1)
     uglifier (2.3.1)
       execjs (>= 0.3.0)
       json (>= 1.8.0)
@@ -189,26 +195,27 @@ DEPENDENCIES
   bootstrap-sass (~> 3.1.0)
   bootstrap-x-editable-rails
   capybara
-  coffee-rails (~> 3.2.0)
+  coffee-rails
   deep_merge
   headless
   httpclient
   jquery-rails
   less
   less-rails
+  minitest (>= 5.0.0)
   multi_json
   oj
   passenger
   piwik_analytics
   poltergeist
-  rails (~> 3.2.0)
+  rails (~> 4.1.0)
   rvm-capistrano
   sass
-  sass-rails (~> 3.2.0)
+  sass-rails
   selenium-webdriver
   simplecov (~> 0.7.1)
   simplecov-rcov
   sqlite3
-  themes_for_rails
+  themes_for_rails!
   therubyracer
   uglifier (>= 1.0.3)
diff --git a/apps/workbench/app/assets/javascripts/api_client_authorizations.js.coffee b/apps/workbench/app/assets/javascripts/api_client_authorizations.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/authorized_keys.js.coffee b/apps/workbench/app/assets/javascripts/authorized_keys.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/folders.js.coffee b/apps/workbench/app/assets/javascripts/folders.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/groups.js.coffee b/apps/workbench/app/assets/javascripts/groups.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/humans.js.coffee b/apps/workbench/app/assets/javascripts/humans.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/job_tasks.js.coffee b/apps/workbench/app/assets/javascripts/job_tasks.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/jobs.js.coffee b/apps/workbench/app/assets/javascripts/jobs.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
index cc3aac784c2459560cacbd966d08fb2d5fbe98ad..e4aa4b4321334d79cd5d3228f77e656c4dafe4b5 100644 (file)
@@ -1,7 +1,3 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
-
 cache_age_in_days = (milliseconds_age) ->
   ONE_DAY = 1000 * 60 * 60 * 24
   milliseconds_age / ONE_DAY
diff --git a/apps/workbench/app/assets/javascripts/links.js.coffee b/apps/workbench/app/assets/javascripts/links.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/logs.js.coffee b/apps/workbench/app/assets/javascripts/logs.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/nodes.js.coffee b/apps/workbench/app/assets/javascripts/nodes.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
index ee14e3b78127dbdfc79513abc97e4ed4c29b18d8..a9ca4df2a5117ef96427e6779550e13a7c766162 100644 (file)
@@ -1,4 +1,3 @@
-
 (function() {
     var run_pipeline_button_state = function() {
         var a = $('a.editable.required.editable-empty');
diff --git a/apps/workbench/app/assets/javascripts/pipeline_templates.js.coffee b/apps/workbench/app/assets/javascripts/pipeline_templates.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/repositories.js.coffee b/apps/workbench/app/assets/javascripts/repositories.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/sessions.js.coffee b/apps/workbench/app/assets/javascripts/sessions.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/specimens.js.coffee b/apps/workbench/app/assets/javascripts/specimens.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/traits.js.coffee b/apps/workbench/app/assets/javascripts/traits.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/user_agreements.js.coffee b/apps/workbench/app/assets/javascripts/user_agreements.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/users.js.coffee b/apps/workbench/app/assets/javascripts/users.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/javascripts/virtual_machines.js.coffee b/apps/workbench/app/assets/javascripts/virtual_machines.js.coffee
deleted file mode 100644 (file)
index 7615679..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
index 2dab6dd6a86e00f52f6f2302eaa817bea2c54ffb..368d9a8e8ce3a9b106b50d1b0f385603ea993021 100644 (file)
@@ -86,7 +86,7 @@ class ActionsController < ApplicationController
     env = Hash[ENV].
       merge({
               'ARVADOS_API_HOST' =>
-              $arvados_api_client.arvados_v1_base.
+              arvados_api_client.arvados_v1_base.
               sub(/\/arvados\/v1/, '').
               sub(/^https?:\/\//, ''),
               'ARVADOS_API_TOKEN' => Thread.current[:arvados_api_token],
index 2fbd8c560f6dd081ef49230151d91c9d10ed03ec..b62838f655e23a54033d28298c265849c32f2398 100644 (file)
@@ -1,4 +1,6 @@
 class ApplicationController < ActionController::Base
+  include ArvadosApiClientHelper
+
   respond_to :html, :json, :js
   protect_from_forgery
 
@@ -198,7 +200,7 @@ class ApplicationController < ActionController::Base
     respond_to do |f|
       f.html {
         if request.method == 'GET'
-          redirect_to $arvados_api_client.arvados_login_url(return_to: request.url)
+          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
index 4178e38361b7481903df9743535d6a2c23818b90..7ef85a5cfc89dbc62c26e90cd41cd7ecd1a137c4 100644 (file)
@@ -233,7 +233,7 @@ class CollectionsController < ApplicationController
       env = Hash[ENV].
         merge({
                 'ARVADOS_API_HOST' =>
-                $arvados_api_client.arvados_v1_base.
+                arvados_api_client.arvados_v1_base.
                 sub(/\/arvados\/v1/, '').
                 sub(/^https?:\/\//, ''),
                 'ARVADOS_API_TOKEN' =>
index 488c67c3c2e8b51cfb8990b9148d7b3b4d0a7f13..585f322a859186d06ba02d9b8a37e8f50c965490 100644 (file)
@@ -4,7 +4,7 @@ class SessionsController < ApplicationController
   skip_before_filter :find_object_by_uuid, :only => [:destroy, :index]
   def destroy
     session.clear
-    redirect_to $arvados_api_client.arvados_logout_url(return_to: root_url)
+    redirect_to arvados_api_client.arvados_logout_url(return_to: root_url)
   end
   def index
     redirect_to root_url if session[:arvados_api_token]
index 863876137fdab5f941740e5f7bd30187415c6099..3d8c8530add9aecd27898bc0325bfa44d8be165f 100644 (file)
@@ -107,11 +107,11 @@ class UsersController < ApplicationController
   end
 
   def sudo
-    resp = $arvados_api_client.api(ApiClientAuthorization, '', {
-                                     api_client_authorization: {
-                                       owner_uuid: @object.uuid
-                                     }
-                                   })
+    resp = arvados_api_client.api(ApiClientAuthorization, '', {
+                                    api_client_authorization: {
+                                      owner_uuid: @object.uuid
+                                    }
+                                  })
     redirect_to root_url(api_token: resp[:api_token])
   end
 
diff --git a/apps/workbench/app/helpers/arvados_api_client_helper.rb b/apps/workbench/app/helpers/arvados_api_client_helper.rb
new file mode 100644 (file)
index 0000000..b6c29a9
--- /dev/null
@@ -0,0 +1,13 @@
+module ArvadosApiClientHelper
+  def arvados_api_client
+    ArvadosApiClient.new_or_current
+  end
+end
+
+# For the benefit of themes that still expect $arvados_api_client to work:
+class ArvadosClientProxyHack
+  def method_missing *args
+    ArvadosApiClient.new_or_current.send *args
+  end
+end
+$arvados_api_client = ArvadosClientProxyHack.new
index c6d8720c9232fa0dba6fdf8d72f2b20b716243cd..25e776a94267fd41394d47a4553bc8e03ecd80dd 100644 (file)
@@ -7,21 +7,31 @@ class ArvadosApiClient
   class InvalidApiResponseException < StandardError
   end
 
-  @@client_mtx = Mutex.new
-  @@api_client = nil
   @@profiling_enabled = Rails.configuration.profiling_enabled
+  @@discovery = nil
+
+  # An API client object suitable for handling API requests on behalf
+  # of the current thread.
+  def self.new_or_current
+    Thread.current[:arvados_api_client] ||= new
+  end
+
+  def initialize *args
+    @api_client = nil
+    @client_mtx = Mutex.new
+  end
 
   def api(resources_kind, action, data=nil)
     profile_checkpoint
 
-    @@client_mtx.synchronize do
-      if not @@api_client
-        @@api_client = HTTPClient.new
+    if not @api_client
+      @client_mtx.synchronize do
+        @api_client = HTTPClient.new
         if Rails.configuration.arvados_insecure_https
-          @@api_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
+          @api_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
         else
           # Use system CA certificates
-          @@api_client.ssl_config.add_trust_ca('/etc/ssl/certs')
+          @api_client.ssl_config.add_trust_ca('/etc/ssl/certs')
         end
       end
     end
@@ -58,9 +68,11 @@ class ArvadosApiClient
     header = {"Accept" => "application/json"}
 
     profile_checkpoint { "Prepare request #{url} #{query[:uuid]} #{query[:where]} #{query[:filters]}" }
-    msg = @@api_client.post(url,
-                            query,
-                            header: header)
+    msg = @client_mtx.synchronize do
+      @api_client.post(url,
+                       query,
+                       header: header)
+    end
     profile_checkpoint 'API transaction'
 
     if msg.status_code == 401
@@ -158,7 +170,7 @@ class ArvadosApiClient
   end
 
   def discovery
-    @discovery ||= api '../../discovery/v1/apis/arvados/v1/rest', ''
+    @@discovery ||= api '../../discovery/v1/apis/arvados/v1/rest', ''
   end
 
   def kind_class(kind)
index 1a0da6424a828b0638aaf95305ffbcb5d34b8273..1ad0230512318bf114e6e30de95d9dc1eb21371f 100644 (file)
@@ -2,11 +2,19 @@ class ArvadosBase < ActiveRecord::Base
   self.abstract_class = true
   attr_accessor :attribute_sortkey
 
+  def self.arvados_api_client
+    ArvadosApiClient.new_or_current
+  end
+
+  def arvados_api_client
+    ArvadosApiClient.new_or_current
+  end
+
   def self.uuid_infix_object_kind
     @@uuid_infix_object_kind ||=
       begin
         infix_kind = {}
-        $arvados_api_client.discovery[:schemas].each do |name, schema|
+        arvados_api_client.discovery[:schemas].each do |name, schema|
           if schema[:uuidPrefix]
             infix_kind[schema[:uuidPrefix]] =
               'arvados#' + name.to_s.camelcase(:lower)
@@ -21,8 +29,8 @@ class ArvadosBase < ActiveRecord::Base
       end
   end
 
-  def initialize(*args)
-    super(*args)
+  def initialize raw_params={}
+    super self.class.permit_attribute_params(raw_params)
     @attribute_sortkey ||= {
       'id' => nil,
       'name' => '000',
@@ -49,7 +57,7 @@ class ArvadosBase < ActiveRecord::Base
     return @columns unless @columns.nil?
     @columns = []
     @attribute_info ||= {}
-    schema = $arvados_api_client.discovery[:schemas][self.to_s.to_sym]
+    schema = arvados_api_client.discovery[:schemas][self.to_s.to_sym]
     return @columns if schema.nil?
     schema[:properties].each do |k, coldef|
       case k
@@ -64,7 +72,6 @@ class ArvadosBase < ActiveRecord::Base
           @columns << column(k, :text)
           serialize k, coldef[:type].constantize
         end
-        attr_accessible k
         @attribute_info[k] = coldef
       end
     end
@@ -94,10 +101,10 @@ class ArvadosBase < ActiveRecord::Base
     # request} unless {cache: false} is given via opts.
     cache_key = "request_#{Thread.current.object_id}_#{self.to_s}_#{uuid}"
     if opts[:cache] == false
-      Rails.cache.write cache_key, $arvados_api_client.api(self, '/' + uuid)
+      Rails.cache.write cache_key, arvados_api_client.api(self, '/' + uuid)
     end
     hash = Rails.cache.fetch cache_key do
-      $arvados_api_client.api(self, '/' + uuid)
+      arvados_api_client.api(self, '/' + uuid)
     end
     new.private_reload(hash)
   end
@@ -126,6 +133,25 @@ class ArvadosBase < ActiveRecord::Base
     ArvadosResourceList.new(self).all(*args)
   end
 
+  def self.permit_attribute_params raw_params
+    # strong_parameters does not provide security in Workbench: anyone
+    # who can get this far can just as well do a call directly to our
+    # database (Arvados) with the same credentials we use.
+    #
+    # The following permit! is necessary even with
+    # "ActionController::Parameters.permit_all_parameters = true",
+    # because permit_all does not permit nested attributes.
+    ActionController::Parameters.new(raw_params).permit!
+  end
+
+  def self.create raw_params={}
+    super(permit_attribute_params(raw_params))
+  end
+
+  def update_attributes raw_params={}
+    super(self.class.permit_attribute_params(raw_params))
+  end
+
   def save
     obdata = {}
     self.class.columns.each do |col|
@@ -136,9 +162,9 @@ class ArvadosBase < ActiveRecord::Base
     if etag
       postdata['_method'] = 'PUT'
       obdata.delete :uuid
-      resp = $arvados_api_client.api(self.class, '/' + uuid, postdata)
+      resp = arvados_api_client.api(self.class, '/' + uuid, postdata)
     else
-      resp = $arvados_api_client.api(self.class, '', postdata)
+      resp = arvados_api_client.api(self.class, '', postdata)
     end
     return false if !resp[:etag] || !resp[:uuid]
 
@@ -165,7 +191,7 @@ class ArvadosBase < ActiveRecord::Base
   def destroy
     if etag || uuid
       postdata = { '_method' => 'DELETE' }
-      resp = $arvados_api_client.api(self.class, '/' + uuid, postdata)
+      resp = arvados_api_client.api(self.class, '/' + uuid, postdata)
       resp[:etag] && resp[:uuid] && resp
     else
       true
@@ -192,13 +218,13 @@ class ArvadosBase < ActiveRecord::Base
         ok
       end
     end
-    @links = $arvados_api_client.api Link, '', { _method: 'GET', where: o, eager: true }
-    @links = $arvados_api_client.unpack_api_response(@links)
+    @links = arvados_api_client.api Link, '', { _method: 'GET', where: o, eager: true }
+    @links = arvados_api_client.unpack_api_response(@links)
   end
 
   def all_links
     return @all_links if @all_links
-    res = $arvados_api_client.api Link, '', {
+    res = arvados_api_client.api Link, '', {
       _method: 'GET',
       where: {
         tail_kind: self.kind,
@@ -206,7 +232,7 @@ class ArvadosBase < ActiveRecord::Base
       },
       eager: true
     }
-    @all_links = $arvados_api_client.unpack_api_response(res)
+    @all_links = arvados_api_client.unpack_api_response(res)
   end
 
   def reload
@@ -218,7 +244,7 @@ class ArvadosBase < ActiveRecord::Base
     if uuid_or_hash.is_a? Hash
       hash = uuid_or_hash
     else
-      hash = $arvados_api_client.api(self.class, '/' + uuid_or_hash)
+      hash = arvados_api_client.api(self.class, '/' + uuid_or_hash)
     end
     hash.each do |k,v|
       if self.respond_to?(k.to_s + '=')
@@ -299,13 +325,13 @@ class ArvadosBase < ActiveRecord::Base
     end
     resource_class = nil
     uuid.match /^[0-9a-z]{5}-([0-9a-z]{5})-[0-9a-z]{15}$/ do |re|
-      resource_class ||= $arvados_api_client.
+      resource_class ||= arvados_api_client.
         kind_class(self.uuid_infix_object_kind[re[1]])
     end
     if opts[:referring_object] and
         opts[:referring_attr] and
         opts[:referring_attr].match /_uuid$/
-      resource_class ||= $arvados_api_client.
+      resource_class ||= arvados_api_client.
         kind_class(opts[:referring_object].
                    attributes[opts[:referring_attr].
                               sub(/_uuid$/, '_kind')])
index 3f74407c01429229bd3ecacf26da7238232dd706..dedd18c81d7eb21193523a52c2dde99cee3176cf 100644 (file)
@@ -1,4 +1,5 @@
 class ArvadosResourceList
+  include ArvadosApiClientHelper
   include Enumerable
 
   def initialize resource_class=nil
@@ -53,7 +54,7 @@ class ArvadosResourceList
     end
     cond.keys.select { |x| x.match /_kind$/ }.each do |kind_key|
       if cond[kind_key].is_a? Class
-        cond = cond.merge({ kind_key => 'arvados#' + $arvados_api_client.class_kind(cond[kind_key]) })
+        cond = cond.merge({ kind_key => 'arvados#' + arvados_api_client.class_kind(cond[kind_key]) })
       end
     end
     api_params = {
@@ -65,8 +66,8 @@ class ArvadosResourceList
     api_params[:offset] = @offset if @offset
     api_params[:order] = @orderby_spec if @orderby_spec
     api_params[:filters] = @filters if @filters
-    res = $arvados_api_client.api @resource_class, '', api_params
-    @results = $arvados_api_client.unpack_api_response res
+    res = arvados_api_client.api @resource_class, '', api_params
+    @results = arvados_api_client.unpack_api_response res
     self
   end
 
index a63bf90cb006d450f7dccf958ec06aa83fa67d24..6022d82433ec843a1aff509d619c964608259b84 100644 (file)
@@ -31,11 +31,11 @@ class Collection < ArvadosBase
   end
 
   def provenance
-    $arvados_api_client.api "collections/#{self.uuid}/", "provenance"
+    arvados_api_client.api "collections/#{self.uuid}/", "provenance"
   end
 
   def used_by
-    $arvados_api_client.api "collections/#{self.uuid}/", "used_by"
+    arvados_api_client.api "collections/#{self.uuid}/", "used_by"
   end
 
 end
index dde6019e9ca4ed9a5d51978fe933fabee0208727..8d8d3900c75a95ea718e36d1f1fb0d7d0e2a7ead 100644 (file)
@@ -1,10 +1,10 @@
 class Group < ArvadosBase
   def contents params={}
-    res = $arvados_api_client.api self.class, "/#{self.uuid}/contents", {
+    res = arvados_api_client.api self.class, "/#{self.uuid}/contents", {
       _method: 'GET'
     }.merge(params)
     ret = ArvadosResourceList.new
-    ret.results = $arvados_api_client.unpack_api_response(res)
+    ret.results = arvados_api_client.unpack_api_response(res)
     ret
   end
 
index 44d615b89fecf117dcc618e01627e1beb74e38f2..c1656bde692ea1b0d454585663b1aca7ec4d3a8a 100644 (file)
@@ -6,15 +6,15 @@ class User < ArvadosBase
   end
 
   def self.current
-    res = $arvados_api_client.api self, '/current'
-    $arvados_api_client.unpack_api_response(res)
+    res = arvados_api_client.api self, '/current'
+    arvados_api_client.unpack_api_response(res)
   end
 
   def self.system
-    $arvados_system_user ||= begin
-                               res = $arvados_api_client.api self, '/system'
-                               $arvados_api_client.unpack_api_response(res)
-                             end
+    @@arvados_system_user ||= begin
+                                res = arvados_api_client.api self, '/system'
+                                arvados_api_client.unpack_api_response(res)
+                              end
   end
 
   def full_name
@@ -22,9 +22,9 @@ class User < ArvadosBase
   end
 
   def activate
-    self.private_reload($arvados_api_client.api(self.class,
-                                                "/#{self.uuid}/activate",
-                                                {}))
+    self.private_reload(arvados_api_client.api(self.class,
+                                               "/#{self.uuid}/activate",
+                                               {}))
   end
 
   def attributes_for_display
@@ -40,13 +40,13 @@ class User < ArvadosBase
   end
 
   def unsetup
-    self.private_reload($arvados_api_client.api(self.class,
-                                                "/#{self.uuid}/unsetup",
-                                                {}))
+    self.private_reload(arvados_api_client.api(self.class,
+                                               "/#{self.uuid}/unsetup",
+                                               {}))
   end
 
   def self.setup params
-    $arvados_api_client.api(self, "/setup", params)
+    arvados_api_client.api(self, "/setup", params)
   end
 
 end
index 63b845228f77934505518e7951e61ec24a92b682..d77038cdd512e7a939c57e3218c260d87efa055c 100644 (file)
@@ -1,10 +1,10 @@
 class UserAgreement < ArvadosBase
   def self.signatures
-    res = $arvados_api_client.api self, '/signatures'
-    $arvados_api_client.unpack_api_response(res)
+    res = arvados_api_client.api self, '/signatures'
+    arvados_api_client.unpack_api_response(res)
   end
   def self.sign(params)
-    res = $arvados_api_client.api self, '/sign', params
-    $arvados_api_client.unpack_api_response(res)
+    res = arvados_api_client.api self, '/sign', params
+    arvados_api_client.unpack_api_response(res)
   end
 end
index e2db3d9b7eae03429c87be3a735880207c67ba38..2d3c4c0de0239881cfe5404679dfd076634f97ca 100644 (file)
             </ul>
           </li>
           <% else %>
-            <li><a href="<%= $arvados_api_client.arvados_login_url(return_to: root_url) %>">Log in</a></li>
+            <li><a href="<%= arvados_api_client.arvados_login_url(return_to: root_url) %>">Log in</a></li>
           <% end %>
         </ul>
       </div><!-- /.navbar-collapse -->
index 7548ae111f51b9f24886fe5990baef4f6e6dc953..1e60bf511d704ec4d7a6361289f940eda0364fa7 100644 (file)
@@ -38,7 +38,7 @@
 
       <td>
         <% if current_user and (current_user.is_admin or current_user.uuid == link.owner_uuid) %>
-        <%= link_to raw('<i class="glyphicon glyphicon-trash"></i>'), { action: 'destroy', id: link.uuid }, { confirm: 'Delete this link?', method: 'delete' } %>
+        <%= link_to raw('<i class="glyphicon glyphicon-trash"></i>'), { action: 'destroy', id: link.uuid }, data: {confirm: 'Delete this link?', method: 'delete'} %>
         <% end %>
       </td>
 
index e2f5fdfa64b354a3988e84683c761f90247c9499..f667f388bdeffa1ce25af5c7dc1fe37d1c8fa179 100644 (file)
@@ -15,7 +15,7 @@ account.</p>
 <p>As an admin, you can deactivate and reset this user. This will remove all repository/VM permissions for the user. If you "setup" the user again, the user will have to sign the user agreement again.</p>
 
 <blockquote>
-<%= button_to "Deactivate #{@object.full_name}", unsetup_user_url(id: @object.uuid), class: 'btn btn-primary', confirm: "Are you sure you want to deactivate #{@object.full_name}?"%>
+<%= button_to "Deactivate #{@object.full_name}", unsetup_user_url(id: @object.uuid), class: 'btn btn-primary', data: {confirm: "Are you sure you want to deactivate #{@object.full_name}?"} %>
 </blockquote>
 
 <% content_for :footer_html do %>
index 4fe55180937c9f5caa763cac10d014642ddcfd94..537041e8f8871c45749db7a3e04c2b5f4520f333 100644 (file)
@@ -13,7 +13,7 @@
   beyond that.
   </p>
       <p>
-       <a  class="pull-right btn btn-primary" href="<%= $arvados_api_client.arvados_login_url(return_to: request.url) %>">
+       <a  class="pull-right btn btn-primary" href="<%= arvados_api_client.arvados_login_url(return_to: request.url) %>">
          Click here to log in to <%= Rails.configuration.site_name %> with a Google account</a>
       </p>
     </div>
index 85202b8662b83d104b3c5a35c9c312fa1850f515..d8053718772fbcd0f8140aa3d85887186983dd70 100644 (file)
@@ -18,7 +18,7 @@ putStuffThere = function (content) {
   $("#PutStuffHere").append(content + "<br>");
 };
 
-var dispatcher = new WebSocket('<%= $arvados_api_client.discovery[:websocketUrl] %>?api_token=<%= Thread.current[:arvados_api_token] %>');
+var dispatcher = new WebSocket('<%= arvados_api_client.discovery[:websocketUrl] %>?api_token=<%= Thread.current[:arvados_api_token] %>');
 dispatcher.onmessage = function(event) {
   //putStuffThere(JSON.parse(event.data));
   putStuffThere(event.data);
index c80b7f960a66f0fe11099688074ae6df289120b2..2fe701afcb6d5efdd9b92abba0ef94f571f23058 100644 (file)
@@ -3,15 +3,12 @@
 
 development:
   cache_classes: false
-  whiny_nils: true
+  eager_load: true
   consider_all_requests_local: true
   action_controller.perform_caching: false
   action_mailer.raise_delivery_errors: false
   active_support.deprecation: :log
   action_dispatch.best_standards_support: :builtin
-  active_record.mass_assignment_sanitizer: :strict
-  active_record.auto_explain_threshold_in_seconds: 0.5
-  assets.compress: false
   assets.debug: true
   profiling_enabled: true
   site_name: Arvados Workbench (dev)
@@ -19,10 +16,10 @@ development:
 production:
   force_ssl: true
   cache_classes: true
+  eager_load: true
   consider_all_requests_local: false
   action_controller.perform_caching: true
   serve_static_assets: false
-  assets.compress: true
   assets.compile: false
   assets.digest: true
   i18n.fallbacks: true
@@ -38,18 +35,18 @@ production:
 
 test:
   cache_classes: true
+  eager_load: false
   serve_static_assets: true
   static_cache_control: public, max-age=3600
-  whiny_nils: true
   consider_all_requests_local: true
   action_controller.perform_caching: false
   action_dispatch.show_exceptions: false
   action_controller.allow_forgery_protection: false
   action_mailer.delivery_method: :test
-  active_record.mass_assignment_sanitizer: :strict
   active_support.deprecation: :stderr
   profiling_enabled: false
   secret_token: <%= rand(2**256).to_s(36) %>
+  secret_key_base: <%= rand(2**256).to_s(36) %>
 
   # When you run the Workbench's integration tests, it starts the API
   # server as a dependency.  These settings should match the API
@@ -62,6 +59,8 @@ test:
   site_name: Workbench:test
 
 common:
+  assets.js_compressor: false
+  assets.css_compressor: false
   data_import_dir: /tmp/arvados-workbench-upload
   data_export_dir: /tmp/arvados-workbench-download
   arvados_login_base: https://arvados.local/login
@@ -72,5 +71,6 @@ common:
   arvados_theme: default
   show_user_agreement_inline: false
   secret_token: ~
+  secret_key_base: false
   default_openid_prefix: https://www.google.com/accounts/o8/id
   send_user_setup_notification_email: true
index 0e1ec9604c319c392a58b912886fa487a0a2838a..4ac68198e8bd6fa6404512ad5479397223de1bc8 100644 (file)
@@ -2,12 +2,7 @@ require File.expand_path('../boot', __FILE__)
 
 require 'rails/all'
 
-if defined?(Bundler)
-  # If you precompile assets before deploying to production, use this line
-  Bundler.require(*Rails.groups(:assets => %w(development test)))
-  # If you want your assets lazily compiled in production, use this line
-  # Bundler.require(:default, :assets, Rails.env)
-end
+Bundler.require(:default, Rails.env)
 
 module ArvadosWorkbench
   class Application < Rails::Application
@@ -47,12 +42,6 @@ module ArvadosWorkbench
     # like if you have constraints or database-specific column types
     # config.active_record.schema_format = :sql
 
-    # Enforce whitelist mode for mass assignment.
-    # This will create an empty whitelist of attributes available for mass-assignment for all models
-    # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
-    # parameters by using an attr_accessible or attr_protected declaration.
-    config.active_record.whitelist_attributes = true
-
     # Enable the asset pipeline
     config.assets.enabled = true
 
@@ -60,3 +49,5 @@ module ArvadosWorkbench
     config.assets.version = '1.0'
   end
 end
+
+require File.expand_path('../load_config', __FILE__)
index 389a25420f1b31eb75290dec3d435acf551e62f7..3ea9ec2016ea89dd5dafa3605fa32ca25b47822d 100644 (file)
@@ -6,9 +6,6 @@ ArvadosWorkbench::Application.configure do
   # since you don't have to restart the web server when you make code changes.
   config.cache_classes = false
 
-  # Log error messages when you accidentally call methods on nil.
-  config.whiny_nils = true
-
   # Show full error reports and disable caching
   config.consider_all_requests_local       = true
   config.action_controller.perform_caching = false
@@ -22,15 +19,8 @@ ArvadosWorkbench::Application.configure do
   # Only use best-standards-support built into browsers
   config.action_dispatch.best_standards_support = :builtin
 
-  # Raise exception on mass assignment protection for Active Record models
-  config.active_record.mass_assignment_sanitizer = :strict
-
-  # Log the query plan for queries taking more than this (works
-  # with SQLite, MySQL, and PostgreSQL)
-  config.active_record.auto_explain_threshold_in_seconds = 0.5
-
   # Do not compress assets
-  config.assets.compress = false
+  config.assets.js_compressor = false
 
   # Expands the lines which load the assets
   config.assets.debug = true
index bb7595454e381abd82ff3f740802274320882503..209556cbf4731e190afe41d28651a68cd40d35c9 100644 (file)
@@ -12,7 +12,7 @@ ArvadosWorkbench::Application.configure do
   config.serve_static_assets = false
 
   # Compress JavaScripts and CSS
-  config.assets.compress = true
+  config.assets.js_compressor = :yui
 
   # Don't fallback to assets pipeline if a precompiled asset is missed
   config.assets.compile = false
@@ -61,10 +61,6 @@ ArvadosWorkbench::Application.configure do
   # Send deprecation notices to registered listeners
   config.active_support.deprecation = :notify
 
-  # Log the query plan for queries taking more than this (works
-  # with SQLite, MySQL, and PostgreSQL)
-  # config.active_record.auto_explain_threshold_in_seconds = 0.5
-
   # Log timing data for API transactions
   config.profiling_enabled = false
 
index b3cb72aff258b8d9b5946cc1cd9fa1865cfe4cd1..fd034d3185da7ce657cc46984b33fcc4cf4bdb1b 100644 (file)
@@ -11,9 +11,6 @@ ArvadosWorkbench::Application.configure do
   config.serve_static_assets = true
   config.static_cache_control = "public, max-age=3600"
 
-  # Log error messages when you accidentally call methods on nil
-  config.whiny_nils = true
-
   # Show full error reports and disable caching
   config.consider_all_requests_local       = true
   config.action_controller.perform_caching = false
@@ -29,9 +26,6 @@ ArvadosWorkbench::Application.configure do
   # ActionMailer::Base.deliveries array.
   config.action_mailer.delivery_method = :test
 
-  # Raise exception on mass assignment protection for Active Record models
-  config.active_record.mass_assignment_sanitizer = :strict
-
   # Print deprecation notices to the stderr
   config.active_support.deprecation = :stderr
 
diff --git a/apps/workbench/config/initializers/zzz_arvados_api_client.rb b/apps/workbench/config/initializers/zzz_arvados_api_client.rb
deleted file mode 100644 (file)
index 20ddd8c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# The client object must be instantiated _after_ zza_load_config.rb
-# runs, because it relies on configuration settings.
-#
-if not $application_config
-  raise "Fatal: Config must be loaded before instantiating ArvadosApiClient."
-end
-
-$arvados_api_client = ArvadosApiClient.new
index e8862c24267846a461708d9f43f1162df0e4dbfc..e0c93ec04bbdcd1fdac748c7c281cd29a168289c 100644 (file)
@@ -18,8 +18,8 @@ ArvadosWorkbench::Application.routes.draw do
   resources :authorized_keys
   resources :job_tasks
   resources :jobs
-  match '/logout' => 'sessions#destroy'
-  match '/logged_out' => 'sessions#index'
+  match '/logout' => 'sessions#destroy', via: [:get, :post]
+  get '/logged_out' => 'sessions#index'
   resources :users do
     get 'home', :on => :member
     get 'welcome', :on => :collection
@@ -39,7 +39,7 @@ ArvadosWorkbench::Application.routes.draw do
     get 'compare', on: :collection
   end
   resources :links
-  match '/collections/graph' => 'collections#graph'
+  get '/collections/graph' => 'collections#graph'
   resources :collections do
     post 'set_persistent', on: :member
   end
@@ -55,5 +55,5 @@ ArvadosWorkbench::Application.routes.draw do
 
   # Send unroutable requests to an arbitrary controller
   # (ends up at ApplicationController#render_not_found)
-  match '*a', :to => 'links#render_not_found'
+  match '*a', to: 'links#render_not_found', via: [:get, :post]
 end
index 6df7ee3a612f89785559067c60de381ccb061299..765156376feb8de6946e6b6e8d21d8b25c1483d5 100644 (file)
@@ -63,6 +63,7 @@ class UsersTest < ActionDispatch::IntegrationTest
       fill_in "email", :with => "foo@example.com"
       fill_in "repo_name", :with => "test_repo"
       click_button "Submit"
+      wait_for_ajax
     end
 
     visit '/users'
@@ -119,9 +120,9 @@ class UsersTest < ActionDispatch::IntegrationTest
       assert has_text? 'Virtual Machine'
       fill_in "repo_name", :with => "test_repo"
       click_button "Submit"
+      wait_for_ajax
     end
 
-    sleep(1)
     assert page.has_text? 'modified_by_client_uuid'
 
     click_link 'Metadata'
@@ -138,9 +139,9 @@ class UsersTest < ActionDispatch::IntegrationTest
       fill_in "repo_name", :with => "second_test_repo"
       select("testvm.shell", :from => 'vm_uuid')
       click_button "Submit"
+      wait_for_ajax
     end
 
-    sleep(0.1)
     assert page.has_text? 'modified_by_client_uuid'
 
     click_link 'Metadata'
@@ -203,9 +204,9 @@ class UsersTest < ActionDispatch::IntegrationTest
       fill_in "repo_name", :with => "second_test_repo"
       select("testvm.shell", :from => 'vm_uuid')
       click_button "Submit"
+      wait_for_ajax
     end
 
-    sleep(0.1)
     assert page.has_text? 'modified_by_client_uuid'
 
     click_link 'Metadata'
index 05be43cb5fe9fe7daeb1a224238f5411bc0c8b40..c1eed5cd7bf6b56412749c7e4a7170d643fd4075 100644 (file)
@@ -22,9 +22,6 @@ end
 require File.expand_path('../../config/environment', __FILE__)
 require 'rails/test_help'
 
-$ARV_API_SERVER_DIR = File.expand_path('../../../../services/api', __FILE__)
-SERVER_PID_PATH = 'tmp/pids/server.pid'
-
 class ActiveSupport::TestCase
   # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in
   # alphabetical order.
@@ -54,7 +51,8 @@ module ApiFixtureLoader
       # Returns the data structure from the named API server test fixture.
       @@api_fixtures[name] ||= \
       begin
-        path = File.join($ARV_API_SERVER_DIR, 'test', 'fixtures', "#{name}.yml")
+        path = File.join(ApiServerForTests::ARV_API_SERVER_DIR,
+                         'test', 'fixtures', "#{name}.yml")
         YAML.load(IO.read(path))
       end
     end
@@ -73,8 +71,13 @@ class ActiveSupport::TestCase
   end
 end
 
-class ApiServerBackedTestRunner < MiniTest::Unit
-  def _system(*cmd)
+class ApiServerForTests
+  ARV_API_SERVER_DIR = File.expand_path('../../../../services/api', __FILE__)
+  SERVER_PID_PATH = File.expand_path('tmp/pids/wbtest-server.pid', ARV_API_SERVER_DIR)
+  @main_process_pid = $$
+
+  def self._system(*cmd)
+    $stderr.puts "_system #{cmd.inspect}"
     Bundler.with_clean_env do
       if not system({'RAILS_ENV' => 'test'}, *cmd)
         raise RuntimeError, "#{cmd[0]} returned exit code #{$?.exitstatus}"
@@ -82,35 +85,66 @@ class ApiServerBackedTestRunner < MiniTest::Unit
     end
   end
 
-  def _run(args=[])
+  def self.make_ssl_cert
+    unless File.exists? './self-signed.key'
+      _system('openssl', 'req', '-new', '-x509', '-nodes',
+              '-out', './self-signed.pem',
+              '-keyout', './self-signed.key',
+              '-days', '3650',
+              '-subj', '/CN=localhost')
+    end
+  end
+
+  def self.kill_server
+    if (pid = find_server_pid)
+      $stderr.puts "Sending TERM to API server, pid #{pid}"
+      Process.kill 'TERM', pid
+    end
+  end
+
+  def self.find_server_pid
+    pid = nil
+    begin
+      pid = IO.read(SERVER_PID_PATH).to_i
+      $stderr.puts "API server is running, pid #{pid.inspect}"
+    rescue Errno::ENOENT
+    end
+    return pid
+  end
+
+  def self.run(args=[])
+    ::MiniTest.after_run do
+      self.kill_server
+    end
+
+    # Kill server left over from previous test run
+    self.kill_server
+
     Capybara.javascript_driver = :poltergeist
-    server_pid = Dir.chdir($ARV_API_SERVER_DIR) do |apidir|
+    Dir.chdir(ARV_API_SERVER_DIR) do |apidir|
       ENV["NO_COVERAGE_TEST"] = "1"
+      make_ssl_cert
       _system('bundle', 'exec', 'rake', 'db:test:load')
       _system('bundle', 'exec', 'rake', 'db:fixtures:load')
-      _system('bundle', 'exec', 'rails', 'server', '-d')
+      _system('bundle', 'exec', 'passenger', 'start', '-d', '-p3001',
+              '--pid-file', SERVER_PID_PATH,
+              '--ssl',
+              '--ssl-certificate', 'self-signed.pem',
+              '--ssl-certificate-key', 'self-signed.key')
       timeout = Time.now.tv_sec + 10
       good_pid = false
       while (not good_pid) and (Time.now.tv_sec < timeout)
         sleep 0.2
-        begin
-          server_pid = IO.read(SERVER_PID_PATH).to_i
-          good_pid = (server_pid > 0) and (Process.kill(0, server_pid) rescue false)
-        rescue Errno::ENOENT
-          good_pid = false
-        end
+        server_pid = find_server_pid
+        good_pid = (server_pid and
+                    (server_pid > 0) and
+                    (Process.kill(0, server_pid) rescue false))
       end
       if not good_pid
         raise RuntimeError, "could not find API server Rails pid"
       end
-      server_pid
-    end
-    begin
-      super(args)
-    ensure
-      Process.kill('TERM', server_pid)
     end
   end
 end
 
-MiniTest::Unit.runner = ApiServerBackedTestRunner.new
+ApiServerForTests.run
index eaf4edecdd8b2fe8c4f1fe28cffa5a205d9e7daa..055ef478923c5618484387e37824c230de548b63 100644 (file)
@@ -49,6 +49,17 @@ Alternatively, if you don't have sudo/root privileges on the host, install the g
 ~/arvados/apps/workbench$ <span class="userinput">bundle install --path=vendor/bundle</span>
 </code></pre></notextile>
 
+The @bundle install@ command might produce a warning about the themes_for_rails gem. This is OK:
+
+<notextile>
+<pre><code>themes_for_rails at /home/<b>you</b>/.rvm/gems/ruby-2.1.1/bundler/gems/themes_for_rails-1fd2d7897d75 did not have a valid gemspec.
+This prevents bundler from installing bins or native extensions, but that may not affect its functionality.
+The validation message from Rubygems was:
+  duplicate dependency on rails (= 3.0.11, development), (>= 3.0.0) use:
+    add_runtime_dependency 'rails', '= 3.0.11', '>= 3.0.0'
+Using themes_for_rails (0.5.1) from https://github.com/holtkampw/themes_for_rails (at 1fd2d78)
+</code></pre></notextile>
+
 h2. Configure the Workbench application
 
 This application needs a secret token. Generate a new secret: