summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-10-05 07:42:12 +0000
committerRémy Coutable <remy@rymai.me>2016-10-05 16:42:26 +0200
commit07602af16360329aa8af1f2091e156c9c92bdf03 (patch)
tree6d60bdfce1a847621a4efab2e81239c6af9cc6c1
parent9264816a34c45fb36c0117fe95bdf9e9af3287c8 (diff)
downloadgitlab-ce-07602af16360329aa8af1f2091e156c9c92bdf03.tar.gz
Merge branch 'sh-fix-project-deletion-private-visibility' into 'master'
Fix project deletion when feature visibility is set to private Projects that are destroyed are put in the pending_delete state. The ProjectDestroyWorker checks whether the current user has access, but since the ProjectFeature class uses the default scope of the Project, it will not be able to find the right project. This was a regression in 8.12 that caused the following stack trace: ``` NoMethodError: undefined method `team' for nil:NilClass from app/models/project_feature.rb:62:in `get_permission' from app/models/project_feature.rb:34:in `feature_available?' from app/models/project.rb:21:in `feature_available?' from app/policies/project_policy.rb:170:in `disabled_features!' from app/policies/project_policy.rb:29:in `rules' from app/policies/base_policy.rb:82:in `block in abilities' from app/policies/base_policy.rb:113:in `collect_rules' from app/policies/base_policy.rb:82:in `abilities' from app/policies/base_policy.rb:50:in `abilities' from app/models/ability.rb:64:in `uncached_allowed' from app/models/ability.rb:58:in `allowed' from app/models/ability.rb:49:in `allowed?' from app/services/base_service.rb:11:in `can?' from lib/gitlab/metrics/instrumentation.rb:155:in `block in can?' from lib/gitlab/metrics/method_call.rb:23:in `measure' from lib/gitlab/metrics/instrumentation.rb:155:in `can?' from app/services/projects/destroy_service.rb:18:in `execute' ``` Closes #22948 See merge request !6688 Signed-off-by: Rémy Coutable <remy@rymai.me>
-rw-r--r--CHANGELOG1
-rw-r--r--app/models/project_feature.rb5
-rw-r--r--spec/services/projects/destroy_service_spec.rb23
3 files changed, 27 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6813fd3bdf8..db972d55a61 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@ v 8.12.4 (unreleased)
- Fix lint-doc error. !6623
- Skip wiki creation when GitHub project has wiki enabled. !6665
- Restrict failed login attempts for users with 2FA enabled. !6668
+ - Fix failed project deletion when feature visibility set to private. !6688
v 8.12.3
- Update Gitlab Shell to support low IO priority for storage moves
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index 8c9534c3565..530f7d5a30e 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -20,7 +20,10 @@ class ProjectFeature < ActiveRecord::Base
FEATURES = %i(issues merge_requests wiki snippets builds)
- belongs_to :project
+ # Default scopes force us to unscope here since a service may need to check
+ # permissions for a project in pending_delete
+ # http://stackoverflow.com/questions/1540645/how-to-disable-default-scope-for-a-belongs-to
+ belongs_to :project, -> { unscope(where: :pending_delete) }
default_value_for :builds_access_level, value: ENABLED, allows_nil: false
default_value_for :issues_access_level, value: ENABLED, allows_nil: false
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 29341c5e57e..7dcd03496bb 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -5,6 +5,7 @@ describe Projects::DestroyService, services: true do
let!(:project) { create(:project, namespace: user.namespace) }
let!(:path) { project.repository.path_to_repo }
let!(:remove_path) { path.sub(/\.git\Z/, "+#{project.id}+deleted.git") }
+ let!(:async) { false } # execute or async_execute
context 'Sidekiq inline' do
before do
@@ -28,6 +29,22 @@ describe Projects::DestroyService, services: true do
it { expect(Dir.exist?(remove_path)).to be_truthy }
end
+ context 'async delete of project with private issue visibility' do
+ let!(:async) { true }
+
+ before do
+ project.project_feature.update_attribute("issues_access_level", ProjectFeature::PRIVATE)
+ # Run sidekiq immediately to check that renamed repository will be removed
+ Sidekiq::Testing.inline! { destroy_project(project, user, {}) }
+ end
+
+ it 'deletes the project' do
+ expect(Project.all).not_to include(project)
+ expect(Dir.exist?(path)).to be_falsey
+ expect(Dir.exist?(remove_path)).to be_falsey
+ end
+ end
+
context 'container registry' do
before do
stub_container_registry_config(enabled: true)
@@ -52,6 +69,10 @@ describe Projects::DestroyService, services: true do
end
def destroy_project(project, user, params)
- Projects::DestroyService.new(project, user, params).execute
+ if async
+ Projects::DestroyService.new(project, user, params).async_execute
+ else
+ Projects::DestroyService.new(project, user, params).execute
+ end
end
end