class Proxy::ContainerGateway::Api

Private Instance Methods

auth_header() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 304
def auth_header
  AuthorizationHeader.new(request.env['HTTP_AUTHORIZATION'])
end
flatpak_client?() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 218
def flatpak_client?
  request.user_agent&.downcase&.include?('flatpak')
end
handle_repo_auth(repository, auth_header, request) click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 274
def handle_repo_auth(repository, auth_header, request)
  user_token_is_valid = false
  if auth_header.present? && auth_header.valid_user_token?
    user_token_is_valid = true
    username = auth_header.user[:name]
    # For flatpak client, header doesn't contain user name. Extract it from token.
    username ||= container_gateway_main.token_user(@value.split(' ')[1]) if flatpak_client?
  end
  username = request.params['account'] if username.nil?

  return if container_gateway_main.authorized_for_repo?(repository, user_token_is_valid, username)

  redirect_authorization_headers

  # If username couldn't be determined from the token or auth_headers
  # which is case for first flatpak request, halt with 401 instead of 404
  if flatpak_client? && username.nil?
    halt 401, "unauthorized"
  end

  throw_repo_not_found_error
end
head_or_get_blobs() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 222
def head_or_get_blobs
  repository = params[:splat][0]
  digest = params[:splat][1]
  handle_repo_auth(repository, auth_header, request)
  pulp_response = container_gateway_main.blobs(repository, digest, translated_headers_for_proxy)
  if pulp_response.code.to_i >= 400
    status pulp_response.code.to_i
    body pulp_response.body
  else
    redirection_uri = URI(pulp_response['location'])
    redirection_uri.host = URI(container_gateway_main.client_endpoint).host
    redirect(redirection_uri.to_s)
  end
end
redirect_authorization_headers() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 297
def redirect_authorization_headers
  response.headers['Docker-Distribution-API-Version'] = 'registry/2.0'
  response.headers['Www-Authenticate'] = "Bearer realm=\"https://#{request.host}/v2/token\"," \
                                         "service=\"#{request.host}\"," \
                                         "scope=\"repository:registry:pull,push\""
end
throw_repo_not_found_error() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 250
def throw_repo_not_found_error
  content_type :json
  body({
    "errors" => [
      {
        "code" => "NAME_UNKNOWN",
        "message" => "Repository name unknown"
      }
    ]
  }.to_json)
  halt 404
end
throw_unsupported_error() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 237
def throw_unsupported_error
  content_type :json
  body({
    "errors" => [
      {
        "code" => "UNSUPPORTED",
        "message" => "Pushing content is unsupported"
      }
    ]
  }.to_json)
  halt 404
end
translated_headers_for_proxy() click to toggle source
# File lib/smart_proxy_container_gateway/container_gateway_api.rb, line 263
def translated_headers_for_proxy
  current_headers = {}
  env = request.env.select do |key, _value|
    key.match("^HTTP_.*")
  end
  env.each do |header|
    current_headers[header[0].split('_')[1..].join('-')] = header[1]
  end
  current_headers
end