src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

resolve_bearer_token.go (3787B)


      1 package config
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 	"time"
      7 
      8 	"github.com/aws/aws-sdk-go-v2/aws"
      9 	"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
     10 	"github.com/aws/aws-sdk-go-v2/service/ssooidc"
     11 	smithybearer "github.com/aws/smithy-go/auth/bearer"
     12 )
     13 
     14 // resolveBearerAuthToken extracts a token provider from the config sources.
     15 //
     16 // If an explicit bearer authentication token provider is not found the
     17 // resolver will fallback to resolving token provider via other config sources
     18 // such as SharedConfig.
     19 func resolveBearerAuthToken(ctx context.Context, cfg *aws.Config, configs configs) error {
     20 	found, err := resolveBearerAuthTokenProvider(ctx, cfg, configs)
     21 	if found || err != nil {
     22 		return err
     23 	}
     24 
     25 	return resolveBearerAuthTokenProviderChain(ctx, cfg, configs)
     26 }
     27 
     28 // resolveBearerAuthTokenProvider extracts the first instance of
     29 // BearerAuthTokenProvider from the config sources.
     30 //
     31 // The resolved BearerAuthTokenProvider will be wrapped in a cache to ensure
     32 // the Token is only refreshed when needed. This also protects the
     33 // TokenProvider so it can be used concurrently.
     34 //
     35 // Config providers used:
     36 // * bearerAuthTokenProviderProvider
     37 func resolveBearerAuthTokenProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) {
     38 	tokenProvider, found, err := getBearerAuthTokenProvider(ctx, configs)
     39 	if !found || err != nil {
     40 		return false, err
     41 	}
     42 
     43 	cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
     44 		ctx, configs, tokenProvider)
     45 	if err != nil {
     46 		return false, err
     47 	}
     48 
     49 	return true, nil
     50 }
     51 
     52 func resolveBearerAuthTokenProviderChain(ctx context.Context, cfg *aws.Config, configs configs) (err error) {
     53 	_, sharedConfig, _ := getAWSConfigSources(configs)
     54 
     55 	var provider smithybearer.TokenProvider
     56 
     57 	if sharedConfig.SSOSession != nil {
     58 		provider, err = resolveBearerAuthSSOTokenProvider(
     59 			ctx, cfg, sharedConfig.SSOSession, configs)
     60 	}
     61 
     62 	if err == nil && provider != nil {
     63 		cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
     64 			ctx, configs, provider)
     65 	}
     66 
     67 	return err
     68 }
     69 
     70 func resolveBearerAuthSSOTokenProvider(ctx context.Context, cfg *aws.Config, session *SSOSession, configs configs) (*ssocreds.SSOTokenProvider, error) {
     71 	ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs)
     72 	if err != nil {
     73 		return nil, fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err)
     74 	}
     75 
     76 	var optFns []func(*ssocreds.SSOTokenProviderOptions)
     77 	if found {
     78 		optFns = append(optFns, ssoTokenProviderOptionsFn)
     79 	}
     80 
     81 	cachePath, err := ssocreds.StandardCachedTokenFilepath(session.Name)
     82 	if err != nil {
     83 		return nil, fmt.Errorf("failed to get SSOTokenProvider's cache path, %w", err)
     84 	}
     85 
     86 	client := ssooidc.NewFromConfig(*cfg)
     87 	provider := ssocreds.NewSSOTokenProvider(client, cachePath, optFns...)
     88 
     89 	return provider, nil
     90 }
     91 
     92 // wrapWithBearerAuthTokenCache will wrap provider with an smithy-go
     93 // bearer/auth#TokenCache with the provided options if the provider is not
     94 // already a TokenCache.
     95 func wrapWithBearerAuthTokenCache(
     96 	ctx context.Context,
     97 	cfgs configs,
     98 	provider smithybearer.TokenProvider,
     99 	optFns ...func(*smithybearer.TokenCacheOptions),
    100 ) (smithybearer.TokenProvider, error) {
    101 	_, ok := provider.(*smithybearer.TokenCache)
    102 	if ok {
    103 		return provider, nil
    104 	}
    105 
    106 	tokenCacheConfigOptions, optionsFound, err := getBearerAuthTokenCacheOptions(ctx, cfgs)
    107 	if err != nil {
    108 		return nil, err
    109 	}
    110 
    111 	opts := make([]func(*smithybearer.TokenCacheOptions), 0, 2+len(optFns))
    112 	opts = append(opts, func(o *smithybearer.TokenCacheOptions) {
    113 		o.RefreshBeforeExpires = 5 * time.Minute
    114 		o.RetrieveBearerTokenTimeout = 30 * time.Second
    115 	})
    116 	opts = append(opts, optFns...)
    117 	if optionsFound {
    118 		opts = append(opts, tokenCacheConfigOptions)
    119 	}
    120 
    121 	return smithybearer.NewTokenCache(provider, opts...), nil
    122 }