[ARVADOS] updated: 754913fc3e5037903048863f5545c9512fbf7bfc

Git user git at public.curoverse.com
Thu Oct 20 15:16:08 EDT 2016


Summary of changes:
 services/api/app/models/container.rb               | 43 +++++-----
 .../test/fixtures/api_client_authorizations.yml    |  7 ++
 services/api/test/fixtures/collections.yml         | 13 +++
 services/api/test/unit/container_test.rb           | 92 ++++++++++++++++++----
 4 files changed, 116 insertions(+), 39 deletions(-)

       via  754913fc3e5037903048863f5545c9512fbf7bfc (commit)
      from  d71020ac08d7b6e84d2d8f8d2c9b22d512144baa (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 754913fc3e5037903048863f5545c9512fbf7bfc
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Oct 20 15:16:00 2016 -0400

    10172: Tests and related fixes for auth_uuid setting output on container.

diff --git a/services/api/app/models/container.rb b/services/api/app/models/container.rb
index 6b5bc4f..a3057d6 100644
--- a/services/api/app/models/container.rb
+++ b/services/api/app/models/container.rb
@@ -187,7 +187,23 @@ class Container < ArvadosModel
   end
 
   def permission_to_update
-    current_user.andand.is_admin
+    # Override base permission check to allow auth_uuid to set progress and
+    # output (only).  Whether it is legal to set progress and output in the current
+    # state has already been checked in validate_change.
+    current_user.andand.is_admin ||
+      (!Thread.current[:api_client_authorization].nil? and
+       [self.auth_uuid, self.locked_by_uuid].include? Thread.current[:api_client_authorization].uuid)
+  end
+
+  def ensure_owner_uuid_is_permitted
+    # Override base permission check to allow auth_uuid to set progress and
+    # output (only).  Whether it is legal to set progress and output in the current
+    # state has already been checked in validate_change.
+    if !Thread.current[:api_client_authorization].nil? and self.auth_uuid == Thread.current[:api_client_authorization].uuid
+      check_update_whitelist [:progress, :output]
+    else
+      super
+    end
   end
 
   def set_timestamps
@@ -241,20 +257,10 @@ class Container < ArvadosModel
   end
 
   def validate_lock
-    if locked_by_uuid_was
-      if not [locked_by_uuid_was, auth_uuid].include? Thread.current[:api_client_authorization].uuid
-        # The container is locked, but is being accessed by an API token that
-        # isn't associated with the container.  Only the priority field may be
-        # updated, needed when updating to max(priority) of relevant
-        # ContainerRequests.
-        check_update_whitelist [:priority]
-      end
-    end
-
     if [Locked, Running].include? self.state
       # If the Container was already locked, locked_by_uuid must not
       # changes. Otherwise, the current auth gets the lock.
-      need_lock = locked_by_uuid_was || Thread.current[:api_client_authorization].uuid
+      need_lock = locked_by_uuid_was || Thread.current[:api_client_authorization].andand.uuid
     else
       need_lock = nil
     end
@@ -280,7 +286,7 @@ class Container < ArvadosModel
           where(portable_data_hash: self.output).
           first
       if !c
-        return errors.add :output, "collection must exist and be readable by current user."
+        errors.add :output, "collection must exist and be readable by current user."
       end
     end
   end
@@ -322,17 +328,6 @@ class Container < ArvadosModel
     end
   end
 
-  def ensure_owner_uuid_is_permitted
-    # Override base permission check to allow auth_uuid to set progress and
-    # output (only).  Whether it is legal to set progress and output in the current
-    # state has already been checked in validate_change.
-    if self.auth_uuid == Thread.current[:api_client_authorization].uuid
-      check_update_whitelist [:progress, :output]
-    else
-      super
-    end
-  end
-
   def handle_completed
     # This container is finished so finalize any associated container requests
     # that are associated with this container.
diff --git a/services/api/test/fixtures/api_client_authorizations.yml b/services/api/test/fixtures/api_client_authorizations.yml
index 7af4f37..0b5baf3 100644
--- a/services/api/test/fixtures/api_client_authorizations.yml
+++ b/services/api/test/fixtures/api_client_authorizations.yml
@@ -291,3 +291,10 @@ running_container_auth:
   user: active
   api_token: 3kg6k6lzmp9kj6bpkcoxie963cmvjahbt2fod9zru30k1jqdmi
   expires_at: 2038-01-01 00:00:00
+
+not_running_container_auth:
+  uuid: zzzzz-gj3su-077z32aux8dg2s3
+  api_client: untrusted
+  user: active
+  api_token: 4kg6k6lzmp9kj6bpkcoxie963cmvjahbt2fod9zru30k1jqdmj
+  expires_at: 2038-01-01 00:00:00
diff --git a/services/api/test/fixtures/collections.yml b/services/api/test/fixtures/collections.yml
index b1154a8..289080c 100644
--- a/services/api/test/fixtures/collections.yml
+++ b/services/api/test/fixtures/collections.yml
@@ -553,6 +553,19 @@ collection_with_several_unsupported_file_types:
   manifest_text: ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:file 0:0:file.bam\n"
   name: collection_with_several_unsupported_file_types
 
+collection_not_readable_by_active:
+  uuid: zzzzz-4zz18-cd42uwvy3neko21
+  portable_data_hash: bb89eb5140e2848d39b416daeef4ffc5+45
+  owner_uuid: zzzzz-tpzed-000000000000000
+  created_at: 2014-02-03T17:22:54Z
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f
+  modified_at: 2014-02-03T17:22:54Z
+  updated_at: 2014-02-03T17:22:54Z
+  manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
+  name: owned_by_active
+
+
 # Test Helper trims the rest of the file
 
 # Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper
diff --git a/services/api/test/unit/container_test.rb b/services/api/test/unit/container_test.rb
index 8894ed9..ebd98e6 100644
--- a/services/api/test/unit/container_test.rb
+++ b/services/api/test/unit/container_test.rb
@@ -5,13 +5,13 @@ class ContainerTest < ActiveSupport::TestCase
 
   DEFAULT_ATTRS = {
     command: ['echo', 'foo'],
-    container_image: 'img',
+    container_image: 'fa3c1a9cb6783f85f2ecda037e07b8c3+167',
     output_path: '/tmp',
     priority: 1,
     runtime_constraints: {"vcpus" => 1, "ram" => 1},
   }
 
-  REUSABLE_COMMON_ATTRS = {container_image: "test",
+  REUSABLE_COMMON_ATTRS = {container_image: "9ae44d5792468c58bcf85ce7353c7027+124",
                            cwd: "test",
                            command: ["echo", "hello"],
                            output_path: "test",
@@ -22,16 +22,12 @@ class ContainerTest < ActiveSupport::TestCase
 
   def minimal_new attrs={}
     cr = ContainerRequest.new DEFAULT_ATTRS.merge(attrs)
+    cr.state = ContainerRequest::Committed
     act_as_user users(:active) do
       cr.save!
     end
-    c = Container.new DEFAULT_ATTRS.merge(attrs)
-    act_as_system_user do
-      c.save!
-      assert cr.update_attributes(container_uuid: c.uuid,
-                                  state: ContainerRequest::Committed,
-                                  ), show_errors(cr)
-    end
+    c = Container.find_by_uuid cr.container_uuid
+    assert_not_nil c
     return c, cr
   end
 
@@ -45,7 +41,7 @@ class ContainerTest < ActiveSupport::TestCase
 
   def check_illegal_modify c
     check_illegal_updates c, [{command: ["echo", "bar"]},
-                              {container_image: "img2"},
+                              {container_image: "arvados/apitestfixture:june10"},
                               {cwd: "/tmp2"},
                               {environment: {"FOO" => "BAR"}},
                               {mounts: {"FOO" => "BAR"}},
@@ -89,7 +85,7 @@ class ContainerTest < ActiveSupport::TestCase
 
   test "Container serialized hash attributes sorted before save" do
     env = {"C" => 3, "B" => 2, "A" => 1}
-    m = {"F" => 3, "E" => 2, "D" => 1}
+    m = {"F" => {"kind" => 3}, "E" => {"kind" => 2}, "D" => {"kind" => 1}}
     rc = {"vcpus" => 1, "ram" => 1}
     c, _ = minimal_new(environment: env, mounts: m, runtime_constraints: rc)
     assert_equal c.environment.to_json, Container.deep_sort_hash(env).to_json
@@ -144,17 +140,28 @@ class ContainerTest < ActiveSupport::TestCase
 
   test "find_reusable method should not select completed container when inconsistent outputs exist" do
     set_user_from_auth :active
-    common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "complete"}})
+    common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "complete"}, priority: 1})
     completed_attrs = {
       state: Container::Complete,
       exit_code: 0,
       log: 'ea10d51bcf88862dbcc36eb292017dfd+45',
     }
 
