diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 9bf1ddbba210e4680c7d29d3c602e62cb7f1fcc9..0048a1a31ea54f6891eb18e39c443a99c5e19adb 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -3,7 +3,7 @@ class JwtController < ApplicationController skip_before_action :verify_authenticity_token SERVICES = { - 'docker' => Jwt::DockerAuthenticationService, + 'container_registry' => Jwt::ContainerRegistryAuthenticationService, } def auth diff --git a/app/services/jwt/docker_authentication_service.rb b/app/services/jwt/container_registry_authentication_service.rb similarity index 68% rename from app/services/jwt/docker_authentication_service.rb rename to app/services/jwt/container_registry_authentication_service.rb index fb0c41a12f7ca4bb438f77ecf4fc45f2b0ba07f0..b9fcd380475f5a1cbfcee1ba4e397e905fb74e0f 100644 --- a/app/services/jwt/docker_authentication_service.rb +++ b/app/services/jwt/container_registry_authentication_service.rb @@ -1,16 +1,18 @@ module Jwt - class DockerAuthenticationService < BaseService + class ContainerRegistryAuthenticationService < BaseService def execute if params[:offline_token] return error('forbidden', 403) unless current_user end - { token: authorized_token.encoded } + return error('forbidden', 401) if scopes.empty? + + { token: authorized_token(scopes).encoded } end private - def authorized_token + def authorized_token(access) token = ::Jwt::RSAToken.new(registry.key) token.issuer = registry.issuer token.audience = params[:service] @@ -19,11 +21,13 @@ module Jwt token end - def access + def scopes return unless params[:scope] - scope = process_scope(params[:scope]) - [scope].compact + @scopes ||= begin + scope = process_scope(params[:scope]) + [scope].compact + end end def process_scope(scope) @@ -44,15 +48,15 @@ module Jwt can_access?(requested_project, action) end - { type: type, name: name, actions: actions } if actions + { 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, :download_code, requested_project) + requested_project.public? || requested_project == project || can?(current_user, :read_container_registry, requested_project) when 'push' - requested_project == project || can?(current_user, :push_code, requested_project) + requested_project == project || can?(current_user, :create_container_registry, requested_project) else false end diff --git a/lib/jwt/token.rb b/lib/jwt/token.rb index 38cbc8004e7460f8e299cf444a46510b9ebc29dc..765ab0d60c778d51c7ed9e99744206149b469803 100644 --- a/lib/jwt/token.rb +++ b/lib/jwt/token.rb @@ -4,19 +4,21 @@ module Jwt attr_accessor :issued_at, :not_before, :expire_time def initialize - @payload = {} @id = SecureRandom.uuid @issued_at = Time.now + # we give a few seconds for time shift @not_before = issued_at - 5.seconds + # default 60 seconds should be more than enough for this authentication token @expire_time = issued_at + 1.minute + @custom_payload = {} end def [](key) - @payload[key] + @custom_payload[key] end def []=(key, value) - @payload[key] = value + @custom_payload[key] = value end def encoded @@ -24,11 +26,7 @@ module Jwt end def payload - @payload.merge(default_payload) - end - - def to_json - payload.to_json + @custom_payload.merge(default_payload) end private