Commit f63b6fc2 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Merge branch 'docker-registry' into docker-registry-view

parents 5c194762 f4f9184a
...@@ -61,7 +61,7 @@ class Ability ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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,33 +27,28 @@ module Auth ...@@ -27,33 +27,28 @@ 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
when 'repository'
process_repository_access(type, name, actions) process_repository_access(type, name, actions)
end end
end
def process_repository_access(type, name, actions) def process_repository_access(type, name, actions)
requested_project = Project.find_with_namespace(name) requested_project = Project.find_with_namespace(name)
...@@ -71,9 +66,9 @@ module Auth ...@@ -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
......
module JWT module JSONWebToken
class RSAToken < Token class RSAToken < Token
attr_reader :key_file attr_reader :key_file
...@@ -29,10 +29,14 @@ module JWT ...@@ -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
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
......
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 }
......
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 ...@@ -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
......
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