src

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

auth.go (10598B)


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