Commit 62ef67ac authored by Robin Bobbitt's avatar Robin Bobbitt

Hide read_registry scope when registry is disabled on instance

parent e6d87021
...@@ -28,7 +28,7 @@ class PersonalAccessToken < ActiveRecord::Base ...@@ -28,7 +28,7 @@ class PersonalAccessToken < ActiveRecord::Base
protected protected
def validate_scopes def validate_scopes
unless scopes.all? { |scope| Gitlab::Auth::AVAILABLE_SCOPES.include?(scope.to_sym) } unless revoked || scopes.all? { |scope| Gitlab::Auth::AVAILABLE_SCOPES.include?(scope.to_sym) }
errors.add :scopes, "can only contain available scopes" errors.add :scopes, "can only contain available scopes"
end end
end end
......
---
title: Hide read_registry scope when registry is disabled on instance
merge_request: 13314
author: Robin Bobbitt
...@@ -2,7 +2,7 @@ module Gitlab ...@@ -2,7 +2,7 @@ module Gitlab
module Auth module Auth
MissingPersonalTokenError = Class.new(StandardError) MissingPersonalTokenError = Class.new(StandardError)
REGISTRY_SCOPES = [:read_registry].freeze REGISTRY_SCOPES = Gitlab.config.registry.enabled ? [:read_registry].freeze : [].freeze
# Scopes used for GitLab API access # Scopes used for GitLab API access
API_SCOPES = [:api, :read_user].freeze API_SCOPES = [:api, :read_user].freeze
......
...@@ -17,13 +17,33 @@ describe Gitlab::Auth do ...@@ -17,13 +17,33 @@ describe Gitlab::Auth do
end end
it 'OPTIONAL_SCOPES contains all non-default scopes' do it 'OPTIONAL_SCOPES contains all non-default scopes' do
stub_container_registry_config(enabled: true)
expect(subject::OPTIONAL_SCOPES).to eq %i[read_user read_registry openid] expect(subject::OPTIONAL_SCOPES).to eq %i[read_user read_registry openid]
end end
it 'REGISTRY_SCOPES contains all registry related scopes' do context 'REGISTRY_SCOPES' do
context 'when registry is disabled' do
before do
stub_container_registry_config(enabled: false)
end
it 'is empty' do
expect(subject::REGISTRY_SCOPES).to eq []
end
end
context 'when registry is enabled' do
before do
stub_container_registry_config(enabled: true)
end
it 'contains all registry related scopes' do
expect(subject::REGISTRY_SCOPES).to eq %i[read_registry] expect(subject::REGISTRY_SCOPES).to eq %i[read_registry]
end end
end end
end
end
describe 'find_for_git_client' do describe 'find_for_git_client' do
context 'build token' do context 'build token' do
...@@ -147,12 +167,18 @@ describe Gitlab::Auth do ...@@ -147,12 +167,18 @@ describe Gitlab::Auth do
expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, full_authentication_abilities)) expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, full_authentication_abilities))
end end
context 'when registry is enabled' do
before do
stub_container_registry_config(enabled: true)
end
it 'succeeds for personal access tokens with the `read_registry` scope' do it 'succeeds for personal access tokens with the `read_registry` scope' do
personal_access_token = create(:personal_access_token, scopes: ['read_registry']) personal_access_token = create(:personal_access_token, scopes: ['read_registry'])
expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '')
expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, [:read_container_image])) expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, [:read_container_image]))
end end
end
it 'succeeds if it is an impersonation token' do it 'succeeds if it is an impersonation token' do
impersonation_token = create(:personal_access_token, :impersonation, scopes: ['api']) impersonation_token = create(:personal_access_token, :impersonation, scopes: ['api'])
......
...@@ -41,7 +41,7 @@ describe PersonalAccessToken do ...@@ -41,7 +41,7 @@ describe PersonalAccessToken do
it 'revokes the token' do it 'revokes the token' do
active_personal_access_token.revoke! active_personal_access_token.revoke!
expect(active_personal_access_token.revoked?).to be true expect(active_personal_access_token).to be_revoked
end end
end end
...@@ -61,11 +61,38 @@ describe PersonalAccessToken do ...@@ -61,11 +61,38 @@ describe PersonalAccessToken do
expect(personal_access_token).to be_valid expect(personal_access_token).to be_valid
end end
context 'when registry is disabled' do
before do
stub_container_registry_config(enabled: false)
end
it "rejects creating a token with read_registry scope" do
personal_access_token.scopes = [:read_registry]
expect(personal_access_token).not_to be_valid
expect(personal_access_token.errors[:scopes].first).to eq "can only contain available scopes"
end
it "allows revoking a token with read_registry scope" do
personal_access_token.scopes = [:read_registry]
personal_access_token.revoke!
expect(personal_access_token).to be_revoked
end
end
context 'when registry is enabled' do
before do
stub_container_registry_config(enabled: true)
end
it "allows creating a token with read_registry scope" do it "allows creating a token with read_registry scope" do
personal_access_token.scopes = [:read_registry] personal_access_token.scopes = [:read_registry]
expect(personal_access_token).to be_valid expect(personal_access_token).to be_valid
end end
end
it "rejects creating a token with unavailable scopes" do it "rejects creating a token with unavailable scopes" do
personal_access_token.scopes = [:openid, :api] personal_access_token.scopes = [:openid, :api]
......
...@@ -49,6 +49,10 @@ describe JwtController do ...@@ -49,6 +49,10 @@ describe JwtController do
let(:pat) { create(:personal_access_token, user: user, scopes: ['read_registry']) } let(:pat) { create(:personal_access_token, user: user, scopes: ['read_registry']) }
let(:headers) { { authorization: credentials('personal_access_token', pat.token) } } let(:headers) { { authorization: credentials('personal_access_token', pat.token) } }
before do
stub_container_registry_config(enabled: true)
end
subject! { get '/jwt/auth', parameters, headers } subject! { get '/jwt/auth', parameters, headers }
it 'authenticates correctly' do it 'authenticates correctly' do
......
...@@ -23,6 +23,10 @@ shared_examples_for 'allows the "read_user" scope' do ...@@ -23,6 +23,10 @@ shared_examples_for 'allows the "read_user" scope' do
context 'when the requesting token does not have any required scope' do context 'when the requesting token does not have any required scope' do
let(:token) { create(:personal_access_token, scopes: ['read_registry'], user: user) } let(:token) { create(:personal_access_token, scopes: ['read_registry'], user: user) }
before do
stub_container_registry_config(enabled: true)
end
it 'returns a "401" response' do it 'returns a "401" response' do
get api_call.call(path, user, personal_access_token: token) get api_call.call(path, user, personal_access_token: token)
......
...@@ -26,9 +26,11 @@ module StubGitlabCalls ...@@ -26,9 +26,11 @@ module StubGitlabCalls
end end
def stub_container_registry_config(registry_settings) def stub_container_registry_config(registry_settings)
allow(Gitlab.config.registry).to receive_messages(registry_settings)
allow(Auth::ContainerRegistryAuthenticationService) allow(Auth::ContainerRegistryAuthenticationService)
.to receive(:full_access_token).and_return('token') .to receive(:full_access_token).and_return('token')
allow(Gitlab.config.registry).to receive_messages(registry_settings)
load 'lib/gitlab/auth.rb'
end end
def stub_container_registry_tags(repository: :any, tags:) def stub_container_registry_tags(repository: :any, tags:)
......
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