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 }