diff options
author | Rémy Coutable <remy@rymai.me> | 2016-10-05 07:42:12 +0000 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2016-10-05 16:42:26 +0200 |
commit | 07602af16360329aa8af1f2091e156c9c92bdf03 (patch) | |
tree | 6d60bdfce1a847621a4efab2e81239c6af9cc6c1 | |
parent | 9264816a34c45fb36c0117fe95bdf9e9af3287c8 (diff) | |
download | gitlab-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-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/models/project_feature.rb | 5 | ||||
-rw-r--r-- | spec/services/projects/destroy_service_spec.rb | 23 |
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 |