1// Code generated by smithy-go-codegen DO NOT EDIT.
  2
  3package sso
  4
  5import (
  6	"context"
  7	"fmt"
  8	"github.com/aws/aws-sdk-go-v2/aws"
  9	"github.com/aws/aws-sdk-go-v2/aws/defaults"
 10	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
 11	"github.com/aws/aws-sdk-go-v2/aws/retry"
 12	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
 13	awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
 14	internalauth "github.com/aws/aws-sdk-go-v2/internal/auth"
 15	internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy"
 16	internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources"
 17	internalmiddleware "github.com/aws/aws-sdk-go-v2/internal/middleware"
 18	smithy "github.com/aws/smithy-go"
 19	smithyauth "github.com/aws/smithy-go/auth"
 20	smithydocument "github.com/aws/smithy-go/document"
 21	"github.com/aws/smithy-go/logging"
 22	"github.com/aws/smithy-go/middleware"
 23	smithyhttp "github.com/aws/smithy-go/transport/http"
 24	"net"
 25	"net/http"
 26	"sync/atomic"
 27	"time"
 28)
 29
 30const ServiceID = "SSO"
 31const ServiceAPIVersion = "2019-06-10"
 32
 33// Client provides the API client to make operations call for AWS Single Sign-On.
 34type Client struct {
 35	options Options
 36
 37	// Difference between the time reported by the server and the client
 38	timeOffset *atomic.Int64
 39}
 40
 41// New returns an initialized Client based on the functional options. Provide
 42// additional functional options to further configure the behavior of the client,
 43// such as changing the client's endpoint or adding custom middleware behavior.
 44func New(options Options, optFns ...func(*Options)) *Client {
 45	options = options.Copy()
 46
 47	resolveDefaultLogger(&options)
 48
 49	setResolvedDefaultsMode(&options)
 50
 51	resolveRetryer(&options)
 52
 53	resolveHTTPClient(&options)
 54
 55	resolveHTTPSignerV4(&options)
 56
 57	resolveEndpointResolverV2(&options)
 58
 59	resolveAuthSchemeResolver(&options)
 60
 61	for _, fn := range optFns {
 62		fn(&options)
 63	}
 64
 65	finalizeRetryMaxAttempts(&options)
 66
 67	ignoreAnonymousAuth(&options)
 68
 69	wrapWithAnonymousAuth(&options)
 70
 71	resolveAuthSchemes(&options)
 72
 73	client := &Client{
 74		options: options,
 75	}
 76
 77	initializeTimeOffsetResolver(client)
 78
 79	return client
 80}
 81
 82// Options returns a copy of the client configuration.
 83//
 84// Callers SHOULD NOT perform mutations on any inner structures within client
 85// config. Config overrides should instead be made on a per-operation basis through
 86// functional options.
 87func (c *Client) Options() Options {
 88	return c.options.Copy()
 89}
 90
 91func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) {
 92	ctx = middleware.ClearStackValues(ctx)
 93	stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
 94	options := c.options.Copy()
 95
 96	for _, fn := range optFns {
 97		fn(&options)
 98	}
 99
100	finalizeOperationRetryMaxAttempts(&options, *c)
101
102	finalizeClientEndpointResolverOptions(&options)
103
104	for _, fn := range stackFns {
105		if err := fn(stack, options); err != nil {
106			return nil, metadata, err
107		}
108	}
109
110	for _, fn := range options.APIOptions {
111		if err := fn(stack); err != nil {
112			return nil, metadata, err
113		}
114	}
115
116	handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
117	result, metadata, err = handler.Handle(ctx, params)
118	if err != nil {
119		err = &smithy.OperationError{
120			ServiceID:     ServiceID,
121			OperationName: opID,
122			Err:           err,
123		}
124	}
125	return result, metadata, err
126}
127
128type operationInputKey struct{}
129
130func setOperationInput(ctx context.Context, input interface{}) context.Context {
131	return middleware.WithStackValue(ctx, operationInputKey{}, input)
132}
133
134func getOperationInput(ctx context.Context) interface{} {
135	return middleware.GetStackValue(ctx, operationInputKey{})
136}
137
138type setOperationInputMiddleware struct {
139}
140
141func (*setOperationInputMiddleware) ID() string {
142	return "setOperationInput"
143}
144
145func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
146	out middleware.SerializeOutput, metadata middleware.Metadata, err error,
147) {
148	ctx = setOperationInput(ctx, in.Parameters)
149	return next.HandleSerialize(ctx, in)
150}
151
152func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error {
153	if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil {
154		return fmt.Errorf("add ResolveAuthScheme: %w", err)
155	}
156	if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil {
157		return fmt.Errorf("add GetIdentity: %v", err)
158	}
159	if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil {
160		return fmt.Errorf("add ResolveEndpointV2: %v", err)
161	}
162	if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil {
163		return fmt.Errorf("add Signing: %w", err)
164	}
165	return nil
166}
167func resolveAuthSchemeResolver(options *Options) {
168	if options.AuthSchemeResolver == nil {
169		options.AuthSchemeResolver = &defaultAuthSchemeResolver{}
170	}
171}
172
173func resolveAuthSchemes(options *Options) {
174	if options.AuthSchemes == nil {
175		options.AuthSchemes = []smithyhttp.AuthScheme{
176			internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{
177				Signer:     options.HTTPSignerV4,
178				Logger:     options.Logger,
179				LogSigning: options.ClientLogMode.IsSigning(),
180			}),
181		}
182	}
183}
184
185type noSmithyDocumentSerde = smithydocument.NoSerde
186
187type legacyEndpointContextSetter struct {
188	LegacyResolver EndpointResolver
189}
190
191func (*legacyEndpointContextSetter) ID() string {
192	return "legacyEndpointContextSetter"
193}
194
195func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
196	out middleware.InitializeOutput, metadata middleware.Metadata, err error,
197) {
198	if m.LegacyResolver != nil {
199		ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true)
200	}
201
202	return next.HandleInitialize(ctx, in)
203
204}
205func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error {
206	return stack.Initialize.Add(&legacyEndpointContextSetter{
207		LegacyResolver: o.EndpointResolver,
208	}, middleware.Before)
209}
210
211func resolveDefaultLogger(o *Options) {
212	if o.Logger != nil {
213		return
214	}
215	o.Logger = logging.Nop{}
216}
217
218func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error {
219	return middleware.AddSetLoggerMiddleware(stack, o.Logger)
220}
221
222func setResolvedDefaultsMode(o *Options) {
223	if len(o.resolvedDefaultsMode) > 0 {
224		return
225	}
226
227	var mode aws.DefaultsMode
228	mode.SetFromString(string(o.DefaultsMode))
229
230	if mode == aws.DefaultsModeAuto {
231		mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment)
232	}
233
234	o.resolvedDefaultsMode = mode
235}
236
237// NewFromConfig returns a new client from the provided config.
238func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
239	opts := Options{
240		Region:                cfg.Region,
241		DefaultsMode:          cfg.DefaultsMode,
242		RuntimeEnvironment:    cfg.RuntimeEnvironment,
243		HTTPClient:            cfg.HTTPClient,
244		Credentials:           cfg.Credentials,
245		APIOptions:            cfg.APIOptions,
246		Logger:                cfg.Logger,
247		ClientLogMode:         cfg.ClientLogMode,
248		AppID:                 cfg.AppID,
249		AccountIDEndpointMode: cfg.AccountIDEndpointMode,
250	}
251	resolveAWSRetryerProvider(cfg, &opts)
252	resolveAWSRetryMaxAttempts(cfg, &opts)
253	resolveAWSRetryMode(cfg, &opts)
254	resolveAWSEndpointResolver(cfg, &opts)
255	resolveUseDualStackEndpoint(cfg, &opts)
256	resolveUseFIPSEndpoint(cfg, &opts)
257	resolveBaseEndpoint(cfg, &opts)
258	return New(opts, optFns...)
259}
260
261func resolveHTTPClient(o *Options) {
262	var buildable *awshttp.BuildableClient
263
264	if o.HTTPClient != nil {
265		var ok bool
266		buildable, ok = o.HTTPClient.(*awshttp.BuildableClient)
267		if !ok {
268			return
269		}
270	} else {
271		buildable = awshttp.NewBuildableClient()
272	}
273
274	modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode)
275	if err == nil {
276		buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) {
277			if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok {
278				dialer.Timeout = dialerTimeout
279			}
280		})
281
282		buildable = buildable.WithTransportOptions(func(transport *http.Transport) {
283			if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok {
284				transport.TLSHandshakeTimeout = tlsHandshakeTimeout
285			}
286		})
287	}
288
289	o.HTTPClient = buildable
290}
291
292func resolveRetryer(o *Options) {
293	if o.Retryer != nil {
294		return
295	}
296
297	if len(o.RetryMode) == 0 {
298		modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode)
299		if err == nil {
300			o.RetryMode = modeConfig.RetryMode
301		}
302	}
303	if len(o.RetryMode) == 0 {
304		o.RetryMode = aws.RetryModeStandard
305	}
306
307	var standardOptions []func(*retry.StandardOptions)
308	if v := o.RetryMaxAttempts; v != 0 {
309		standardOptions = append(standardOptions, func(so *retry.StandardOptions) {
310			so.MaxAttempts = v
311		})
312	}
313
314	switch o.RetryMode {
315	case aws.RetryModeAdaptive:
316		var adaptiveOptions []func(*retry.AdaptiveModeOptions)
317		if len(standardOptions) != 0 {
318			adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) {
319				ao.StandardOptions = append(ao.StandardOptions, standardOptions...)
320			})
321		}
322		o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...)
323
324	default:
325		o.Retryer = retry.NewStandard(standardOptions...)
326	}
327}
328
329func resolveAWSRetryerProvider(cfg aws.Config, o *Options) {
330	if cfg.Retryer == nil {
331		return
332	}
333	o.Retryer = cfg.Retryer()
334}
335
336func resolveAWSRetryMode(cfg aws.Config, o *Options) {
337	if len(cfg.RetryMode) == 0 {
338		return
339	}
340	o.RetryMode = cfg.RetryMode
341}
342func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) {
343	if cfg.RetryMaxAttempts == 0 {
344		return
345	}
346	o.RetryMaxAttempts = cfg.RetryMaxAttempts
347}
348
349func finalizeRetryMaxAttempts(o *Options) {
350	if o.RetryMaxAttempts == 0 {
351		return
352	}
353
354	o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts)
355}
356
357func finalizeOperationRetryMaxAttempts(o *Options, client Client) {
358	if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts {
359		return
360	}
361
362	o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts)
363}
364
365func resolveAWSEndpointResolver(cfg aws.Config, o *Options) {
366	if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil {
367		return
368	}
369	o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions)
370}
371
372func addClientUserAgent(stack *middleware.Stack, options Options) error {
373	ua, err := getOrAddRequestUserAgent(stack)
374	if err != nil {
375		return err
376	}
377
378	ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sso", goModuleVersion)
379	if len(options.AppID) > 0 {
380		ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)
381	}
382
383	return nil
384}
385
386func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) {
387	id := (*awsmiddleware.RequestUserAgent)(nil).ID()
388	mw, ok := stack.Build.Get(id)
389	if !ok {
390		mw = awsmiddleware.NewRequestUserAgent()
391		if err := stack.Build.Add(mw, middleware.After); err != nil {
392			return nil, err
393		}
394	}
395
396	ua, ok := mw.(*awsmiddleware.RequestUserAgent)
397	if !ok {
398		return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id)
399	}
400
401	return ua, nil
402}
403
404type HTTPSignerV4 interface {
405	SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error
406}
407
408func resolveHTTPSignerV4(o *Options) {
409	if o.HTTPSignerV4 != nil {
410		return
411	}
412	o.HTTPSignerV4 = newDefaultV4Signer(*o)
413}
414
415func newDefaultV4Signer(o Options) *v4.Signer {
416	return v4.NewSigner(func(so *v4.SignerOptions) {
417		so.Logger = o.Logger
418		so.LogSigning = o.ClientLogMode.IsSigning()
419	})
420}
421
422func addClientRequestID(stack *middleware.Stack) error {
423	return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After)
424}
425
426func addComputeContentLength(stack *middleware.Stack) error {
427	return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After)
428}
429
430func addRawResponseToMetadata(stack *middleware.Stack) error {
431	return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before)
432}
433
434func addRecordResponseTiming(stack *middleware.Stack) error {
435	return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After)
436}
437func addStreamingEventsPayload(stack *middleware.Stack) error {
438	return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before)
439}
440
441func addUnsignedPayload(stack *middleware.Stack) error {
442	return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After)
443}
444
445func addComputePayloadSHA256(stack *middleware.Stack) error {
446	return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After)
447}
448
449func addContentSHA256Header(stack *middleware.Stack) error {
450	return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After)
451}
452
453func addIsWaiterUserAgent(o *Options) {
454	o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error {
455		ua, err := getOrAddRequestUserAgent(stack)
456		if err != nil {
457			return err
458		}
459
460		ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter)
461		return nil
462	})
463}
464
465func addIsPaginatorUserAgent(o *Options) {
466	o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error {
467		ua, err := getOrAddRequestUserAgent(stack)
468		if err != nil {
469			return err
470		}
471
472		ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator)
473		return nil
474	})
475}
476
477func addRetry(stack *middleware.Stack, o Options) error {
478	attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) {
479		m.LogAttempts = o.ClientLogMode.IsRetries()
480	})
481	if err := stack.Finalize.Insert(attempt, "Signing", middleware.Before); err != nil {
482		return err
483	}
484	if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil {
485		return err
486	}
487	return nil
488}
489
490// resolves dual-stack endpoint configuration
491func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error {
492	if len(cfg.ConfigSources) == 0 {
493		return nil
494	}
495	value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources)
496	if err != nil {
497		return err
498	}
499	if found {
500		o.EndpointOptions.UseDualStackEndpoint = value
501	}
502	return nil
503}
504
505// resolves FIPS endpoint configuration
506func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error {
507	if len(cfg.ConfigSources) == 0 {
508		return nil
509	}
510	value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources)
511	if err != nil {
512		return err
513	}
514	if found {
515		o.EndpointOptions.UseFIPSEndpoint = value
516	}
517	return nil
518}
519
520func resolveAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) *string {
521	if mode == aws.AccountIDEndpointModeDisabled {
522		return nil
523	}
524
525	if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); ok && ca.Credentials.AccountID != "" {
526		return aws.String(ca.Credentials.AccountID)
527	}
528
529	return nil
530}
531
532func addTimeOffsetBuild(stack *middleware.Stack, c *Client) error {
533	mw := internalmiddleware.AddTimeOffsetMiddleware{Offset: c.timeOffset}
534	if err := stack.Build.Add(&mw, middleware.After); err != nil {
535		return err
536	}
537	return stack.Deserialize.Insert(&mw, "RecordResponseTiming", middleware.Before)
538}
539func initializeTimeOffsetResolver(c *Client) {
540	c.timeOffset = new(atomic.Int64)
541}
542
543func checkAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) error {
544	switch mode {
545	case aws.AccountIDEndpointModeUnset:
546	case aws.AccountIDEndpointModePreferred:
547	case aws.AccountIDEndpointModeDisabled:
548	case aws.AccountIDEndpointModeRequired:
549		if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); !ok {
550			return fmt.Errorf("accountID is required but not set")
551		} else if ca.Credentials.AccountID == "" {
552			return fmt.Errorf("accountID is required but not set")
553		}
554	// default check in case invalid mode is configured through request config
555	default:
556		return fmt.Errorf("invalid accountID endpoint mode %s, must be preferred/required/disabled", mode)
557	}
558
559	return nil
560}
561
562func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
563	ua, err := getOrAddRequestUserAgent(stack)
564	if err != nil {
565		return err
566	}
567
568	switch options.Retryer.(type) {
569	case *retry.Standard:
570		ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard)
571	case *retry.AdaptiveMode:
572		ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive)
573	}
574	return nil
575}
576
577func addRecursionDetection(stack *middleware.Stack) error {
578	return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After)
579}
580
581func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error {
582	return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before)
583
584}
585
586func addResponseErrorMiddleware(stack *middleware.Stack) error {
587	return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before)
588
589}
590
591func addRequestResponseLogging(stack *middleware.Stack, o Options) error {
592	return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{
593		LogRequest:          o.ClientLogMode.IsRequest(),
594		LogRequestWithBody:  o.ClientLogMode.IsRequestWithBody(),
595		LogResponse:         o.ClientLogMode.IsResponse(),
596		LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(),
597	}, middleware.After)
598}
599
600type disableHTTPSMiddleware struct {
601	DisableHTTPS bool
602}
603
604func (*disableHTTPSMiddleware) ID() string {
605	return "disableHTTPS"
606}
607
608func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
609	out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
610) {
611	req, ok := in.Request.(*smithyhttp.Request)
612	if !ok {
613		return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
614	}
615
616	if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) {
617		req.URL.Scheme = "http"
618	}
619
620	return next.HandleFinalize(ctx, in)
621}
622
623func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error {
624	return stack.Finalize.Insert(&disableHTTPSMiddleware{
625		DisableHTTPS: o.EndpointOptions.DisableHTTPS,
626	}, "ResolveEndpointV2", middleware.After)
627}