File: endpoints.rb

package info (click to toggle)
ruby-aws-sdk-core 3.212.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,232 kB
  • sloc: ruby: 17,533; makefile: 4
file content (134 lines) | stat: -rw-r--r-- 4,480 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true

require_relative 'endpoints/rule'
require_relative 'endpoints/condition'
require_relative 'endpoints/endpoint_rule'
require_relative 'endpoints/endpoint'
require_relative 'endpoints/error_rule'
require_relative 'endpoints/function'
require_relative 'endpoints/matchers'
require_relative 'endpoints/reference'
require_relative 'endpoints/rules_provider'
require_relative 'endpoints/rule_set'
require_relative 'endpoints/templater'
require_relative 'endpoints/tree_rule'
require_relative 'endpoints/url'

require 'aws-sigv4'

module Aws
  # @api private
  module Endpoints
    SUPPORTED_AUTH_TRAITS = %w[
      aws.auth#sigv4
      aws.auth#sigv4a
      smithy.api#httpBearerAuth
      smithy.api#noAuth
    ].freeze

    class << self
      def resolve_auth_scheme(context, endpoint)
        if endpoint && (auth_schemes = endpoint.properties['authSchemes'])
          auth_scheme = auth_schemes.find do |scheme|
            Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES.include?(scheme['name'])
          end
          raise 'No supported auth scheme for this endpoint.' unless auth_scheme

          merge_signing_defaults(auth_scheme, context.config)
        else
          default_auth_scheme(context)
        end
      end

      private

      def merge_signing_defaults(auth_scheme, config)
        if %w[sigv4 sigv4a sigv4-s3express].include?(auth_scheme['name'])
          auth_scheme['signingName'] ||= sigv4_name(config)

          # back fill disableNormalizePath for S3 until it gets correctly set in the rules
          if auth_scheme['signingName'] == 's3' &&
            !auth_scheme.include?('disableNormalizePath') &&
            auth_scheme.include?('disableDoubleEncoding')
            auth_scheme['disableNormalizePath'] = auth_scheme['disableDoubleEncoding']
          end
          if auth_scheme['name'] == 'sigv4a'
            # config option supersedes endpoint properties
            auth_scheme['signingRegionSet'] =
              config.sigv4a_signing_region_set || auth_scheme['signingRegionSet'] || [config.region]
          else
            auth_scheme['signingRegion'] ||= config.region
          end
        end
        auth_scheme
      end

      def sigv4_name(config)
        config.api.metadata['signingName'] ||
          config.api.metadata['endpointPrefix']
      end

      def default_auth_scheme(context)
        if (auth_list = default_api_auth(context))
          auth = auth_list.find { |a| SUPPORTED_AUTH_TRAITS.include?(a) }
          case auth
          when 'aws.auth#sigv4', 'aws.auth#sigv4a'
            auth_scheme = { 'name' => auth.split('#').last }
            if s3_or_s3v4_signature_version?(context)
              auth_scheme = auth_scheme.merge(
                'disableDoubleEncoding' => true,
                'disableNormalizePath' => true
              )
            end
            merge_signing_defaults(auth_scheme, context.config)
          when 'smithy.api#httpBearerAuth'
            { 'name' => 'bearer' }
          when 'smithy.api#noAuth'
            { 'name' => 'none' }
          else
            raise 'No supported auth trait for this endpoint.'
          end
        else
          legacy_default_auth_scheme(context)
        end
      end

      def default_api_auth(context)
        context.config.api.operation(context.operation_name)['auth'] ||
          context.config.api.metadata['auth']
      end

      def s3_or_s3v4_signature_version?(context)
        %w[s3 s3v4].include?(context.config.api.metadata['signatureVersion'])
      end

      # Legacy auth resolution - looks for deprecated signatureVersion
      # and authType traits.

      def legacy_default_auth_scheme(context)
        case legacy_default_api_authtype(context)
        when 'v4', 'v4-unsigned-body'
          auth_scheme = { 'name' => 'sigv4' }
          merge_signing_defaults(auth_scheme, context.config)
        when 's3', 's3v4'
          auth_scheme = {
            'name' => 'sigv4',
            'disableDoubleEncoding' => true,
            'disableNormalizePath' => true
          }
          merge_signing_defaults(auth_scheme, context.config)
        when 'bearer'
          { 'name' => 'bearer' }
        when 'none', nil
          { 'name' => 'none' }
        end
      end

      def legacy_default_api_authtype(context)
        context.config.api.operation(context.operation_name)['authtype'] ||
          context.config.api.metadata['signatureVersion']
      end

    end
  end
end