From f5fc912b33e0d343b8ef88b543a3b5b0b1f3cf9b Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Fri, 28 Jul 2017 09:25:13 -0700 Subject: Exclude keys linked to other projects --- app/models/project.rb | 13 ++++++- .../unreleased/mk-fix-deploy-key-deletion.yml | 4 +++ spec/models/project_spec.rb | 42 +++++++++++++++++----- 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/mk-fix-deploy-key-deletion.yml diff --git a/app/models/project.rb b/app/models/project.rb index d827bfaa806..90967a12b96 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1265,7 +1265,18 @@ class Project < ActiveRecord::Base end def remove_private_deploy_keys - deploy_keys.where(public: false).delete_all + exclude_keys_linked_to_other_projects = <<-SQL + NOT EXISTS ( + SELECT 1 + FROM deploy_keys_projects dkp2 + WHERE dkp2.deploy_key_id = deploy_keys_projects.deploy_key_id + AND dkp2.project_id != deploy_keys_projects.project_id + ) + SQL + + deploy_keys.where(public: false) + .where(exclude_keys_linked_to_other_projects) + .delete_all end def remove_pages diff --git a/changelogs/unreleased/mk-fix-deploy-key-deletion.yml b/changelogs/unreleased/mk-fix-deploy-key-deletion.yml new file mode 100644 index 00000000000..9ff2e49b14c --- /dev/null +++ b/changelogs/unreleased/mk-fix-deploy-key-deletion.yml @@ -0,0 +1,4 @@ +--- +title: Fix deletion of deploy keys linked to other projects +merge_request: 13162 +author: diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 473b7a88d61..19808e7d36a 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2238,19 +2238,43 @@ describe Project do end describe '#remove_private_deploy_keys' do - it 'removes the private deploy keys of a project' do - project = create(:empty_project) + let!(:project) { create(:empty_project) } + + context 'for a private deploy key' do + let!(:key) { create(:deploy_key, public: false) } + let!(:deploy_keys_project) { create(:deploy_keys_project, deploy_key: key, project: project) } + + context 'when the key is not linked to another project' do + it 'removes the key' do + project.remove_private_deploy_keys + + expect(project.deploy_keys).not_to include(key) + end + end + + context 'when the key is linked to another project' do + before do + another_project = create(:empty_project) + create(:deploy_keys_project, deploy_key: key, project: another_project) + end - private_key = create(:deploy_key, public: false) - public_key = create(:deploy_key, public: true) + it 'does not remove the key' do + project.remove_private_deploy_keys - create(:deploy_keys_project, deploy_key: private_key, project: project) - create(:deploy_keys_project, deploy_key: public_key, project: project) + expect(project.deploy_keys).to include(key) + end + end + end + + context 'for a public deploy key' do + let!(:key) { create(:deploy_key, public: true) } + let!(:deploy_keys_project) { create(:deploy_keys_project, deploy_key: key, project: project) } - project.remove_private_deploy_keys + it 'does not remove the key' do + project.remove_private_deploy_keys - expect(project.deploy_keys.where(public: false).any?).to eq(false) - expect(project.deploy_keys.where(public: true).any?).to eq(true) + expect(project.deploy_keys).to include(key) + end end end end -- cgit v1.2.1