auth.go raw
1 // Code generated by smithy-go-codegen DO NOT EDIT.
2
3 package lightsail
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
129 func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option {
130 return []*smithyauth.Option{
131 {
132 SchemeID: smithyauth.SchemeIDSigV4,
133 SignerProperties: func() smithy.Properties {
134 var props smithy.Properties
135 smithyhttp.SetSigV4SigningName(&props, "lightsail")
136 smithyhttp.SetSigV4SigningRegion(&props, params.Region)
137 return props
138 }(),
139 },
140 }
141 }
142
143 type resolveAuthSchemeMiddleware struct {
144 operation string
145 options Options
146 }
147
148 func (*resolveAuthSchemeMiddleware) ID() string {
149 return "ResolveAuthScheme"
150 }
151
152 func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
153 out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
154 ) {
155 _, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
156 defer span.End()
157
158 params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
159 if err != nil {
160 return out, metadata, fmt.Errorf("bind auth scheme params: %w", err)
161 }
162 options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
163 if err != nil {
164 return out, metadata, fmt.Errorf("resolve auth scheme: %w", err)
165 }
166
167 scheme, ok := m.selectScheme(options)
168 if !ok {
169 return out, metadata, fmt.Errorf("could not select an auth scheme")
170 }
171
172 ctx = setResolvedAuthScheme(ctx, scheme)
173
174 span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID())
175 span.End()
176 return next.HandleFinalize(ctx, in)
177 }
178
179 func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) {
180 sorted := sortAuthOptions(options, m.options.AuthSchemePreference)
181 for _, option := range sorted {
182 if option.SchemeID == smithyauth.SchemeIDAnonymous {
183 return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true
184 }
185
186 for _, scheme := range m.options.AuthSchemes {
187 if scheme.SchemeID() != option.SchemeID {
188 continue
189 }
190
191 if scheme.IdentityResolver(m.options) != nil {
192 return newResolvedAuthScheme(scheme, option), true
193 }
194 }
195 }
196
197 return nil, false
198 }
199
200 func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option {
201 byPriority := make([]*smithyauth.Option, 0, len(options))
202 for _, prefName := range preferred {
203 for _, option := range options {
204 optName := option.SchemeID
205 if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 {
206 optName = parts[1]
207 }
208 if prefName == optName {
209 byPriority = append(byPriority, option)
210 }
211 }
212 }
213 for _, option := range options {
214 if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool {
215 return o.SchemeID == option.SchemeID
216 }) {
217 byPriority = append(byPriority, option)
218 }
219 }
220 return byPriority
221 }
222
223 type resolvedAuthSchemeKey struct{}
224
225 type resolvedAuthScheme struct {
226 Scheme smithyhttp.AuthScheme
227 IdentityProperties smithy.Properties
228 SignerProperties smithy.Properties
229 }
230
231 func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme {
232 return &resolvedAuthScheme{
233 Scheme: scheme,
234 IdentityProperties: option.IdentityProperties,
235 SignerProperties: option.SignerProperties,
236 }
237 }
238
239 func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context {
240 return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme)
241 }
242
243 func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme {
244 v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme)
245 return v
246 }
247
248 type getIdentityMiddleware struct {
249 options Options
250 }
251
252 func (*getIdentityMiddleware) ID() string {
253 return "GetIdentity"
254 }
255
256 func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
257 out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
258 ) {
259 innerCtx, span := tracing.StartSpan(ctx, "GetIdentity")
260 defer span.End()
261
262 rscheme := getResolvedAuthScheme(innerCtx)
263 if rscheme == nil {
264 return out, metadata, fmt.Errorf("no resolved auth scheme")
265 }
266
267 resolver := rscheme.Scheme.IdentityResolver(m.options)
268 if resolver == nil {
269 return out, metadata, fmt.Errorf("no identity resolver")
270 }
271
272 identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration",
273 func() (smithyauth.Identity, error) {
274 return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties)
275 },
276 func(o *metrics.RecordMetricOptions) {
277 o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
278 })
279 if err != nil {
280 return out, metadata, fmt.Errorf("get identity: %w", err)
281 }
282
283 ctx = setIdentity(ctx, identity)
284
285 span.End()
286 return next.HandleFinalize(ctx, in)
287 }
288
289 type identityKey struct{}
290
291 func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context {
292 return middleware.WithStackValue(ctx, identityKey{}, identity)
293 }
294
295 func getIdentity(ctx context.Context) smithyauth.Identity {
296 v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity)
297 return v
298 }
299
300 type signRequestMiddleware struct {
301 options Options
302 }
303
304 func (*signRequestMiddleware) ID() string {
305 return "Signing"
306 }
307
308 func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
309 out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
310 ) {
311 _, span := tracing.StartSpan(ctx, "SignRequest")
312 defer span.End()
313
314 req, ok := in.Request.(*smithyhttp.Request)
315 if !ok {
316 return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request)
317 }
318
319 rscheme := getResolvedAuthScheme(ctx)
320 if rscheme == nil {
321 return out, metadata, fmt.Errorf("no resolved auth scheme")
322 }
323
324 identity := getIdentity(ctx)
325 if identity == nil {
326 return out, metadata, fmt.Errorf("no identity")
327 }
328
329 signer := rscheme.Scheme.Signer()
330 if signer == nil {
331 return out, metadata, fmt.Errorf("no signer")
332 }
333
334 _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) {
335 return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties)
336 }, func(o *metrics.RecordMetricOptions) {
337 o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
338 })
339 if err != nil {
340 return out, metadata, fmt.Errorf("sign request: %w", err)
341 }
342
343 span.End()
344 return next.HandleFinalize(ctx, in)
345 }
346