scheme.go raw
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 }
192