<commit_before>module Auth
  class ContainerRegistryAuthenticationService < BaseService
    extend Gitlab::CurrentSettings

    AUDIENCE = 'container_registry'.freeze

    def execute(authentication_abilities:)
      @authentication_abilities = authentication_abilities

      return error('UNAVAILABLE', status: 404, message: 'registry not enabled') unless registry.enabled

      unless scope || current_user || project
        return error('DENIED', status: 403, message: 'access forbidden')
      end

      { token: authorized_token(scope).encoded }
    end

    def self.full_access_token(*names)
      names = names.flatten
      registry = Gitlab.config.registry
      token = JSONWebToken::RSAToken.new(registry.key)
      token.issuer = registry.issuer
      token.audience = AUDIENCE
      token.expire_time = token_expire_at

      token[:access] = names.map do |name|
        { type: 'repository', name: name, actions: %w(*) }
      end

      token.encoded
    end

    def self.token_expire_at
      Time.now + current_application_settings.container_registry_token_expire_delay.minutes
    end

    private

    def authorized_token(*accesses)
      JSONWebToken::RSAToken.new(registry.key).tap do |token|
        token.issuer = registry.issuer
        token.audience = params[:service]
        token.subject = current_user.try(:username)
        token.expire_time = self.class.token_expire_at
        token[:access] = accesses.compact
      end
    end

    def scope
      return unless params[:scope]

      @scope ||= process_scope(params[:scope])
    end

    def process_scope(scope)
      type, name, actions = scope.split(':', 3)
      actions = actions.split(',')
      path = ContainerRegistry::Path.new(name)

      if type == 'registry' && name == 'catalog' && current_user && current_user.admin?
        return { type: type, name: name, actions: ['*'] }
      end

      return unless type == 'repository'

      process_repository_access(type, path, actions)
    end

    def process_repository_access(type, path, actions)
      return unless path.valid?

      requested_project = path.repository_project

      return unless requested_project<commit_msg>refactor access handling<commit_after>module Auth
  class ContainerRegistryAuthenticationService < BaseService
    extend Gitlab::CurrentSettings

    AUDIENCE = 'container_registry'.freeze

    def execute(authentication_abilities:)
      @authentication_abilities = authentication_abilities

      return error('UNAVAILABLE', status: 404, message: 'registry not enabled') unless registry.enabled

      unless scope || current_user || project
        return error('DENIED', status: 403, message: 'access forbidden')
      end

      { token: authorized_token(scope).encoded }
    end

    def self.full_access_token(*names)
      names = names.flatten
      registry = Gitlab.config.registry
      token = JSONWebToken::RSAToken.new(registry.key)
      token.issuer = registry.issuer
      token.audience = AUDIENCE
      token.expire_time = token_expire_at

      token[:access] = names.map do |name|
        { type: 'repository', name: name, actions: %w(*) }
      end

      token.encoded
    end

    def self.token_expire_at
      Time.now + current_application_settings.container_registry_token_expire_delay.minutes
    end

    private

    def authorized_token(*accesses)
      JSONWebToken::RSAToken.new(registry.key).tap do |token|
        token.issuer = registry.issuer
        token.audience = params[:service]
        token.subject = current_user.try(:username)
        token.expire_time = self.class.token_expire_at
        token[:access] = accesses.compact
      end
    end

    def scope
      return unless params[:scope]

      @scope ||= process_scope(params[:scope])
    end

    def process_scope(scope)
      type, name, actions = scope.split(':', 3)
      actions = actions.split(',')

      case type
      when 'registry'
        process_registry_access(type, name, actions)
      when 'repository'
        path = ContainerRegistry::Path.new(name)
        process_repository_access(type, path, actions)
      end
    end

    def process_registry_access(type, name, actions)
      return unless current_user&.admin?
      return unless name == 'catalog'
      return unless actions == ['*']

      { type: type, name: name, actions: ['*'] }
    end

    def process_repository_access(type, path, actions)
      return unless path.valid?

      requested_project = path.repository_project

      return unless requested_project
{'fraction_non_alphanumeric': 0.09429389733421459, 'fraction_numerical': 0.0030843798193434676, 'mean_word_length': 3.024822695035461, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5450349', 'n_tokens_mistral': 1308, 'n_tokens_neox': 1245, 'n_words': 295}