auth.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. // Code generated by smithy-go-codegen DO NOT EDIT.
  2. package s3
  3. import (
  4. "context"
  5. "fmt"
  6. awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
  7. smithy "github.com/aws/smithy-go"
  8. smithyauth "github.com/aws/smithy-go/auth"
  9. "github.com/aws/smithy-go/metrics"
  10. "github.com/aws/smithy-go/middleware"
  11. "github.com/aws/smithy-go/tracing"
  12. smithyhttp "github.com/aws/smithy-go/transport/http"
  13. "slices"
  14. "strings"
  15. )
  16. func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) {
  17. params.Region = options.Region
  18. }
  19. func bindAuthEndpointParams(ctx context.Context, params *AuthResolverParameters, input interface{}, options Options) {
  20. params.endpointParams = bindEndpointParams(ctx, input, options)
  21. }
  22. type setLegacyContextSigningOptionsMiddleware struct {
  23. }
  24. func (*setLegacyContextSigningOptionsMiddleware) ID() string {
  25. return "setLegacyContextSigningOptions"
  26. }
  27. func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
  28. out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
  29. ) {
  30. rscheme := getResolvedAuthScheme(ctx)
  31. schemeID := rscheme.Scheme.SchemeID()
  32. if sn := awsmiddleware.GetSigningName(ctx); sn != "" {
  33. if schemeID == "aws.auth#sigv4" {
  34. smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn)
  35. } else if schemeID == "aws.auth#sigv4a" {
  36. smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn)
  37. }
  38. }
  39. if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" {
  40. if schemeID == "aws.auth#sigv4" {
  41. smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr)
  42. } else if schemeID == "aws.auth#sigv4a" {
  43. smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr})
  44. }
  45. }
  46. return next.HandleFinalize(ctx, in)
  47. }
  48. func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error {
  49. return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before)
  50. }
  51. type withAnonymous struct {
  52. resolver AuthSchemeResolver
  53. }
  54. var _ AuthSchemeResolver = (*withAnonymous)(nil)
  55. func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) {
  56. opts, err := v.resolver.ResolveAuthSchemes(ctx, params)
  57. if err != nil {
  58. return nil, err
  59. }
  60. opts = append(opts, &smithyauth.Option{
  61. SchemeID: smithyauth.SchemeIDAnonymous,
  62. })
  63. return opts, nil
  64. }
  65. func wrapWithAnonymousAuth(options *Options) {
  66. if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok {
  67. return
  68. }
  69. options.AuthSchemeResolver = &withAnonymous{
  70. resolver: options.AuthSchemeResolver,
  71. }
  72. }
  73. // AuthResolverParameters contains the set of inputs necessary for auth scheme
  74. // resolution.
  75. type AuthResolverParameters struct {
  76. // The name of the operation being invoked.
  77. Operation string
  78. // The endpoint resolver parameters for this operation. This service's default
  79. // resolver delegates to endpoint rules.
  80. endpointParams *EndpointParameters
  81. // The region in which the operation is being invoked.
  82. Region string
  83. }
  84. func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters {
  85. params := &AuthResolverParameters{
  86. Operation: operation,
  87. }
  88. bindAuthEndpointParams(ctx, params, input, options)
  89. bindAuthParamsRegion(ctx, params, input, options)
  90. return params
  91. }
  92. // AuthSchemeResolver returns a set of possible authentication options for an
  93. // operation.
  94. type AuthSchemeResolver interface {
  95. ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error)
  96. }
  97. type defaultAuthSchemeResolver struct{}
  98. var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil)
  99. func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) {
  100. if overrides, ok := operationAuthOptions[params.Operation]; ok {
  101. return overrides(params), nil
  102. }
  103. return serviceAuthOptions(params), nil
  104. }
  105. var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{
  106. "WriteGetObjectResponse": func(params *AuthResolverParameters) []*smithyauth.Option {
  107. return []*smithyauth.Option{
  108. {
  109. SchemeID: smithyauth.SchemeIDSigV4,
  110. SignerProperties: func() smithy.Properties {
  111. var props smithy.Properties
  112. smithyhttp.SetSigV4SigningName(&props, "s3")
  113. smithyhttp.SetSigV4SigningRegion(&props, params.Region)
  114. smithyhttp.SetIsUnsignedPayload(&props, true)
  115. return props
  116. }(),
  117. },
  118. }
  119. },
  120. }
  121. func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option {
  122. return []*smithyauth.Option{
  123. {
  124. SchemeID: smithyauth.SchemeIDSigV4,
  125. SignerProperties: func() smithy.Properties {
  126. var props smithy.Properties
  127. smithyhttp.SetSigV4SigningName(&props, "s3")
  128. smithyhttp.SetSigV4SigningRegion(&props, params.Region)
  129. return props
  130. }(),
  131. },
  132. {
  133. SchemeID: smithyauth.SchemeIDSigV4A,
  134. SignerProperties: func() smithy.Properties {
  135. var props smithy.Properties
  136. smithyhttp.SetSigV4ASigningName(&props, "s3")
  137. smithyhttp.SetSigV4ASigningRegions(&props, []string{params.Region})
  138. return props
  139. }(),
  140. },
  141. }
  142. }
  143. type resolveAuthSchemeMiddleware struct {
  144. operation string
  145. options Options
  146. }
  147. func (*resolveAuthSchemeMiddleware) ID() string {
  148. return "ResolveAuthScheme"
  149. }
  150. func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
  151. out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
  152. ) {
  153. _, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
  154. defer span.End()
  155. params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
  156. options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
  157. if err != nil {
  158. return out, metadata, fmt.Errorf("resolve auth scheme: %w", err)
  159. }
  160. scheme, ok := m.selectScheme(options)
  161. if !ok {
  162. return out, metadata, fmt.Errorf("could not select an auth scheme")
  163. }
  164. ctx = setResolvedAuthScheme(ctx, scheme)
  165. span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID())
  166. span.End()
  167. return next.HandleFinalize(ctx, in)
  168. }
  169. func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) {
  170. sorted := sortAuthOptions(options, m.options.AuthSchemePreference)
  171. for _, option := range sorted {
  172. if option.SchemeID == smithyauth.SchemeIDAnonymous {
  173. return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true
  174. }
  175. for _, scheme := range m.options.AuthSchemes {
  176. if scheme.SchemeID() != option.SchemeID {
  177. continue
  178. }
  179. if scheme.IdentityResolver(m.options) != nil {
  180. return newResolvedAuthScheme(scheme, option), true
  181. }
  182. }
  183. }
  184. return nil, false
  185. }
  186. func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option {
  187. byPriority := make([]*smithyauth.Option, 0, len(options))
  188. for _, prefName := range preferred {
  189. for _, option := range options {
  190. optName := option.SchemeID
  191. if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 {
  192. optName = parts[1]
  193. }
  194. if prefName == optName {
  195. byPriority = append(byPriority, option)
  196. }
  197. }
  198. }
  199. for _, option := range options {
  200. if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool {
  201. return o.SchemeID == option.SchemeID
  202. }) {
  203. byPriority = append(byPriority, option)
  204. }
  205. }
  206. return byPriority
  207. }
  208. type resolvedAuthSchemeKey struct{}
  209. type resolvedAuthScheme struct {
  210. Scheme smithyhttp.AuthScheme
  211. IdentityProperties smithy.Properties
  212. SignerProperties smithy.Properties
  213. }
  214. func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme {
  215. return &resolvedAuthScheme{
  216. Scheme: scheme,
  217. IdentityProperties: option.IdentityProperties,
  218. SignerProperties: option.SignerProperties,
  219. }
  220. }
  221. func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context {
  222. return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme)
  223. }
  224. func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme {
  225. v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme)
  226. return v
  227. }
  228. type getIdentityMiddleware struct {
  229. options Options
  230. }
  231. func (*getIdentityMiddleware) ID() string {
  232. return "GetIdentity"
  233. }
  234. func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
  235. out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
  236. ) {
  237. innerCtx, span := tracing.StartSpan(ctx, "GetIdentity")
  238. defer span.End()
  239. rscheme := getResolvedAuthScheme(innerCtx)
  240. if rscheme == nil {
  241. return out, metadata, fmt.Errorf("no resolved auth scheme")
  242. }
  243. resolver := rscheme.Scheme.IdentityResolver(m.options)
  244. if resolver == nil {
  245. return out, metadata, fmt.Errorf("no identity resolver")
  246. }
  247. identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration",
  248. func() (smithyauth.Identity, error) {
  249. return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties)
  250. },
  251. func(o *metrics.RecordMetricOptions) {
  252. o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
  253. })
  254. if err != nil {
  255. return out, metadata, fmt.Errorf("get identity: %w", err)
  256. }
  257. ctx = setIdentity(ctx, identity)
  258. span.End()
  259. return next.HandleFinalize(ctx, in)
  260. }
  261. type identityKey struct{}
  262. func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context {
  263. return middleware.WithStackValue(ctx, identityKey{}, identity)
  264. }
  265. func getIdentity(ctx context.Context) smithyauth.Identity {
  266. v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity)
  267. return v
  268. }
  269. type signRequestMiddleware struct {
  270. options Options
  271. }
  272. func (*signRequestMiddleware) ID() string {
  273. return "Signing"
  274. }
  275. func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
  276. out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
  277. ) {
  278. _, span := tracing.StartSpan(ctx, "SignRequest")
  279. defer span.End()
  280. req, ok := in.Request.(*smithyhttp.Request)
  281. if !ok {
  282. return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request)
  283. }
  284. rscheme := getResolvedAuthScheme(ctx)
  285. if rscheme == nil {
  286. return out, metadata, fmt.Errorf("no resolved auth scheme")
  287. }
  288. identity := getIdentity(ctx)
  289. if identity == nil {
  290. return out, metadata, fmt.Errorf("no identity")
  291. }
  292. signer := rscheme.Scheme.Signer()
  293. if signer == nil {
  294. return out, metadata, fmt.Errorf("no signer")
  295. }
  296. _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) {
  297. return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties)
  298. }, func(o *metrics.RecordMetricOptions) {
  299. o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
  300. })
  301. if err != nil {
  302. return out, metadata, fmt.Errorf("sign request: %w", err)
  303. }
  304. span.End()
  305. return next.HandleFinalize(ctx, in)
  306. }