Module: Dapp::Dimg::DockerRegistry::Base::Authorization

Included in:
Dapp::Dimg::DockerRegistry::Base
Defined in:
lib/dapp/dimg/docker_registry/base/authorization.rb

Instance Method Summary collapse

Instance Method Details

#authorization_authObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/dapp/dimg/docker_registry/base/authorization.rb', line 51

def authorization_auth
  @authorization_auth ||= begin
    if ::Dapp::Dapp.options_with_docker_credentials?
      Base64.strict_encode64(::Dapp::Dapp.docker_credentials.join(':'))
    else
      auths = auths_section_from_docker_config
      r = repo
      loop do
        break unless r.include?('/') && !auths.keys.any? { |auth| auth.start_with?(r) }
        r = chomp_name(r)
      end
      credential = (auths[r] || auths.find { |repo, _| repo == r })
      user_not_authorized! if credential.nil?
      credential['auth']
    end
  end
end

#authorization_options(url, method:) ⇒ Object



6
7
8
9
10
11
12
13
14
15
# File 'lib/dapp/dimg/docker_registry/base/authorization.rb', line 6

def authorization_options(url, method:)
  (@authorization_options ||= {})[[@repo_suffix, method]] ||= begin
    case authenticate_header = raw_request(url, method: method).headers['Www-Authenticate']
      when /Bearer/ then { headers: { Authorization: "Bearer #{authorization_token(authenticate_header)}" } }
      when /Basic/ then { headers: { Authorization: "Basic #{authorization_auth}" } }
      when nil then {}
      else raise Error::Registry, code: :authenticate_type_not_supported, data: { registry: api_url }
    end
  end
end

#authorization_token(authenticate_header) ⇒ Object



17
18
19
20
21
22
23
24
25
26
# File 'lib/dapp/dimg/docker_registry/base/authorization.rb', line 17

def authorization_token(authenticate_header)
  options = parse_authenticate_header(authenticate_header)
  realm = options.delete(:realm)
  begin
    response = raw_request(realm, headers: { Authorization: "Basic #{authorization_auth}" }, query: options, expects: [200])
  rescue Error::Registry
    raise unless (response = raw_request(realm, query: options)).status == 200
  end
  JSON.load(response.body)['token']
end

#auths_section_from_docker_configObject



69
70
71
72
73
# File 'lib/dapp/dimg/docker_registry/base/authorization.rb', line 69

def auths_section_from_docker_config
  file = Pathname(File.join(::Dapp::Dapp.host_docker_config_dir, 'config.json'))
  user_not_authorized! unless file.exist?
  JSON.load(file.read)['auths'].tap { |auths| user_not_authorized! if auths.nil? }
end

#handle_scope_option(resourcescope) ⇒ Object



45
46
47
48
49
# File 'lib/dapp/dimg/docker_registry/base/authorization.rb', line 45

def handle_scope_option(resourcescope)
  resource_type, resource_name, actions = resourcescope.split(":")
  actions                               = actions.split(",").map { |action| action == "delete" ? "*" : action }.join(",")
  [resource_type, resource_name, actions].join(":")
end

#parse_authenticate_header(header) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/dapp/dimg/docker_registry/base/authorization.rb', line 28

def parse_authenticate_header(header)
  [:realm, :service, :scope].map do |option|
    /#{option}="([[^"].]*)/ =~ header
    next unless Regexp.last_match(1)

    option_value = begin
      if option == :scope
        handle_scope_option(Regexp.last_match(1))
      else
        Regexp.last_match(1)
      end
    end

    [option, option_value]
  end.compact.to_h
end