scheme.go 5.6 KB

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