Merge branch 'docker-registry' into docker-registry-view
This commit is contained in:
commit
f63b6fc297
7 changed files with 30 additions and 31 deletions
|
@ -61,7 +61,7 @@ class Ability
|
||||||
:read_merge_request,
|
:read_merge_request,
|
||||||
:read_note,
|
:read_note,
|
||||||
:read_commit_status,
|
:read_commit_status,
|
||||||
:read_container_registry,
|
:read_container_image,
|
||||||
:download_code
|
:download_code
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ class Ability
|
||||||
:admin_label,
|
:admin_label,
|
||||||
:read_commit_status,
|
:read_commit_status,
|
||||||
:read_build,
|
:read_build,
|
||||||
:read_container_registry,
|
:read_container_image,
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -219,8 +219,8 @@ class Ability
|
||||||
:create_merge_request,
|
:create_merge_request,
|
||||||
:create_wiki,
|
:create_wiki,
|
||||||
:push_code,
|
:push_code,
|
||||||
:create_container_registry,
|
:create_container_image,
|
||||||
:update_container_registry,
|
:update_container_image,
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ class Ability
|
||||||
:admin_project,
|
:admin_project,
|
||||||
:admin_commit_status,
|
:admin_commit_status,
|
||||||
:admin_build,
|
:admin_build,
|
||||||
:admin_container_registry,
|
:admin_container_image,
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ class Ability
|
||||||
end
|
end
|
||||||
|
|
||||||
unless project.container_registry_enabled
|
unless project.container_registry_enabled
|
||||||
rules += named_abilities('container_registry')
|
rules += named_abilities('container_image')
|
||||||
end
|
end
|
||||||
|
|
||||||
rules
|
rules
|
||||||
|
|
|
@ -9,9 +9,9 @@ module Auth
|
||||||
return error('forbidden', 403) unless current_user
|
return error('forbidden', 403) unless current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
return error('forbidden', 401) if scopes.blank?
|
return error('forbidden', 401) unless scope
|
||||||
|
|
||||||
{ token: authorized_token(scopes).encoded }
|
{ token: authorized_token(scope).encoded }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.full_access_token(*names)
|
def self.full_access_token(*names)
|
||||||
|
@ -27,32 +27,27 @@ module Auth
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def authorized_token(access)
|
def authorized_token(*accesses)
|
||||||
token = ::JWT::RSAToken.new(registry.key)
|
token = JSONWebToken::RSAToken.new(registry.key)
|
||||||
token.issuer = registry.issuer
|
token.issuer = registry.issuer
|
||||||
token.audience = params[:service]
|
token.audience = params[:service]
|
||||||
token.subject = current_user.try(:username)
|
token.subject = current_user.try(:username)
|
||||||
token[:access] = access
|
token[:access] = accesses
|
||||||
token
|
token
|
||||||
end
|
end
|
||||||
|
|
||||||
def scopes
|
def scope
|
||||||
return unless params[:scope]
|
return unless params[:scope]
|
||||||
|
|
||||||
@scopes ||= begin
|
@scope ||= process_scope(params[:scope])
|
||||||
scope = process_scope(params[:scope])
|
|
||||||
[scope].compact
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_scope(scope)
|
def process_scope(scope)
|
||||||
type, name, actions = scope.split(':', 3)
|
type, name, actions = scope.split(':', 3)
|
||||||
actions = actions.split(',')
|
actions = actions.split(',')
|
||||||
|
return unless type == 'repository'
|
||||||
|
|
||||||
case type
|
process_repository_access(type, name, actions)
|
||||||
when 'repository'
|
|
||||||
process_repository_access(type, name, actions)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_repository_access(type, name, actions)
|
def process_repository_access(type, name, actions)
|
||||||
|
@ -71,9 +66,9 @@ module Auth
|
||||||
|
|
||||||
case requested_action
|
case requested_action
|
||||||
when 'pull'
|
when 'pull'
|
||||||
requested_project == project || can?(current_user, :read_container_registry, requested_project)
|
requested_project == project || can?(current_user, :read_container_image, requested_project)
|
||||||
when 'push'
|
when 'push'
|
||||||
requested_project == project || can?(current_user, :create_container_registry, requested_project)
|
requested_project == project || can?(current_user, :create_container_image, requested_project)
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module JWT
|
module JSONWebToken
|
||||||
class RSAToken < Token
|
class RSAToken < Token
|
||||||
attr_reader :key_file
|
attr_reader :key_file
|
||||||
|
|
||||||
|
@ -29,10 +29,14 @@ module JWT
|
||||||
end
|
end
|
||||||
|
|
||||||
def kid
|
def kid
|
||||||
fingerprint = Digest::SHA256.digest(public_key.to_der)
|
# calculate sha256 from DER encoded ASN1
|
||||||
Base32.encode(fingerprint).split('').each_slice(4).each_with_object([]) do |slice, mem|
|
kid = Digest::SHA256.digest(public_key.to_der)
|
||||||
mem << slice.join
|
|
||||||
end.join(':')
|
# we encode only 30 bytes with base32
|
||||||
|
kid = Base32.encode(kid[0..29])
|
||||||
|
|
||||||
|
# insert colon every 4 characters
|
||||||
|
kid.scan(/.{4}/).join(':')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module JWT
|
module JSONWebToken
|
||||||
class Token
|
class Token
|
||||||
attr_accessor :issuer, :subject, :audience, :id
|
attr_accessor :issuer, :subject, :audience, :id
|
||||||
attr_accessor :issued_at, :not_before, :expire_time
|
attr_accessor :issued_at, :not_before, :expire_time
|
|
@ -1,4 +1,4 @@
|
||||||
describe JWT::RSAToken do
|
describe JSONWebToken::RSAToken do
|
||||||
let(:rsa_key) { generate_key }
|
let(:rsa_key) { generate_key }
|
||||||
let(:rsa_token) { described_class.new(nil) }
|
let(:rsa_token) { described_class.new(nil) }
|
||||||
let(:rsa_encoded) { rsa_token.encoded }
|
let(:rsa_encoded) { rsa_token.encoded }
|
|
@ -1,4 +1,4 @@
|
||||||
describe JWT::Token do
|
describe JSONWebToken::Token do
|
||||||
let(:token) { described_class.new }
|
let(:token) { described_class.new }
|
||||||
|
|
||||||
context 'custom parameters' do
|
context 'custom parameters' do
|
|
@ -18,7 +18,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(Gitlab.config.registry).to receive_messages(registry_settings)
|
allow(Gitlab.config.registry).to receive_messages(registry_settings)
|
||||||
allow_any_instance_of(JWT::RSAToken).to receive(:key).and_return(rsa_key)
|
allow_any_instance_of(JSONWebToken::RSAToken).to receive(:key).and_return(rsa_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'an authenticated' do
|
shared_examples 'an authenticated' do
|
||||||
|
|
Loading…
Reference in a new issue