From 63cdf1aeb04b9694c0b6d44b1141868fcc5a0904 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Sat, 14 May 2016 11:11:48 -0500 Subject: Use Auth::ContainerRegistryAuthenticationService --- app/controllers/jwt_controller.rb | 2 +- .../container_registry_authentication_service.rb | 69 +++++++++++++++++++++ .../container_registry_authentication_service.rb | 71 ---------------------- ...ntainer_registry_authentication_service_spec.rb | 2 +- 4 files changed, 71 insertions(+), 73 deletions(-) create mode 100644 app/services/auth/container_registry_authentication_service.rb delete mode 100644 app/services/jwt/container_registry_authentication_service.rb diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index e067f59808a..e5affb1adc9 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 = { - 'container_registry' => ::Gitlab::JWT::ContainerRegistryAuthenticationService, + 'container_registry' => Auth::ContainerRegistryAuthenticationService, } def auth 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..0323a42b697 --- /dev/null +++ b/app/services/auth/container_registry_authentication_service.rb @@ -0,0 +1,69 @@ +module Auth + class ContainerRegistryAuthenticationService < BaseService + def execute + 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 + + 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 dd0f2954784..00000000000 --- a/app/services/jwt/container_registry_authentication_service.rb +++ /dev/null @@ -1,71 +0,0 @@ -module Gitlab - module JWT - class ContainerRegistryAuthenticationService < BaseService - def execute - 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 - - 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 -end diff --git a/spec/services/jwt/container_registry_authentication_service_spec.rb b/spec/services/jwt/container_registry_authentication_service_spec.rb index 7c879852520..1873ea2639b 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 JWT::ContainerRegistryAuthenticationService, services: true do let(:current_project) { nil } let(:current_user) { nil } let(:current_params) { {} } -- cgit v1.2.1