auth.go

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