From 484370cbfe47b04e1d4222dd4a7606171c87a324 Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Fri, 17 Feb 2017 16:17:26 -0500 Subject: [PATCH] 11127: Delete dependent links too when emptying trash. --- services/api/app/models/arvados_model.rb | 6 +++++- services/api/lib/has_uuid.rb | 4 ++-- services/api/test/unit/collection_test.rb | 16 +++++++++++++++ services/api/test/unit/link_test.rb | 24 ++++++++++++++++------- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/services/api/app/models/arvados_model.rb b/services/api/app/models/arvados_model.rb index fd542ca909..b2e1bea3ab 100644 --- a/services/api/app/models/arvados_model.rb +++ b/services/api/app/models/arvados_model.rb @@ -32,7 +32,11 @@ class ArvadosModel < ActiveRecord::Base # Note: This only returns permission links. It does not account for # permissions obtained via user.is_admin or # user.uuid==object.owner_uuid. - has_many :permissions, :foreign_key => :head_uuid, :class_name => 'Link', :primary_key => :uuid, :conditions => "link_class = 'permission'" + has_many(:permissions, + foreign_key: :head_uuid, + class_name: 'Link', + primary_key: :uuid, + conditions: "link_class = 'permission'") class PermissionDeniedError < StandardError def http_status diff --git a/services/api/lib/has_uuid.rb b/services/api/lib/has_uuid.rb index e0a56134fc..36c087986e 100644 --- a/services/api/lib/has_uuid.rb +++ b/services/api/lib/has_uuid.rb @@ -7,8 +7,8 @@ module HasUuid base.validate :validate_uuid base.before_create :assign_uuid base.before_destroy :destroy_permission_links - base.has_many :links_via_head, class_name: 'Link', foreign_key: :head_uuid, primary_key: :uuid, conditions: "not (link_class = 'permission')", dependent: :restrict - base.has_many :links_via_tail, class_name: 'Link', foreign_key: :tail_uuid, primary_key: :uuid, conditions: "not (link_class = 'permission')", dependent: :restrict + base.has_many :links_via_head, class_name: 'Link', foreign_key: :head_uuid, primary_key: :uuid, conditions: "not (link_class = 'permission')", dependent: :destroy + base.has_many :links_via_tail, class_name: 'Link', foreign_key: :tail_uuid, primary_key: :uuid, conditions: "not (link_class = 'permission')", dependent: :destroy end module ClassMethods diff --git a/services/api/test/unit/collection_test.rb b/services/api/test/unit/collection_test.rb index 4984aad88b..87bec21520 100644 --- a/services/api/test/unit/collection_test.rb +++ b/services/api/test/unit/collection_test.rb @@ -493,4 +493,20 @@ class CollectionTest < ActiveSupport::TestCase SweepTrashedCollections.sweep_now assert_empty Collection.unscoped.where(uuid: uuid) end + + test "delete referring links in SweepTrashedCollections" do + uuid = collections(:trashed_on_next_sweep).uuid + act_as_system_user do + Link.create!(head_uuid: uuid, + tail_uuid: system_user_uuid, + link_class: 'whatever', + name: 'something') + end + past = db_current_time + Collection.unscoped.where(uuid: uuid). + update_all(is_trashed: true, trash_at: past, delete_at: past) + assert_not_empty Collection.unscoped.where(uuid: uuid) + SweepTrashedCollections.sweep_now + assert_empty Collection.unscoped.where(uuid: uuid) + end end diff --git a/services/api/test/unit/link_test.rb b/services/api/test/unit/link_test.rb index 16ce54bbe0..64c98857ba 100644 --- a/services/api/test/unit/link_test.rb +++ b/services/api/test/unit/link_test.rb @@ -7,17 +7,27 @@ class LinkTest < ActiveSupport::TestCase set_user_from_auth :admin_trustedclient end - test "cannot delete an object referenced by links" do - ob = Specimen.create - link = Link.create(tail_uuid: users(:active).uuid, - head_uuid: ob.uuid, - link_class: 'test', - name: 'test') + test "cannot delete an object referenced by unwritable links" do + ob = act_as_user users(:active) do + Specimen.create + end + link = act_as_user users(:admin) do + Link.create(tail_uuid: users(:active).uuid, + head_uuid: ob.uuid, + link_class: 'test', + name: 'test') + end assert_equal users(:admin).uuid, link.owner_uuid - assert_raises(ActiveRecord::DeleteRestrictionError, + assert_raises(ArvadosModel::PermissionDeniedError, "should not delete #{ob.uuid} with link #{link.uuid}") do + act_as_user users(:active) do + ob.destroy + end + end + act_as_user users(:admin) do ob.destroy end + assert_empty Link.where(uuid: link.uuid) end def new_active_link_valid?(link_attrs) -- 2.39.5