diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-05-14 19:15:19 +0300 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-05-14 19:15:33 +0300 |
commit | 654d5ad3f42732df77553bfbc2230f17d9185267 (patch) | |
tree | e732669d38adb58696ac7e9b78dbd1d3a835340c | |
parent | 906c880400a36abd34426c634d2a9f6086909db0 (diff) | |
parent | 63cdf1aeb04b9694c0b6d44b1141868fcc5a0904 (diff) |
Merge branch 'docker-registry' into docker-registry-view
-rw-r--r-- | app/controllers/jwt_controller.rb | 2 | ||||
-rw-r--r-- | app/models/project.rb | 2 | ||||
-rw-r--r-- | app/services/auth/container_registry_authentication_service.rb | 84 | ||||
-rw-r--r-- | app/services/jwt/container_registry_authentication_service.rb | 99 | ||||
-rw-r--r-- | spec/features/container_registry_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/jwt/container_registry_authentication_service_spec.rb | 2 |
6 files changed, 88 insertions, 103 deletions
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 568f14a713a..5b9a04c249a 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -4,7 +4,7 @@ class JwtController < ApplicationController before_action :authenticate_project_or_user SERVICES = { - ::Gitlab::JWT::ContainerRegistryAuthenticationService::AUDIENCE => ::Gitlab::JWT::ContainerRegistryAuthenticationService, + Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService, } def auth diff --git a/app/models/project.rb b/app/models/project.rb index 5fca175f460..0206ccc8d37 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -330,7 +330,7 @@ class Project < ActiveRecord::Base def container_registry_repository @container_registry_repository ||= begin - token = Gitlab::JWT::ContainerRegistryAuthenticationService.full_access_token(path_with_namespace) + token = Auth::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/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb new file mode 100644 index 00000000000..e7aa7faeb96 --- /dev/null +++ b/app/services/auth/container_registry_authentication_service.rb @@ -0,0 +1,84 @@ +module Auth + class ContainerRegistryAuthenticationService < BaseService + AUDIENCE = 'container_registry' + + def execute + return error('not found', 404) unless registry.enabled + + if params[:offline_token] + return error('forbidden', 403) unless current_user + end + + return error('forbidden', 401) if scopes.blank? + + { 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) } + end + token.encoded + end + + private + + 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] + + @scopes ||= begin + scope = process_scope(params[:scope]) + [scope].compact + end + end + + def process_scope(scope) + type, name, actions = scope.split(':', 3) + actions = actions.split(',') + + case type + when 'repository' + process_repository_access(type, name, actions) + end + end + + 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 + + { type: type, name: name, actions: actions } if actions.present? + end + + 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 + end + + def registry + Gitlab.config.registry + end + end +end diff --git a/app/services/jwt/container_registry_authentication_service.rb b/app/services/jwt/container_registry_authentication_service.rb deleted file mode 100644 index 46b30ec9202..00000000000 --- a/app/services/jwt/container_registry_authentication_service.rb +++ /dev/null @@ -1,99 +0,0 @@ -module Gitlab - module JWT - class ContainerRegistryAuthenticationService < BaseService - AUDIENCE = 'container_registry' - - def execute - return error('not found', 404) unless registry.enabled - - if params[:offline_token] - return error('forbidden', 403) unless current_user - end - - return error('forbidden', 401) if scopes.blank? - - { 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) } - end - token.encoded - end - - private - - 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] - - @scopes ||= begin - scope = process_scope(params[:scope]) - [scope].compact - end - end - - def process_scope(scope) - type, name, actions = scope.split(':', 3) - actions = actions.split(',') - - case type - when 'repository' - process_repository_access(type, name, actions) - end - end - - 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 - - { 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? - - case requested_action - when 'pull' - 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 -======= - 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 - - def registry - Gitlab.config.registry - end - end - end -end diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb index 992da289028..be5910e4abb 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(Gitlab::JWT::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token') + allow(Auth::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 c8a0ba958dd..a45410f0458 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 Gitlab::JWT::ContainerRegistryAuthenticationService, services: true do +describe Auth::ContainerRegistryAuthenticationService, services: true do let(:current_project) { nil } let(:current_user) { nil } let(:current_params) { {} } |