summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-05-13 16:43:49 -0500
committerKamil Trzcinski <ayufan@ayufan.eu>2016-05-13 16:43:49 -0500
commit692b5e0b47931bf173e92dab3d01b502fd284285 (patch)
treece14cde539ae8994a2484e82ead22a08472514e1
parent9e318bd99deb90a93130cd4ef79e54f18555d4dc (diff)
parent509654b3784da2a084a0c8303e9c6cc1498b8d2b (diff)
downloadgitlab-ce-692b5e0b47931bf173e92dab3d01b502fd284285.tar.gz
Merge branch 'docker-registry' into docker-registry-view
# Conflicts: # app/controllers/jwt_controller.rb # app/services/jwt/container_registry_authentication_service.rb
-rw-r--r--app/controllers/jwt_controller.rb39
-rw-r--r--app/models/project.rb2
-rw-r--r--app/services/jwt/container_registry_authentication_service.rb119
-rw-r--r--lib/jwt/rsa_token.rb10
-rw-r--r--spec/features/container_registry_spec.rb2
-rw-r--r--spec/services/jwt/container_registry_authentication_service_spec.rb2
6 files changed, 95 insertions, 79 deletions
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 07a842970b8..568f14a713a 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -1,22 +1,13 @@
class JwtController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
+ before_action :authenticate_project_or_user
SERVICES = {
- Jwt::ContainerRegistryAuthenticationService::AUDIENCE => Jwt::ContainerRegistryAuthenticationService,
+ ::Gitlab::JWT::ContainerRegistryAuthenticationService::AUDIENCE => ::Gitlab::JWT::ContainerRegistryAuthenticationService,
}
def auth
- @authenticated = authenticate_with_http_basic do |login, password|
- # if it's possible we first try to authenticate project with login and password
- @project = authenticate_project(login, password)
- @user = authenticate_user(login, password) unless @project
- end
-
- unless @authenticated
- head :forbidden if ActionController::HttpAuthentication::Basic.has_basic_credentials?(request)
- end
-
service = SERVICES[params[:service]]
head :not_found unless service
@@ -28,19 +19,28 @@ class JwtController < ApplicationController
private
+ def authenticate_project_or_user
+ authenticate_with_http_basic do |login, password|
+ # if it's possible we first try to authenticate project with login and password
+ @project = authenticate_project(login, password)
+ return if @project
+
+ @user = authenticate_user(login, password)
+ return if @user
+ end
+
+ if ActionController::HttpAuthentication::Basic.has_basic_credentials?(request)
+ head :forbidden
+ end
+ end
+
def auth_params
params.permit(:service, :scope, :offline_token, :account, :client_id)
end
def authenticate_project(login, password)
- matched_login = /(?<s>^[a-zA-Z]*-ci)-token$/.match(login)
-
- if matched_login.present?
- underscored_service = matched_login['s'].underscore
-
- if underscored_service == 'gitlab_ci'
- Project.find_by(builds_enabled: true, runners_token: password)
- end
+ if login == 'gitlab_ci_token'
+ Project.find_by(builds_enabled: true, runners_token: password)
end
end
@@ -77,6 +77,7 @@ class JwtController < ApplicationController
if banned
Rails.logger.info "IP #{request.ip} failed to login " \
"as #{login} but has been temporarily banned from Git auth"
+ return
end
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index e5ace7d755b..fb90102db73 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -377,7 +377,7 @@ class Project < ActiveRecord::Base
def container_registry_repository
@container_registry_repository ||= begin
- token = JWT::ContainerRegistryAuthenticationService.full_access_token(path_with_namespace)
+ token = Gitlab::JWT::ContainerRegistryAuthenticationService.full_access_token(path_with_namespace)
url = Gitlab.config.registry.api_url
host_port = Gitlab.config.registry.host_port
registry = ContainerRegistry::Registry.new(url, token: token, path: host_port)
diff --git a/app/services/jwt/container_registry_authentication_service.rb b/app/services/jwt/container_registry_authentication_service.rb
index b60cd3c57e5..46b30ec9202 100644
--- a/app/services/jwt/container_registry_authentication_service.rb
+++ b/app/services/jwt/container_registry_authentication_service.rb
@@ -1,71 +1,73 @@
-module JWT
- class ContainerRegistryAuthenticationService < BaseService
- AUDIENCE = 'container_registry'
+module Gitlab
+ module JWT
+ class ContainerRegistryAuthenticationService < BaseService
+ AUDIENCE = 'container_registry'
- def execute
- return error('not found', 404) unless registry.enabled
+ def execute
+ return error('not found', 404) unless registry.enabled
- if params[:offline_token]
- return error('forbidden', 403) unless current_user
- end
+ if params[:offline_token]
+ return error('forbidden', 403) unless current_user
+ end
- return error('forbidden', 401) if scopes.blank?
+ return error('forbidden', 401) if scopes.blank?
- { token: authorized_token(scopes).encoded }
- end
+ { token: authorized_token(scopes).encoded }
+ end
- def self.full_access_token(*names)
- registry = Gitlab.config.registry
- token = ::JWT::RSAToken.new(registry.key)
- token.issuer = registry.issuer
- token.audience = AUDIENCE
- token[:access] = names.map do |name|
- { type: 'repository', name: name, actions: %w(pull push) }
+ def self.full_access_token(*names)
+ registry = Gitlab.config.registry
+ token = ::JWT::RSAToken.new(registry.key)
+ token.issuer = registry.issuer
+ token.audience = AUDIENCE
+ token[:access] = names.map do |name|
+ { type: 'repository', name: name, actions: %w(pull push) }
+ end
+ token.encoded
end
- token.encoded
- end
- private
+ private
- def authorized_token(access)
- token = ::JWT::RSAToken.new(registry.key)
- token.issuer = registry.issuer
- token.audience = AUDIENCE
- token.subject = current_user.try(:username)
- token[:access] = access
- token
- end
+ def authorized_token(access)
+ token = ::JWT::RSAToken.new(registry.key)
+ token.issuer = registry.issuer
+ token.audience = params[:service]
+ token.subject = current_user.try(:username)
+ token[:access] = access
+ token
+ end
- def scopes
- return unless params[:scope]
+ def scopes
+ return unless params[:scope]
- @scopes ||= begin
- scope = process_scope(params[:scope])
- [scope].compact
+ @scopes ||= begin
+ scope = process_scope(params[:scope])
+ [scope].compact
+ end
end
- end
- def process_scope(scope)
- type, name, actions = scope.split(':', 3)
- actions = actions.split(',')
+ def process_scope(scope)
+ type, name, actions = scope.split(':', 3)
+ actions = actions.split(',')
- case type
- when 'repository'
- process_repository_access(type, name, actions)
+ case type
+ when 'repository'
+ process_repository_access(type, name, actions)
+ end
end
- end
- def process_repository_access(type, name, actions)
- requested_project = Project.find_with_namespace(name)
- return unless requested_project
+ def process_repository_access(type, name, actions)
+ requested_project = Project.find_with_namespace(name)
+ return unless requested_project
- actions = actions.select do |action|
- can_access?(requested_project, action)
- end
+ actions = actions.select do |action|
+ can_access?(requested_project, action)
+ end
- { type: type, name: name, actions: actions } if actions.present?
- end
+ { type: type, name: name, actions: actions } if actions.present?
+ end
+<<<<<<< HEAD
def can_access?(requested_project, requested_action)
return false unless requested_project.container_registry_enabled?
@@ -76,11 +78,22 @@ module JWT
requested_project == project || can?(current_user, :create_container_registry, requested_project)
else
false
+=======
+ def can_access?(requested_project, requested_action)
+ case requested_action
+ when 'pull'
+ requested_project.public? || requested_project == project || can?(current_user, :read_container_registry, requested_project)
+ when 'push'
+ requested_project == project || can?(current_user, :create_container_registry, requested_project)
+ else
+ false
+ end
+>>>>>>> docker-registry
end
- end
- def registry
- Gitlab.config.registry
+ def registry
+ Gitlab.config.registry
+ end
end
end
end
diff --git a/lib/jwt/rsa_token.rb b/lib/jwt/rsa_token.rb
index 0438135ad54..4de89bf0d37 100644
--- a/lib/jwt/rsa_token.rb
+++ b/lib/jwt/rsa_token.rb
@@ -24,11 +24,13 @@ module JWT
@key ||= OpenSSL::PKey::RSA.new(key_data)
end
+ def public_key
+ key.public_key
+ end
+
def kid
- sha256 = Digest::SHA256.new
- sha256.update(key.public_key.to_der)
- payload = StringIO.new(sha256.digest).read(30)
- Base32.encode(payload).split('').each_slice(4).each_with_object([]) do |slice, mem|
+ fingerprint = Digest::SHA256.digest(public_key.to_der)
+ Base32.encode(fingerprint).split('').each_slice(4).each_with_object([]) do |slice, mem|
mem << slice.join
end.join(':')
end
diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb
index 6c4d675fd6a..992da289028 100644
--- a/spec/features/container_registry_spec.rb
+++ b/spec/features/container_registry_spec.rb
@@ -16,7 +16,7 @@ describe "Container Registry" do
project.team << [@user, :developer]
stub_container_registry(*tags)
allow(Gitlab.config.registry).to receive_messages(registry_settings)
- allow(JWT::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token')
+ allow(Gitlab::JWT::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token')
end
describe 'GET /:project/container_registry' do
diff --git a/spec/services/jwt/container_registry_authentication_service_spec.rb b/spec/services/jwt/container_registry_authentication_service_spec.rb
index 672a7579dd3..c8a0ba958dd 100644
--- a/spec/services/jwt/container_registry_authentication_service_spec.rb
+++ b/spec/services/jwt/container_registry_authentication_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe JWT::ContainerRegistryAuthenticationService, services: true do
+describe Gitlab::JWT::ContainerRegistryAuthenticationService, services: true do
let(:current_project) { nil }
let(:current_user) { nil }
let(:current_params) { {} }