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