-    c_output1, _ = minimal_new(common_attrs)
-    c_output2, _ = minimal_new(common_attrs)
-
     set_user_from_auth :dispatch1
+
+    c_output1 = Container.create common_attrs
+    c_output2 = Container.create common_attrs
+
+    cr = ContainerRequest.new common_attrs
+    cr.state = ContainerRequest::Committed
+    cr.container_uuid = c_output1.uuid
+    cr.save!
+
+    cr = ContainerRequest.new common_attrs
+    cr.state = ContainerRequest::Committed
+    cr.container_uuid = c_output2.uuid
+    cr.save!
+
     c_output1.update_attributes!({state: Container::Locked})
     c_output1.update_attributes!({state: Container::Running})
     c_output1.update_attributes!(completed_attrs.merge({output: '1f4b0bc7583c2a7f9102c395f4ffc5e3+45'}))
@@ -427,4 +434,59 @@ class ContainerTest < ActiveSupport::TestCase
 
     assert c.update_attributes(exit_code: 1, state: Container::Complete)
   end
+
+  test "locked_by_uuid can set output on running container" do
+    c, _ = minimal_new
+    set_user_from_auth :dispatch1
+    c.lock
+    c.update_attributes! state: Container::Running
+
+    assert_equal c.locked_by_uuid, Thread.current[:api_client_authorization].uuid
+
+    assert c.update_attributes output: collections(:collection_owned_by_active).portable_data_hash
+    assert c.update_attributes! state: Container::Complete
+  end
+
+  test "auth_uuid can set output on running container, but not change container state" do
+    c, _ = minimal_new
+    set_user_from_auth :dispatch1
+    c.lock
+    c.update_attributes! state: Container::Running
+
+    Thread.current[:api_client_authorization] = ApiClientAuthorization.find_by_uuid(c.auth_uuid)
+    Thread.current[:user] = User.find_by_id(Thread.current[:api_client_authorization].user_id)
+    assert c.update_attributes output: collections(:collection_owned_by_active).portable_data_hash
+
+    assert_raises ArvadosModel::PermissionDeniedError do
+      # auth_uuid cannot set container state
+      c.update_attributes state: Container::Complete
+    end
+  end
+
+  test "output must be readable by auth_uuid" do
+    c, _ = minimal_new
+    set_user_from_auth :dispatch1
+    c.lock
+    c.update_attributes! state: Container::Running
+
+    Thread.current[:api_client_authorization] = ApiClientAuthorization.find_by_uuid(c.auth_uuid)
+    Thread.current[:user] = User.find_by_id(Thread.current[:api_client_authorization].user_id)
+
+    assert_raises ActiveRecord::RecordInvalid do
+      c.update_attributes! output: collections(:collection_not_readable_by_active).portable_data_hash
+    end
+  end
+
+  test "other token cannot set output on running container" do
+    c, _ = minimal_new
+    set_user_from_auth :dispatch1
+    c.lock
+    c.update_attributes! state: Container::Running
+
+    set_user_from_auth :not_running_container_auth
+    assert_raises ArvadosModel::PermissionDeniedError do
+      c.update_attributes! output: collections(:foo_file).portable_data_hash
+    end
+  end
+
 end

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list