src

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

scheme.go (5688B)


      1 package auth
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 
      7 	smithy "github.com/aws/smithy-go"
      8 	"github.com/aws/smithy-go/middleware"
      9 )
     10 
     11 // SigV4 is a constant representing
     12 // Authentication Scheme Signature Version 4
     13 const SigV4 = "sigv4"
     14 
     15 // SigV4A is a constant representing
     16 // Authentication Scheme Signature Version 4A
     17 const SigV4A = "sigv4a"
     18 
     19 // SigV4S3Express identifies the S3 S3Express auth scheme.
     20 const SigV4S3Express = "sigv4-s3express"
     21 
     22 // None is a constant representing the
     23 // None Authentication Scheme
     24 const None = "none"
     25 
     26 // SupportedSchemes is a data structure
     27 // that indicates the list of supported AWS
     28 // authentication schemes
     29 var SupportedSchemes = map[string]bool{
     30 	SigV4:          true,
     31 	SigV4A:         true,
     32 	SigV4S3Express: true,
     33 	None:           true,
     34 }
     35 
     36 // AuthenticationScheme is a representation of
     37 // AWS authentication schemes
     38 type AuthenticationScheme interface {
     39 	isAuthenticationScheme()
     40 }
     41 
     42 // AuthenticationSchemeV4 is a AWS SigV4 representation
     43 type AuthenticationSchemeV4 struct {
     44 	Name                  string
     45 	SigningName           *string
     46 	SigningRegion         *string
     47 	DisableDoubleEncoding *bool
     48 }
     49 
     50 func (a *AuthenticationSchemeV4) isAuthenticationScheme() {}
     51 
     52 // AuthenticationSchemeV4A is a AWS SigV4A representation
     53 type AuthenticationSchemeV4A struct {
     54 	Name                  string
     55 	SigningName           *string
     56 	SigningRegionSet      []string
     57 	DisableDoubleEncoding *bool
     58 }
     59 
     60 func (a *AuthenticationSchemeV4A) isAuthenticationScheme() {}
     61 
     62 // AuthenticationSchemeNone is a representation for the none auth scheme
     63 type AuthenticationSchemeNone struct{}
     64 
     65 func (a *AuthenticationSchemeNone) isAuthenticationScheme() {}
     66 
     67 // NoAuthenticationSchemesFoundError is used in signaling
     68 // that no authentication schemes have been specified.
     69 type NoAuthenticationSchemesFoundError struct{}
     70 
     71 func (e *NoAuthenticationSchemesFoundError) Error() string {
     72 	return fmt.Sprint("No authentication schemes specified.")
     73 }
     74 
     75 // UnSupportedAuthenticationSchemeSpecifiedError is used in
     76 // signaling that only unsupported authentication schemes
     77 // were specified.
     78 type UnSupportedAuthenticationSchemeSpecifiedError struct {
     79 	UnsupportedSchemes []string
     80 }
     81 
     82 func (e *UnSupportedAuthenticationSchemeSpecifiedError) Error() string {
     83 	return fmt.Sprint("Unsupported authentication scheme specified.")
     84 }
     85 
     86 // GetAuthenticationSchemes extracts the relevant authentication scheme data
     87 // into a custom strongly typed Go data structure.
     88 func GetAuthenticationSchemes(p *smithy.Properties) ([]AuthenticationScheme, error) {
     89 	var result []AuthenticationScheme
     90 	if !p.Has("authSchemes") {
     91 		return nil, &NoAuthenticationSchemesFoundError{}
     92 	}
     93 
     94 	authSchemes, _ := p.Get("authSchemes").([]interface{})
     95 
     96 	var unsupportedSchemes []string
     97 	for _, scheme := range authSchemes {
     98 		authScheme, _ := scheme.(map[string]interface{})
     99 
    100 		version := authScheme["name"].(string)
    101 		switch version {
    102 		case SigV4, SigV4S3Express:
    103 			v4Scheme := AuthenticationSchemeV4{
    104 				Name:                  version,
    105 				SigningName:           getSigningName(authScheme),
    106 				SigningRegion:         getSigningRegion(authScheme),
    107 				DisableDoubleEncoding: getDisableDoubleEncoding(authScheme),
    108 			}
    109 			result = append(result, AuthenticationScheme(&v4Scheme))
    110 		case SigV4A:
    111 			v4aScheme := AuthenticationSchemeV4A{
    112 				Name:                  SigV4A,
    113 				SigningName:           getSigningName(authScheme),
    114 				SigningRegionSet:      getSigningRegionSet(authScheme),
    115 				DisableDoubleEncoding: getDisableDoubleEncoding(authScheme),
    116 			}
    117 			result = append(result, AuthenticationScheme(&v4aScheme))
    118 		case None:
    119 			noneScheme := AuthenticationSchemeNone{}
    120 			result = append(result, AuthenticationScheme(&noneScheme))
    121 		default:
    122 			unsupportedSchemes = append(unsupportedSchemes, authScheme["name"].(string))
    123 			continue
    124 		}
    125 	}
    126 
    127 	if len(result) == 0 {
    128 		return nil, &UnSupportedAuthenticationSchemeSpecifiedError{
    129 			UnsupportedSchemes: unsupportedSchemes,
    130 		}
    131 	}
    132 
    133 	return result, nil
    134 }
    135 
    136 type disableDoubleEncoding struct{}
    137 
    138 // SetDisableDoubleEncoding sets or modifies the disable double encoding option
    139 // on the context.
    140 //
    141 // Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
    142 // to clear all stack values.
    143 func SetDisableDoubleEncoding(ctx context.Context, value bool) context.Context {
    144 	return middleware.WithStackValue(ctx, disableDoubleEncoding{}, value)
    145 }
    146 
    147 // GetDisableDoubleEncoding retrieves the disable double encoding option
    148 // from the context.
    149 //
    150 // Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
    151 // to clear all stack values.
    152 func GetDisableDoubleEncoding(ctx context.Context) (value bool, ok bool) {
    153 	value, ok = middleware.GetStackValue(ctx, disableDoubleEncoding{}).(bool)
    154 	return value, ok
    155 }
    156 
    157 func getSigningName(authScheme map[string]interface{}) *string {
    158 	signingName, ok := authScheme["signingName"].(string)
    159 	if !ok || signingName == "" {
    160 		return nil
    161 	}
    162 	return &signingName
    163 }
    164 
    165 func getSigningRegionSet(authScheme map[string]interface{}) []string {
    166 	untypedSigningRegionSet, ok := authScheme["signingRegionSet"].([]interface{})
    167 	if !ok {
    168 		return nil
    169 	}
    170 	signingRegionSet := []string{}
    171 	for _, item := range untypedSigningRegionSet {
    172 		signingRegionSet = append(signingRegionSet, item.(string))
    173 	}
    174 	return signingRegionSet
    175 }
    176 
    177 func getSigningRegion(authScheme map[string]interface{}) *string {
    178 	signingRegion, ok := authScheme["signingRegion"].(string)
    179 	if !ok || signingRegion == "" {
    180 		return nil
    181 	}
    182 	return &signingRegion
    183 }
    184 
    185 func getDisableDoubleEncoding(authScheme map[string]interface{}) *bool {
    186 	disableDoubleEncoding, ok := authScheme["disableDoubleEncoding"].(bool)
    187 	if !ok {
    188 		return nil
    189 	}
    190 	return &disableDoubleEncoding
    191 }