Commit bc4d0a8c authored by Etienne Baqué's avatar Etienne Baqué

Merge branch 'vij-cr-storage-quota' into 'master'

Handle auth error for container registry

See merge request gitlab-org/gitlab!83278
parents 5247f187 4142c344
......@@ -5,6 +5,19 @@ module EE
module ContainerRegistryAuthenticationService
extend ::Gitlab::Utils::Override
StorageError = Class.new(StandardError)
override :execute
def execute(authentication_abilities:)
super
rescue StorageError
error(
'DENIED',
status: 403,
message: 'You are above your storage quota! Visit https://docs.gitlab.com/ee/user/usage_quotas.html to learn more.'
)
end
private
override :can_access?
......@@ -14,6 +27,8 @@ module EE
return false
end
raise StorageError if storage_error?(requested_project, requested_action)
super
end
......@@ -30,6 +45,13 @@ module EE
def access_denied_in_maintenance_mode?
@access_denied_in_maintenance_mode
end
def storage_error?(project, action)
return false unless project
return false unless action == 'push'
project.root_ancestor.over_storage_limit?
end
end
end
end
......@@ -53,4 +53,82 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
context 'when not in maintenance mode' do
it_behaves_like 'a container registry auth service'
end
context 'when over storage limit' do
include_context 'container registry auth service context'
let_it_be(:current_user) { create(:user) }
let_it_be(:namespace) { create(:group) }
before do
allow_next_found_instance_of(Project) do |instance|
allow(instance).to receive(:root_ancestor).and_return namespace
end
allow(namespace).to receive(:over_storage_limit?).and_return true
end
context 'when there is a project' do
let_it_be(:project) { create(:project, namespace: namespace) }
before do
project.add_developer(current_user)
end
shared_examples 'storage error' do
it 'returns an appropriate response' do
expect(subject[:errors].first).to include(
code: 'DENIED',
message: 'You are above your storage quota! Visit https://docs.gitlab.com/ee/user/usage_quotas.html to learn more.'
)
end
end
context 'does not allow developer to push images' do
context 'when only pushing an image' do
let(:current_params) do
{ scopes: ["repository:#{project.full_path}:push"] }
end
it_behaves_like 'not a container repository factory' do
it_behaves_like 'storage error'
end
end
context 'when performing multiple actions including push' do
let(:current_params) do
{ scopes: ["repository:#{project.full_path}:push,pull"] }
end
it_behaves_like 'not a container repository factory' do
it_behaves_like 'storage error'
end
end
end
context 'allows developers to pull images' do
let(:current_params) do
{ scopes: ["repository:#{project.full_path}:pull"] }
end
it_behaves_like 'a pullable'
end
context 'allows maintainers to delete images' do
before do
project.add_maintainer(current_user)
end
it_behaves_like 'allowed to delete container repository images'
end
end
context 'when there is no project' do
let(:project) { nil }
it 'does not return a storage error' do
expect(subject[:errors]).to be_nil
end
end
end
end
......@@ -154,6 +154,30 @@ RSpec.shared_examples 'logs an auth warning' do |requested_actions|
end
end
RSpec.shared_examples 'allowed to delete container repository images' do
let(:authentication_abilities) do
[:admin_container_image]
end
it_behaves_like 'a valid token'
context 'allow to delete images' do
let(:current_params) do
{ scopes: ["repository:#{project.full_path}:*"] }
end
it_behaves_like 'a deletable'
end
context 'allow to delete images since registry 2.7' do
let(:current_params) do
{ scopes: ["repository:#{project.full_path}:delete"] }
end
it_behaves_like 'a deletable since registry 2.7'
end
end
RSpec.shared_examples 'a container registry auth service' do
include_context 'container registry auth service context'
......@@ -544,38 +568,14 @@ RSpec.shared_examples 'a container registry auth service' do
end
context 'delete authorized as maintainer' do
let_it_be(:current_project) { create(:project) }
let_it_be(:project) { create(:project) }
let_it_be(:current_user) { create(:user) }
let(:authentication_abilities) do
[:admin_container_image]
end
before_all do
current_project.add_maintainer(current_user)
end
it_behaves_like 'a valid token'
context 'allow to delete images' do
let(:current_params) do
{ scopes: ["repository:#{current_project.full_path}:*"] }
end
it_behaves_like 'a deletable' do
let(:project) { current_project }
end
project.add_maintainer(current_user)
end
context 'allow to delete images since registry 2.7' do
let(:current_params) do
{ scopes: ["repository:#{current_project.full_path}:delete"] }
end
it_behaves_like 'a deletable since registry 2.7' do
let(:project) { current_project }
end
end
it_behaves_like 'allowed to delete container repository images'
end
context 'build authorized as user' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment