Commit 32042ef5 authored by Alejandro Rodriguez's avatar Alejandro Rodriguez Committed by Rémy Coutable

Merge branch 'unauthenticated-container-registry-access' into 'security'

Restore unauthenticated access to public container registries

Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/24284

See merge request !2025
Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent b0088b52
...@@ -12,7 +12,7 @@ class JwtController < ApplicationController ...@@ -12,7 +12,7 @@ class JwtController < ApplicationController
return head :not_found unless service return head :not_found unless service
result = service.new(@authentication_result.project, @authentication_result.actor, auth_params). result = service.new(@authentication_result.project, @authentication_result.actor, auth_params).
execute(authentication_abilities: @authentication_result.authentication_abilities || []) execute(authentication_abilities: @authentication_result.authentication_abilities)
render json: result, status: result[:http_status] render json: result, status: result[:http_status]
end end
...@@ -20,7 +20,7 @@ class JwtController < ApplicationController ...@@ -20,7 +20,7 @@ class JwtController < ApplicationController
private private
def authenticate_project_or_user def authenticate_project_or_user
@authentication_result = Gitlab::Auth::Result.new @authentication_result = Gitlab::Auth::Result.new(nil, nil, :none, Gitlab::Auth.read_authentication_abilities)
authenticate_with_http_basic do |login, password| authenticate_with_http_basic do |login, password|
@authentication_result = Gitlab::Auth.find_for_git_client(login, password, project: nil, ip: request.ip) @authentication_result = Gitlab::Auth.find_for_git_client(login, password, project: nil, ip: request.ip)
......
...@@ -9,8 +9,8 @@ module Auth ...@@ -9,8 +9,8 @@ module Auth
return error('UNAVAILABLE', status: 404, message: 'registry not enabled') unless registry.enabled return error('UNAVAILABLE', status: 404, message: 'registry not enabled') unless registry.enabled
unless current_user || project unless scope || current_user || project
return error('DENIED', status: 403, message: 'access forbidden') unless scope return error('DENIED', status: 403, message: 'access forbidden')
end end
{ token: authorized_token(scope).encoded } { token: authorized_token(scope).encoded }
...@@ -92,23 +92,23 @@ module Auth ...@@ -92,23 +92,23 @@ module Auth
# Build can: # Build can:
# 1. pull from its own project (for ex. a build) # 1. pull from its own project (for ex. a build)
# 2. read images from dependent projects if creator of build is a team member # 2. read images from dependent projects if creator of build is a team member
@authentication_abilities.include?(:build_read_container_image) && has_authentication_ability?(:build_read_container_image) &&
(requested_project == project || can?(current_user, :build_read_container_image, requested_project)) (requested_project == project || can?(current_user, :build_read_container_image, requested_project))
end end
def user_can_pull?(requested_project) def user_can_pull?(requested_project)
@authentication_abilities.include?(:read_container_image) && has_authentication_ability?(:read_container_image) &&
can?(current_user, :read_container_image, requested_project) can?(current_user, :read_container_image, requested_project)
end end
def build_can_push?(requested_project) def build_can_push?(requested_project)
# Build can push only to the project from which it originates # Build can push only to the project from which it originates
@authentication_abilities.include?(:build_create_container_image) && has_authentication_ability?(:build_create_container_image) &&
requested_project == project requested_project == project
end end
def user_can_push?(requested_project) def user_can_push?(requested_project)
@authentication_abilities.include?(:create_container_image) && has_authentication_ability?(:create_container_image) &&
can?(current_user, :create_container_image, requested_project) can?(current_user, :create_container_image, requested_project)
end end
...@@ -118,5 +118,9 @@ module Auth ...@@ -118,5 +118,9 @@ module Auth
http_status: status http_status: status
} }
end end
def has_authentication_ability?(capability)
(@authentication_abilities || []).include?(capability)
end
end end
end end
...@@ -20,7 +20,7 @@ describe JwtController do ...@@ -20,7 +20,7 @@ describe JwtController do
end end
end end
context 'when using authorized request' do context 'when using authenticated request' do
context 'using CI token' do context 'using CI token' do
let(:build) { create(:ci_build, :running) } let(:build) { create(:ci_build, :running) }
let(:project) { build.project } let(:project) { build.project }
...@@ -65,7 +65,7 @@ describe JwtController do ...@@ -65,7 +65,7 @@ describe JwtController do
let(:access_token) { create(:personal_access_token, user: user) } let(:access_token) { create(:personal_access_token, user: user) }
let(:headers) { { authorization: credentials(user.username, access_token.token) } } let(:headers) { { authorization: credentials(user.username, access_token.token) } }
it 'rejects the authorization attempt' do it 'accepts the authorization attempt' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
end end
...@@ -81,6 +81,20 @@ describe JwtController do ...@@ -81,6 +81,20 @@ describe JwtController do
end end
end end
context 'when using unauthenticated request' do
it 'accepts the authorization attempt' do
get '/jwt/auth', parameters
expect(response).to have_http_status(200)
end
it 'allows read access' do
expect(service).to receive(:execute).with(authentication_abilities: Gitlab::Auth.read_authentication_abilities)
get '/jwt/auth', parameters
end
end
context 'unknown service' do context 'unknown service' do
subject! { get '/jwt/auth', service: 'unknown' } subject! { get '/jwt/auth', service: 'unknown' }
......
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