Merge pull request #3990 from DavidSpek/update-aws-sdk

fix(deps): update module github.com/aws/aws-sdk-go to v1.44.325
This commit is contained in:
Hayley Swimelar 2023-08-17 11:36:27 -07:00 committed by GitHub
commit d7241d788b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 18507 additions and 3480 deletions

2
go.mod
View file

@ -9,7 +9,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d
github.com/aws/aws-sdk-go v1.43.16
github.com/aws/aws-sdk-go v1.44.325
github.com/bshuster-repo/logrus-logstash-hook v1.0.0
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c

18
go.sum
View file

@ -63,8 +63,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aws/aws-sdk-go v1.43.16 h1:Y7wBby44f+tINqJjw5fLH3vA+gFq4uMITIKqditwM14=
github.com/aws/aws-sdk-go v1.43.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.325 h1:jF/L99fJSq/BfiLmUOflO/aM+LwcqBm0Fe/qTK5xxuI=
github.com/aws/aws-sdk-go v1.44.325/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -305,6 +305,7 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
@ -324,6 +325,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -356,6 +358,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -385,8 +388,10 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -406,6 +411,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -448,10 +454,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -459,6 +469,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -504,6 +515,7 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View file

@ -0,0 +1,50 @@
package bearer
import (
"github.com/aws/aws-sdk-go/aws"
"time"
)
// Token provides a type wrapping a bearer token and expiration metadata.
type Token struct {
Value string
CanExpire bool
Expires time.Time
}
// Expired returns if the token's Expires time is before or equal to the time
// provided. If CanExpire is false, Expired will always return false.
func (t Token) Expired(now time.Time) bool {
if !t.CanExpire {
return false
}
now = now.Round(0)
return now.Equal(t.Expires) || now.After(t.Expires)
}
// TokenProvider provides interface for retrieving bearer tokens.
type TokenProvider interface {
RetrieveBearerToken(aws.Context) (Token, error)
}
// TokenProviderFunc provides a helper utility to wrap a function as a type
// that implements the TokenProvider interface.
type TokenProviderFunc func(aws.Context) (Token, error)
// RetrieveBearerToken calls the wrapped function, returning the Token or
// error.
func (fn TokenProviderFunc) RetrieveBearerToken(ctx aws.Context) (Token, error) {
return fn(ctx)
}
// StaticTokenProvider provides a utility for wrapping a static bearer token
// value within an implementation of a token provider.
type StaticTokenProvider struct {
Token Token
}
// RetrieveBearerToken returns the static token specified.
func (s StaticTokenProvider) RetrieveBearerToken(aws.Context) (Token, error) {
return s.Token, nil
}

View file

@ -20,16 +20,16 @@ type RequestRetryer interface{}
// A Config provides service configuration for service clients. By default,
// all clients will use the defaults.DefaultConfig structure.
//
// // Create Session with MaxRetries configuration to be shared by multiple
// // service clients.
// sess := session.Must(session.NewSession(&aws.Config{
// MaxRetries: aws.Int(3),
// }))
// // Create Session with MaxRetries configuration to be shared by multiple
// // service clients.
// sess := session.Must(session.NewSession(&aws.Config{
// MaxRetries: aws.Int(3),
// }))
//
// // Create S3 service client with a specific Region.
// svc := s3.New(sess, &aws.Config{
// Region: aws.String("us-west-2"),
// })
// // Create S3 service client with a specific Region.
// svc := s3.New(sess, &aws.Config{
// Region: aws.String("us-west-2"),
// })
type Config struct {
// Enables verbose error printing of all credential chain errors.
// Should be used when wanting to see all errors while attempting to
@ -192,6 +192,23 @@ type Config struct {
//
EC2MetadataDisableTimeoutOverride *bool
// Set this to `false` to disable EC2Metadata client from falling back to IMDSv1.
// By default, EC2 role credentials will fall back to IMDSv1 as needed for backwards compatibility.
// You can disable this behavior by explicitly setting this flag to `false`. When false, the EC2Metadata
// client will return any errors encountered from attempting to fetch a token instead of silently
// using the insecure data flow of IMDSv1.
//
// Example:
// sess := session.Must(session.NewSession(aws.NewConfig()
// .WithEC2MetadataEnableFallback(false)))
//
// svc := s3.New(sess)
//
// See [configuring IMDS] for more information.
//
// [configuring IMDS]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
EC2MetadataEnableFallback *bool
// Instructs the endpoint to be generated for a service client to
// be the dual stack endpoint. The dual stack endpoint will support
// both IPv4 and IPv6 addressing.
@ -283,16 +300,16 @@ type Config struct {
// NewConfig returns a new Config pointer that can be chained with builder
// methods to set multiple configuration values inline without using pointers.
//
// // Create Session with MaxRetries configuration to be shared by multiple
// // service clients.
// sess := session.Must(session.NewSession(aws.NewConfig().
// WithMaxRetries(3),
// ))
// // Create Session with MaxRetries configuration to be shared by multiple
// // service clients.
// sess := session.Must(session.NewSession(aws.NewConfig().
// WithMaxRetries(3),
// ))
//
// // Create S3 service client with a specific Region.
// svc := s3.New(sess, aws.NewConfig().
// WithRegion("us-west-2"),
// )
// // Create S3 service client with a specific Region.
// svc := s3.New(sess, aws.NewConfig().
// WithRegion("us-west-2"),
// )
func NewConfig() *Config {
return &Config{}
}
@ -432,6 +449,13 @@ func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
return c
}
// WithEC2MetadataEnableFallback sets a config EC2MetadataEnableFallback value
// returning a Config pointer for chaining.
func (c *Config) WithEC2MetadataEnableFallback(v bool) *Config {
c.EC2MetadataEnableFallback = &v
return c
}
// WithSleepDelay overrides the function used to sleep while waiting for the
// next retry. Defaults to time.Sleep.
func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
@ -576,6 +600,10 @@ func mergeInConfig(dst *Config, other *Config) {
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
}
if other.EC2MetadataEnableFallback != nil {
dst.EC2MetadataEnableFallback = other.EC2MetadataEnableFallback
}
if other.SleepDelay != nil {
dst.SleepDelay = other.SleepDelay
}

View file

@ -226,12 +226,24 @@ func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider))
return credentials.NewCredentials(p)
}
type credentialProcessResponse struct {
Version int
AccessKeyID string `json:"AccessKeyId"`
// A CredentialProcessResponse is the AWS credentials format that must be
// returned when executing an external credential_process.
type CredentialProcessResponse struct {
// As of this writing, the Version key must be set to 1. This might
// increment over time as the structure evolves.
Version int
// The access key ID that identifies the temporary security credentials.
AccessKeyID string `json:"AccessKeyId"`
// The secret access key that can be used to sign requests.
SecretAccessKey string
SessionToken string
Expiration *time.Time
// The token that users must pass to the service API to use the temporary credentials.
SessionToken string
// The date on which the current credentials expire.
Expiration *time.Time
}
// Retrieve executes the 'credential_process' and returns the credentials.
@ -242,7 +254,7 @@ func (p *ProcessProvider) Retrieve() (credentials.Value, error) {
}
// Serialize and validate response
resp := &credentialProcessResponse{}
resp := &CredentialProcessResponse{}
if err = json.Unmarshal(out, resp); err != nil {
return credentials.Value{ProviderName: ProviderName}, awserr.New(
ErrCodeProcessProviderParse,

View file

@ -4,13 +4,13 @@ import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"path/filepath"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/auth/bearer"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/credentials"
@ -55,6 +55,19 @@ type Provider struct {
// The URL that points to the organization's AWS Single Sign-On (AWS SSO) user portal.
StartURL string
// The filepath the cached token will be retrieved from. If unset Provider will
// use the startURL to determine the filepath at.
//
// ~/.aws/sso/cache/<sha1-hex-encoded-startURL>.json
//
// If custom cached token filepath is used, the Provider's startUrl
// parameter will be ignored.
CachedTokenFilepath string
// Used by the SSOCredentialProvider if a token configuration
// profile is used in the shared config
TokenProvider bearer.TokenProvider
}
// NewCredentials returns a new AWS Single Sign-On (AWS SSO) credential provider. The ConfigProvider is expected to be configured
@ -89,13 +102,31 @@ func (p *Provider) Retrieve() (credentials.Value, error) {
// RetrieveWithContext retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
// by exchanging the accessToken present in ~/.aws/sso/cache.
func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
tokenFile, err := loadTokenFile(p.StartURL)
if err != nil {
return credentials.Value{}, err
var accessToken *string
if p.TokenProvider != nil {
token, err := p.TokenProvider.RetrieveBearerToken(ctx)
if err != nil {
return credentials.Value{}, err
}
accessToken = &token.Value
} else {
if p.CachedTokenFilepath == "" {
cachedTokenFilePath, err := getCachedFilePath(p.StartURL)
if err != nil {
return credentials.Value{}, err
}
p.CachedTokenFilepath = cachedTokenFilePath
}
tokenFile, err := loadTokenFile(p.CachedTokenFilepath)
if err != nil {
return credentials.Value{}, err
}
accessToken = &tokenFile.AccessToken
}
output, err := p.Client.GetRoleCredentialsWithContext(ctx, &sso.GetRoleCredentialsInput{
AccessToken: &tokenFile.AccessToken,
AccessToken: accessToken,
AccountId: &p.AccountID,
RoleName: &p.RoleName,
})
@ -114,32 +145,13 @@ func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Val
}, nil
}
func getCacheFileName(url string) (string, error) {
func getCachedFilePath(startUrl string) (string, error) {
hash := sha1.New()
_, err := hash.Write([]byte(url))
_, err := hash.Write([]byte(startUrl))
if err != nil {
return "", err
}
return strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json", nil
}
type rfc3339 time.Time
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
var value string
if err := json.Unmarshal(bytes, &value); err != nil {
return err
}
parse, err := time.Parse(time.RFC3339, value)
if err != nil {
return fmt.Errorf("expected RFC3339 timestamp: %v", err)
}
*r = rfc3339(parse)
return nil
return filepath.Join(defaultCacheLocation(), strings.ToLower(hex.EncodeToString(hash.Sum(nil)))+".json"), nil
}
type token struct {
@ -153,13 +165,8 @@ func (t token) Expired() bool {
return nowTime().Round(0).After(time.Time(t.ExpiresAt))
}
func loadTokenFile(startURL string) (t token, err error) {
key, err := getCacheFileName(startURL)
if err != nil {
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
}
fileBytes, err := ioutil.ReadFile(filepath.Join(defaultCacheLocation(), key))
func loadTokenFile(cachedTokenPath string) (t token, err error) {
fileBytes, err := ioutil.ReadFile(cachedTokenPath)
if err != nil {
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
}

View file

@ -0,0 +1,237 @@
package ssocreds
import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"time"
)
var resolvedOsUserHomeDir = shareddefaults.UserHomeDir
// StandardCachedTokenFilepath returns the filepath for the cached SSO token file, or
// error if unable get derive the path. Key that will be used to compute a SHA1
// value that is hex encoded.
//
// Derives the filepath using the Key as:
//
// ~/.aws/sso/cache/<sha1-hex-encoded-key>.json
func StandardCachedTokenFilepath(key string) (string, error) {
homeDir := resolvedOsUserHomeDir()
if len(homeDir) == 0 {
return "", fmt.Errorf("unable to get USER's home directory for cached token")
}
hash := sha1.New()
if _, err := hash.Write([]byte(key)); err != nil {
return "", fmt.Errorf("unable to compute cached token filepath key SHA1 hash, %v", err)
}
cacheFilename := strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json"
return filepath.Join(homeDir, ".aws", "sso", "cache", cacheFilename), nil
}
type tokenKnownFields struct {
AccessToken string `json:"accessToken,omitempty"`
ExpiresAt *rfc3339 `json:"expiresAt,omitempty"`
RefreshToken string `json:"refreshToken,omitempty"`
ClientID string `json:"clientId,omitempty"`
ClientSecret string `json:"clientSecret,omitempty"`
}
type cachedToken struct {
tokenKnownFields
UnknownFields map[string]interface{} `json:"-"`
}
// MarshalJSON provides custom marshalling because the standard library Go marshaller ignores unknown/unspecified fields
// when marshalling from a struct: https://pkg.go.dev/encoding/json#Marshal
// This function adds some extra validation to the known fields and captures unknown fields.
func (t cachedToken) MarshalJSON() ([]byte, error) {
fields := map[string]interface{}{}
setTokenFieldString(fields, "accessToken", t.AccessToken)
setTokenFieldRFC3339(fields, "expiresAt", t.ExpiresAt)
setTokenFieldString(fields, "refreshToken", t.RefreshToken)
setTokenFieldString(fields, "clientId", t.ClientID)
setTokenFieldString(fields, "clientSecret", t.ClientSecret)
for k, v := range t.UnknownFields {
if _, ok := fields[k]; ok {
return nil, fmt.Errorf("unknown token field %v, duplicates known field", k)
}
fields[k] = v
}
return json.Marshal(fields)
}
func setTokenFieldString(fields map[string]interface{}, key, value string) {
if value == "" {
return
}
fields[key] = value
}
func setTokenFieldRFC3339(fields map[string]interface{}, key string, value *rfc3339) {
if value == nil {
return
}
fields[key] = value
}
// UnmarshalJSON provides custom unmarshalling because the standard library Go unmarshaller ignores unknown/unspecified
// fields when unmarshalling from a struct: https://pkg.go.dev/encoding/json#Unmarshal
// This function adds some extra validation to the known fields and captures unknown fields.
func (t *cachedToken) UnmarshalJSON(b []byte) error {
var fields map[string]interface{}
if err := json.Unmarshal(b, &fields); err != nil {
return nil
}
t.UnknownFields = map[string]interface{}{}
for k, v := range fields {
var err error
switch k {
case "accessToken":
err = getTokenFieldString(v, &t.AccessToken)
case "expiresAt":
err = getTokenFieldRFC3339(v, &t.ExpiresAt)
case "refreshToken":
err = getTokenFieldString(v, &t.RefreshToken)
case "clientId":
err = getTokenFieldString(v, &t.ClientID)
case "clientSecret":
err = getTokenFieldString(v, &t.ClientSecret)
default:
t.UnknownFields[k] = v
}
if err != nil {
return fmt.Errorf("field %q, %v", k, err)
}
}
return nil
}
func getTokenFieldString(v interface{}, value *string) error {
var ok bool
*value, ok = v.(string)
if !ok {
return fmt.Errorf("expect value to be string, got %T", v)
}
return nil
}
func getTokenFieldRFC3339(v interface{}, value **rfc3339) error {
var stringValue string
if err := getTokenFieldString(v, &stringValue); err != nil {
return err
}
timeValue, err := parseRFC3339(stringValue)
if err != nil {
return err
}
*value = &timeValue
return nil
}
func loadCachedToken(filename string) (cachedToken, error) {
fileBytes, err := ioutil.ReadFile(filename)
if err != nil {
return cachedToken{}, fmt.Errorf("failed to read cached SSO token file, %v", err)
}
var t cachedToken
if err := json.Unmarshal(fileBytes, &t); err != nil {
return cachedToken{}, fmt.Errorf("failed to parse cached SSO token file, %v", err)
}
if len(t.AccessToken) == 0 || t.ExpiresAt == nil || time.Time(*t.ExpiresAt).IsZero() {
return cachedToken{}, fmt.Errorf(
"cached SSO token must contain accessToken and expiresAt fields")
}
return t, nil
}
func storeCachedToken(filename string, t cachedToken, fileMode os.FileMode) (err error) {
tmpFilename := filename + ".tmp-" + strconv.FormatInt(nowTime().UnixNano(), 10)
if err := writeCacheFile(tmpFilename, fileMode, t); err != nil {
return err
}
if err := os.Rename(tmpFilename, filename); err != nil {
return fmt.Errorf("failed to replace old cached SSO token file, %v", err)
}
return nil
}
func writeCacheFile(filename string, fileMode os.FileMode, t cachedToken) (err error) {
var f *os.File
f, err = os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, fileMode)
if err != nil {
return fmt.Errorf("failed to create cached SSO token file %v", err)
}
defer func() {
closeErr := f.Close()
if err == nil && closeErr != nil {
err = fmt.Errorf("failed to close cached SSO token file, %v", closeErr)
}
}()
encoder := json.NewEncoder(f)
if err = encoder.Encode(t); err != nil {
return fmt.Errorf("failed to serialize cached SSO token, %v", err)
}
return nil
}
type rfc3339 time.Time
// UnmarshalJSON decode rfc3339 from JSON format
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
var value string
var err error
if err = json.Unmarshal(bytes, &value); err != nil {
return err
}
*r, err = parseRFC3339(value)
return err
}
func parseRFC3339(v string) (rfc3339, error) {
parsed, err := time.Parse(time.RFC3339, v)
if err != nil {
return rfc3339{}, fmt.Errorf("expected RFC3339 timestamp: %v", err)
}
return rfc3339(parsed), nil
}
// MarshalJSON encode rfc3339 to JSON format time
func (r *rfc3339) MarshalJSON() ([]byte, error) {
value := time.Time(*r).Format(time.RFC3339)
// Use JSON unmarshal to unescape the quoted value making use of JSON's
// quoting rules.
return json.Marshal(value)
}

View file

@ -0,0 +1,139 @@
package ssocreds
import (
"fmt"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/auth/bearer"
"github.com/aws/aws-sdk-go/service/ssooidc"
)
// CreateTokenAPIClient provides the interface for the SSOTokenProvider's API
// client for calling CreateToken operation to refresh the SSO token.
type CreateTokenAPIClient interface {
CreateToken(input *ssooidc.CreateTokenInput) (*ssooidc.CreateTokenOutput, error)
}
// SSOTokenProviderOptions provides the options for configuring the
// SSOTokenProvider.
type SSOTokenProviderOptions struct {
// Client that can be overridden
Client CreateTokenAPIClient
// The path the file containing the cached SSO token will be read from.
// Initialized the NewSSOTokenProvider's cachedTokenFilepath parameter.
CachedTokenFilepath string
}
// SSOTokenProvider provides a utility for refreshing SSO AccessTokens for
// Bearer Authentication. The SSOTokenProvider can only be used to refresh
// already cached SSO Tokens. This utility cannot perform the initial SSO
// create token.
//
// The initial SSO create token should be preformed with the AWS CLI before the
// Go application using the SSOTokenProvider will need to retrieve the SSO
// token. If the AWS CLI has not created the token cache file, this provider
// will return an error when attempting to retrieve the cached token.
//
// This provider will attempt to refresh the cached SSO token periodically if
// needed when RetrieveBearerToken is called.
//
// A utility such as the AWS CLI must be used to initially create the SSO
// session and cached token file.
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
type SSOTokenProvider struct {
options SSOTokenProviderOptions
}
// NewSSOTokenProvider returns an initialized SSOTokenProvider that will
// periodically refresh the SSO token cached stored in the cachedTokenFilepath.
// The cachedTokenFilepath file's content will be rewritten by the token
// provider when the token is refreshed.
//
// The client must be configured for the AWS region the SSO token was created for.
func NewSSOTokenProvider(client CreateTokenAPIClient, cachedTokenFilepath string, optFns ...func(o *SSOTokenProviderOptions)) *SSOTokenProvider {
options := SSOTokenProviderOptions{
Client: client,
CachedTokenFilepath: cachedTokenFilepath,
}
for _, fn := range optFns {
fn(&options)
}
provider := &SSOTokenProvider{
options: options,
}
return provider
}
// RetrieveBearerToken returns the SSO token stored in the cachedTokenFilepath
// the SSOTokenProvider was created with. If the token has expired
// RetrieveBearerToken will attempt to refresh it. If the token cannot be
// refreshed or is not present an error will be returned.
//
// A utility such as the AWS CLI must be used to initially create the SSO
// session and cached token file. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
func (p *SSOTokenProvider) RetrieveBearerToken(ctx aws.Context) (bearer.Token, error) {
cachedToken, err := loadCachedToken(p.options.CachedTokenFilepath)
if err != nil {
return bearer.Token{}, err
}
if cachedToken.ExpiresAt != nil && nowTime().After(time.Time(*cachedToken.ExpiresAt)) {
cachedToken, err = p.refreshToken(cachedToken)
if err != nil {
return bearer.Token{}, fmt.Errorf("refresh cached SSO token failed, %v", err)
}
}
expiresAt := toTime((*time.Time)(cachedToken.ExpiresAt))
return bearer.Token{
Value: cachedToken.AccessToken,
CanExpire: !expiresAt.IsZero(),
Expires: expiresAt,
}, nil
}
func (p *SSOTokenProvider) refreshToken(token cachedToken) (cachedToken, error) {
if token.ClientSecret == "" || token.ClientID == "" || token.RefreshToken == "" {
return cachedToken{}, fmt.Errorf("cached SSO token is expired, or not present, and cannot be refreshed")
}
createResult, err := p.options.Client.CreateToken(&ssooidc.CreateTokenInput{
ClientId: &token.ClientID,
ClientSecret: &token.ClientSecret,
RefreshToken: &token.RefreshToken,
GrantType: aws.String("refresh_token"),
})
if err != nil {
return cachedToken{}, fmt.Errorf("unable to refresh SSO token, %v", err)
}
expiresAt := nowTime().Add(time.Duration(*createResult.ExpiresIn) * time.Second)
token.AccessToken = *createResult.AccessToken
token.ExpiresAt = (*rfc3339)(&expiresAt)
token.RefreshToken = *createResult.RefreshToken
fileInfo, err := os.Stat(p.options.CachedTokenFilepath)
if err != nil {
return cachedToken{}, fmt.Errorf("failed to stat cached SSO token file %v", err)
}
if err = storeCachedToken(p.options.CachedTokenFilepath, token, fileInfo.Mode()); err != nil {
return cachedToken{}, fmt.Errorf("unable to cache refreshed SSO token, %v", err)
}
return token, nil
}
func toTime(p *time.Time) (v time.Time) {
if p == nil {
return v
}
return *p
}

View file

@ -9,7 +9,7 @@ to refresh the credentials will be synchronized. But, the SDK is unable to
ensure synchronous usage of the AssumeRoleProvider if the value is shared
between multiple Credentials, Sessions or service clients.
Assume Role
# Assume Role
To assume an IAM role using STS with the SDK you can create a new Credentials
with the SDKs's stscreds package.
@ -27,7 +27,7 @@ with the SDKs's stscreds package.
// from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds})
Assume Role with static MFA Token
# Assume Role with static MFA Token
To assume an IAM role with a MFA token you can either specify a MFA token code
directly or provide a function to prompt the user each time the credentials
@ -49,7 +49,7 @@ credentials.
// from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds})
Assume Role with MFA Token Provider
# Assume Role with MFA Token Provider
To assume an IAM role with MFA for longer running tasks where the credentials
may need to be refreshed setting the TokenProvider field of AssumeRoleProvider
@ -74,7 +74,6 @@ single Credentials with an AssumeRoleProvider can be shared safely.
// Create service client value configured for credentials
// from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds})
*/
package stscreds
@ -199,6 +198,10 @@ type AssumeRoleProvider struct {
// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
SerialNumber *string
// The SourceIdentity which is used to identity a persistent identity through the whole session.
// For more details see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
SourceIdentity *string
// The value provided by the MFA device, if the trust policy of the role being
// assumed requires MFA (that is, if the policy includes a condition that tests
// for MFA). If the role being assumed requires MFA and if the TokenCode value
@ -320,6 +323,7 @@ func (p *AssumeRoleProvider) RetrieveWithContext(ctx credentials.Context) (crede
Tags: p.Tags,
PolicyArns: p.PolicyArns,
TransitiveTagKeys: p.TransitiveTagKeys,
SourceIdentity: p.SourceIdentity,
}
if p.Policy != nil {
input.Policy = p.Policy

View file

@ -57,13 +57,13 @@ type EC2Metadata struct {
// New creates a new instance of the EC2Metadata client with a session.
// This client is safe to use across multiple goroutines.
//
//
// Example:
// // Create a EC2Metadata client from just a session.
// svc := ec2metadata.New(mySession)
//
// // Create a EC2Metadata client with additional configuration
// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
// // Create a EC2Metadata client from just a session.
// svc := ec2metadata.New(mySession)
//
// // Create a EC2Metadata client with additional configuration
// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
c := p.ClientConfig(ServiceName, cfgs...)
return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)

View file

@ -1,6 +1,7 @@
package ec2metadata
import (
"fmt"
"net/http"
"sync/atomic"
"time"
@ -33,11 +34,15 @@ func newTokenProvider(c *EC2Metadata, duration time.Duration) *tokenProvider {
return &tokenProvider{client: c, configuredTTL: duration}
}
// check if fallback is enabled
func (t *tokenProvider) fallbackEnabled() bool {
return t.client.Config.EC2MetadataEnableFallback == nil || *t.client.Config.EC2MetadataEnableFallback
}
// fetchTokenHandler fetches token for EC2Metadata service client by default.
func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
// short-circuits to insecure data flow if tokenProvider is disabled.
if v := atomic.LoadUint32(&t.disabled); v == 1 {
if v := atomic.LoadUint32(&t.disabled); v == 1 && t.fallbackEnabled() {
return
}
@ -49,23 +54,21 @@ func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
output, err := t.client.getToken(r.Context(), t.configuredTTL)
if err != nil {
// only attempt fallback to insecure data flow if IMDSv1 is enabled
if !t.fallbackEnabled() {
r.Error = awserr.New("EC2MetadataError", "failed to get IMDSv2 token and fallback to IMDSv1 is disabled", err)
return
}
// change the disabled flag on token provider to true,
// when error is request timeout error.
// change the disabled flag on token provider to true and fallback
if requestFailureError, ok := err.(awserr.RequestFailure); ok {
switch requestFailureError.StatusCode() {
case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
atomic.StoreUint32(&t.disabled, 1)
t.client.Config.Logger.Log(fmt.Sprintf("WARN: failed to get session token, falling back to IMDSv1: %v", requestFailureError))
case http.StatusBadRequest:
r.Error = requestFailureError
}
// Check if request timed out while waiting for response
if e, ok := requestFailureError.OrigErr().(awserr.Error); ok {
if e.Code() == request.ErrCodeRequestError {
atomic.StoreUint32(&t.disabled, 1)
}
}
}
return
}

View file

@ -31,12 +31,12 @@ func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) {
// allow you to get a list of the partitions in the order the endpoints
// will be resolved in.
//
// resolver, err := endpoints.DecodeModel(reader)
// resolver, err := endpoints.DecodeModel(reader)
//
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
// for _, p := range partitions {
// // ... inspect partitions
// }
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
// for _, p := range partitions {
// // ... inspect partitions
// }
func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) {
var opts DecodeModelOptions
opts.Set(optFns...)

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
// AWS GovCloud (US) (aws-us-gov).
// .
//
// Enumerating Regions and Endpoint Metadata
// # Enumerating Regions and Endpoint Metadata
//
// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface
// will allow you to get access to the list of underlying Partitions with the
@ -17,22 +17,22 @@
// resolving to a single partition, or enumerate regions, services, and endpoints
// in the partition.
//
// resolver := endpoints.DefaultResolver()
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
// resolver := endpoints.DefaultResolver()
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
//
// for _, p := range partitions {
// fmt.Println("Regions for", p.ID())
// for id, _ := range p.Regions() {
// fmt.Println("*", id)
// }
// for _, p := range partitions {
// fmt.Println("Regions for", p.ID())
// for id, _ := range p.Regions() {
// fmt.Println("*", id)
// }
//
// fmt.Println("Services for", p.ID())
// for id, _ := range p.Services() {
// fmt.Println("*", id)
// }
// }
// fmt.Println("Services for", p.ID())
// for id, _ := range p.Services() {
// fmt.Println("*", id)
// }
// }
//
// Using Custom Endpoints
// # Using Custom Endpoints
//
// The endpoints package also gives you the ability to use your own logic how
// endpoints are resolved. This is a great way to define a custom endpoint
@ -47,20 +47,19 @@
// of Resolver.EndpointFor, converting it to a type that satisfies the
// Resolver interface.
//
// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
// if service == endpoints.S3ServiceID {
// return endpoints.ResolvedEndpoint{
// URL: "s3.custom.endpoint.com",
// SigningRegion: "custom-signing-region",
// }, nil
// }
//
// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
// if service == endpoints.S3ServiceID {
// return endpoints.ResolvedEndpoint{
// URL: "s3.custom.endpoint.com",
// SigningRegion: "custom-signing-region",
// }, nil
// }
// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
// }
//
// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
// }
//
// sess := session.Must(session.NewSession(&aws.Config{
// Region: aws.String("us-west-2"),
// EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
// }))
// sess := session.Must(session.NewSession(&aws.Config{
// Region: aws.String("us-west-2"),
// EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
// }))
package endpoints

View file

@ -353,10 +353,12 @@ type EnumPartitions interface {
// as the second parameter.
//
// This example shows how to get the regions for DynamoDB in the AWS partition.
// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
//
// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
//
// This is equivalent to using the partition directly.
// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
//
// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
for _, p := range ps {
if p.ID() != partitionID {
@ -423,8 +425,8 @@ func (p Partition) ID() string { return p.id }
// of new regions and services expansions.
//
// Errors that can be returned.
// * UnknownServiceError
// * UnknownEndpointError
// - UnknownServiceError
// - UnknownEndpointError
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
return p.p.EndpointFor(service, region, opts...)
}

View file

@ -330,6 +330,9 @@ func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
// WithSetRequestHeaders updates the operation request's HTTP header to contain
// the header key value pairs provided. If the header key already exists in the
// request's HTTP header set, the existing value(s) will be replaced.
//
// Header keys added will be added as canonical format with title casing
// applied via http.Header.Set method.
func WithSetRequestHeaders(h map[string]string) Option {
return withRequestHeader(h).SetRequestHeaders
}
@ -338,6 +341,6 @@ type withRequestHeader map[string]string
func (h withRequestHeader) SetRequestHeaders(r *Request) {
for k, v := range h {
r.HTTPRequest.Header[k] = []string{v}
r.HTTPRequest.Header.Set(k, v)
}
}

View file

@ -14,6 +14,7 @@ import (
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
"github.com/aws/aws-sdk-go/service/ssooidc"
"github.com/aws/aws-sdk-go/service/sts"
)
@ -23,6 +24,10 @@ type CredentialsProviderOptions struct {
// WebIdentityRoleProviderOptions configures a WebIdentityRoleProvider,
// such as setting its ExpiryWindow.
WebIdentityRoleProviderOptions func(*stscreds.WebIdentityRoleProvider)
// ProcessProviderOptions configures a ProcessProvider,
// such as setting its Timeout.
ProcessProviderOptions func(*processcreds.ProcessProvider)
}
func resolveCredentials(cfg *aws.Config,
@ -33,7 +38,7 @@ func resolveCredentials(cfg *aws.Config,
switch {
case len(sessOpts.Profile) != 0:
// User explicitly provided an Profile in the session's configuration
// User explicitly provided a Profile in the session's configuration
// so load that profile from shared config first.
// Github(aws/aws-sdk-go#2727)
return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts)
@ -134,7 +139,11 @@ func resolveCredsFromProfile(cfg *aws.Config,
case len(sharedCfg.CredentialProcess) != 0:
// Get credentials from CredentialProcess
creds = processcreds.NewCredentials(sharedCfg.CredentialProcess)
var optFns []func(*processcreds.ProcessProvider)
if sessOpts.CredentialsProviderOptions != nil && sessOpts.CredentialsProviderOptions.ProcessProviderOptions != nil {
optFns = append(optFns, sessOpts.CredentialsProviderOptions.ProcessProviderOptions)
}
creds = processcreds.NewCredentials(sharedCfg.CredentialProcess, optFns...)
default:
// Fallback to default credentials provider, include mock errors for
@ -173,8 +182,28 @@ func resolveSSOCredentials(cfg *aws.Config, sharedCfg sharedConfig, handlers req
return nil, err
}
var optFns []func(provider *ssocreds.Provider)
cfgCopy := cfg.Copy()
cfgCopy.Region = &sharedCfg.SSORegion
if sharedCfg.SSOSession != nil {
cfgCopy.Region = &sharedCfg.SSOSession.SSORegion
cachedPath, err := ssocreds.StandardCachedTokenFilepath(sharedCfg.SSOSession.Name)
if err != nil {
return nil, err
}
// create oidcClient with AnonymousCredentials to avoid recursively resolving credentials
mySession := Must(NewSession(&aws.Config{
Credentials: credentials.AnonymousCredentials,
}))
oidcClient := ssooidc.New(mySession, cfgCopy)
tokenProvider := ssocreds.NewSSOTokenProvider(oidcClient, cachedPath)
optFns = append(optFns, func(p *ssocreds.Provider) {
p.TokenProvider = tokenProvider
p.CachedTokenFilepath = cachedPath
})
} else {
cfgCopy.Region = &sharedCfg.SSORegion
}
return ssocreds.NewCredentials(
&Session{
@ -184,6 +213,7 @@ func resolveSSOCredentials(cfg *aws.Config, sharedCfg sharedConfig, handlers req
sharedCfg.SSOAccountID,
sharedCfg.SSORoleName,
sharedCfg.SSOStartURL,
optFns...,
), nil
}

View file

@ -37,7 +37,7 @@ const (
// ErrSharedConfigSourceCollision will be returned if a section contains both
// source_profile and credential_source
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only one credential type may be specified per profile: source profile, credential source, credential process, web identity token, or sso", nil)
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only one credential type may be specified per profile: source profile, credential source, credential process, web identity token", nil)
// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
// variables are empty and Environment was set as the credential source
@ -174,7 +174,6 @@ const (
// Options provides the means to control how a Session is created and what
// configuration values will be loaded.
//
type Options struct {
// Provides config values for the SDK to use when creating service clients
// and making API requests to services. Any value set in with this field
@ -224,7 +223,7 @@ type Options struct {
// from stdin for the MFA token code.
//
// This field is only used if the shared configuration is enabled, and
// the config enables assume role wit MFA via the mfa_serial field.
// the config enables assume role with MFA via the mfa_serial field.
AssumeRoleTokenProvider func() (string, error)
// When the SDK's shared config is configured to assume a role this option
@ -322,24 +321,24 @@ type Options struct {
// credentials file. Enabling the Shared Config will also allow the Session
// to be built with retrieving credentials with AssumeRole set in the config.
//
// // Equivalent to session.New
// sess := session.Must(session.NewSessionWithOptions(session.Options{}))
// // Equivalent to session.New
// sess := session.Must(session.NewSessionWithOptions(session.Options{}))
//
// // Specify profile to load for the session's config
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// Profile: "profile_name",
// }))
// // Specify profile to load for the session's config
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// Profile: "profile_name",
// }))
//
// // Specify profile for config and region for requests
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// Config: aws.Config{Region: aws.String("us-east-1")},
// Profile: "profile_name",
// }))
// // Specify profile for config and region for requests
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// Config: aws.Config{Region: aws.String("us-east-1")},
// Profile: "profile_name",
// }))
//
// // Force enable Shared Config support
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// SharedConfigState: session.SharedConfigEnable,
// }))
// // Force enable Shared Config support
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// SharedConfigState: session.SharedConfigEnable,
// }))
func NewSessionWithOptions(opts Options) (*Session, error) {
var envCfg envConfig
var err error
@ -375,7 +374,7 @@ func NewSessionWithOptions(opts Options) (*Session, error) {
// This helper is intended to be used in variable initialization to load the
// Session and configuration at startup. Such as:
//
// var sess = session.Must(session.NewSession())
// var sess = session.Must(session.NewSession())
func Must(sess *Session, err error) *Session {
if err != nil {
panic(err)
@ -780,16 +779,6 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, ec2IMDSEndpoint, endpointMode)
}
// Configure credentials if not already set by the user when creating the
// Session.
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts)
if err != nil {
return err
}
cfg.Credentials = creds
}
cfg.S3UseARNRegion = userCfg.S3UseARNRegion
if cfg.S3UseARNRegion == nil {
cfg.S3UseARNRegion = &envCfg.S3UseARNRegion
@ -812,6 +801,17 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
}
}
// Configure credentials if not already set by the user when creating the Session.
// Credentials are resolved last such that all _resolved_ config values are propagated to credential providers.
// ticket: P83606045
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts)
if err != nil {
return err
}
cfg.Credentials = creds
}
return nil
}
@ -845,8 +845,8 @@ func initHandlers(s *Session) {
// and handlers. If any additional configs are provided they will be merged
// on top of the Session's copied config.
//
// // Create a copy of the current Session, configured for the us-west-2 region.
// sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
// // Create a copy of the current Session, configured for the us-west-2 region.
// sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
newSession := &Session{
Config: s.Config.Copy(cfgs...),

View file

@ -26,6 +26,13 @@ const (
roleSessionNameKey = `role_session_name` // optional
roleDurationSecondsKey = "duration_seconds" // optional
// Prefix to be used for SSO sections. These are supposed to only exist in
// the shared config file, not the credentials file.
ssoSectionPrefix = `sso-session `
// AWS Single Sign-On (AWS SSO) group
ssoSessionNameKey = "sso_session"
// AWS Single Sign-On (AWS SSO) group
ssoAccountIDKey = "sso_account_id"
ssoRegionKey = "sso_region"
@ -99,6 +106,10 @@ type sharedConfig struct {
CredentialProcess string
WebIdentityTokenFile string
// SSO session options
SSOSessionName string
SSOSession *ssoSession
SSOAccountID string
SSORegion string
SSORoleName string
@ -186,6 +197,20 @@ type sharedConfigFile struct {
IniData ini.Sections
}
// SSOSession provides the shared configuration parameters of the sso-session
// section.
type ssoSession struct {
Name string
SSORegion string
SSOStartURL string
}
func (s *ssoSession) setFromIniSection(section ini.Section) {
updateString(&s.Name, section, ssoSessionNameKey)
updateString(&s.SSORegion, section, ssoRegionKey)
updateString(&s.SSOStartURL, section, ssoStartURL)
}
// loadSharedConfig retrieves the configuration from the list of files using
// the profile provided. The order the files are listed will determine
// precedence. Values in subsequent files will overwrite values defined in
@ -266,13 +291,13 @@ func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile s
// profile only have credential provider options.
cfg.clearAssumeRoleOptions()
} else {
// First time a profile has been seen, It must either be a assume role
// credentials, or SSO. Assert if the credential type requires a role ARN,
// the ARN is also set, or validate that the SSO configuration is complete.
// First time a profile has been seen. Assert if the credential type
// requires a role ARN, the ARN is also set
if err := cfg.validateCredentialsConfig(profile); err != nil {
return err
}
}
profiles[profile] = struct{}{}
if err := cfg.validateCredentialType(); err != nil {
@ -308,6 +333,30 @@ func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile s
cfg.SourceProfile = srcCfg
}
// If the profile contains an SSO session parameter, the session MUST exist
// as a section in the config file. Load the SSO session using the name
// provided. If the session section is not found or incomplete an error
// will be returned.
if cfg.hasSSOTokenProviderConfiguration() {
skippedFiles = 0
for _, f := range files {
section, ok := f.IniData.GetSection(fmt.Sprintf(ssoSectionPrefix + strings.TrimSpace(cfg.SSOSessionName)))
if ok {
var ssoSession ssoSession
ssoSession.setFromIniSection(section)
ssoSession.Name = cfg.SSOSessionName
cfg.SSOSession = &ssoSession
break
}
skippedFiles++
}
if skippedFiles == len(files) {
// If all files were skipped because the sso session section is not found, return
// the sso section not found error.
return fmt.Errorf("failed to find SSO session section, %v", cfg.SSOSessionName)
}
}
return nil
}
@ -363,6 +412,10 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
cfg.S3UsEast1RegionalEndpoint = sre
}
// AWS Single Sign-On (AWS SSO)
// SSO session options
updateString(&cfg.SSOSessionName, section, ssoSessionNameKey)
// AWS Single Sign-On (AWS SSO)
updateString(&cfg.SSOAccountID, section, ssoAccountIDKey)
updateString(&cfg.SSORegion, section, ssoRegionKey)
@ -461,32 +514,20 @@ func (cfg *sharedConfig) validateCredentialType() error {
}
func (cfg *sharedConfig) validateSSOConfiguration() error {
if !cfg.hasSSOConfiguration() {
if cfg.hasSSOTokenProviderConfiguration() {
err := cfg.validateSSOTokenProviderConfiguration()
if err != nil {
return err
}
return nil
}
var missing []string
if len(cfg.SSOAccountID) == 0 {
missing = append(missing, ssoAccountIDKey)
if cfg.hasLegacySSOConfiguration() {
err := cfg.validateLegacySSOConfiguration()
if err != nil {
return err
}
}
if len(cfg.SSORegion) == 0 {
missing = append(missing, ssoRegionKey)
}
if len(cfg.SSORoleName) == 0 {
missing = append(missing, ssoRoleNameKey)
}
if len(cfg.SSOStartURL) == 0 {
missing = append(missing, ssoStartURL)
}
if len(missing) > 0 {
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
cfg.Profile, strings.Join(missing, ", "))
}
return nil
}
@ -525,15 +566,76 @@ func (cfg *sharedConfig) clearAssumeRoleOptions() {
}
func (cfg *sharedConfig) hasSSOConfiguration() bool {
switch {
case len(cfg.SSOAccountID) != 0:
case len(cfg.SSORegion) != 0:
case len(cfg.SSORoleName) != 0:
case len(cfg.SSOStartURL) != 0:
default:
return false
return cfg.hasSSOTokenProviderConfiguration() || cfg.hasLegacySSOConfiguration()
}
func (c *sharedConfig) hasSSOTokenProviderConfiguration() bool {
return len(c.SSOSessionName) > 0
}
func (c *sharedConfig) hasLegacySSOConfiguration() bool {
return len(c.SSORegion) > 0 || len(c.SSOAccountID) > 0 || len(c.SSOStartURL) > 0 || len(c.SSORoleName) > 0
}
func (c *sharedConfig) validateSSOTokenProviderConfiguration() error {
var missing []string
if len(c.SSOSessionName) == 0 {
missing = append(missing, ssoSessionNameKey)
}
return true
if c.SSOSession == nil {
missing = append(missing, ssoSectionPrefix)
} else {
if len(c.SSOSession.SSORegion) == 0 {
missing = append(missing, ssoRegionKey)
}
if len(c.SSOSession.SSOStartURL) == 0 {
missing = append(missing, ssoStartURL)
}
}
if len(missing) > 0 {
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
c.Profile, strings.Join(missing, ", "))
}
if len(c.SSORegion) > 0 && c.SSORegion != c.SSOSession.SSORegion {
return fmt.Errorf("%s in profile %q must match %s in %s", ssoRegionKey, c.Profile, ssoRegionKey, ssoSectionPrefix)
}
if len(c.SSOStartURL) > 0 && c.SSOStartURL != c.SSOSession.SSOStartURL {
return fmt.Errorf("%s in profile %q must match %s in %s", ssoStartURL, c.Profile, ssoStartURL, ssoSectionPrefix)
}
return nil
}
func (c *sharedConfig) validateLegacySSOConfiguration() error {
var missing []string
if len(c.SSORegion) == 0 {
missing = append(missing, ssoRegionKey)
}
if len(c.SSOStartURL) == 0 {
missing = append(missing, ssoStartURL)
}
if len(c.SSOAccountID) == 0 {
missing = append(missing, ssoAccountIDKey)
}
if len(c.SSORoleName) == 0 {
missing = append(missing, ssoRoleNameKey)
}
if len(missing) > 0 {
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
c.Profile, strings.Join(missing, ", "))
}
return nil
}
func oneOrNone(bs ...bool) bool {

View file

@ -3,21 +3,21 @@
// Provides request signing for request that need to be signed with
// AWS V4 Signatures.
//
// Standalone Signer
// # Standalone Signer
//
// Generally using the signer outside of the SDK should not require any additional
// logic when using Go v1.5 or higher. The signer does this by taking advantage
// of the URL.EscapedPath method. If your request URI requires additional escaping
// you many need to use the URL.Opaque to define what the raw URI should be sent
// you may need to use the URL.Opaque to define what the raw URI should be sent
// to the service as.
//
// The signer will first check the URL.Opaque field, and use its value if set.
// The signer does require the URL.Opaque field to be set in the form of:
//
// "//<hostname>/<path>"
// "//<hostname>/<path>"
//
// // e.g.
// "//example.com/some/path"
// // e.g.
// "//example.com/some/path"
//
// The leading "//" and hostname are required or the URL.Opaque escaping will
// not work correctly.
@ -695,7 +695,8 @@ func (ctx *signingCtx) buildBodyDigest() error {
includeSHA256Header := ctx.unsignedPayload ||
ctx.ServiceName == "s3" ||
ctx.ServiceName == "s3-object-lambda" ||
ctx.ServiceName == "glacier"
ctx.ServiceName == "glacier" ||
ctx.ServiceName == "s3-outposts"
s3Presign := ctx.isPresign &&
(ctx.ServiceName == "s3" ||

View file

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.43.16"
const SDKVersion = "1.44.325"

View file

@ -1,9 +1,8 @@
package shareddefaults
import (
"os"
"os/user"
"path/filepath"
"runtime"
)
// SharedCredentialsFilename returns the SDK's default file path
@ -31,10 +30,17 @@ func SharedConfigFilename() string {
// UserHomeDir returns the home directory for the user the process is
// running under.
func UserHomeDir() string {
if runtime.GOOS == "windows" { // Windows
return os.Getenv("USERPROFILE")
var home string
home = userHomeDir()
if len(home) > 0 {
return home
}
// *nix
return os.Getenv("HOME")
currUser, _ := user.Current()
if currUser != nil {
home = currUser.HomeDir
}
return home
}

View file

@ -0,0 +1,18 @@
//go:build !go1.12
// +build !go1.12
package shareddefaults
import (
"os"
"runtime"
)
func userHomeDir() string {
if runtime.GOOS == "windows" { // Windows
return os.Getenv("USERPROFILE")
}
// *nix
return os.Getenv("HOME")
}

View file

@ -0,0 +1,13 @@
//go:build go1.12
// +build go1.12
package shareddefaults
import (
"os"
)
func userHomeDir() string {
home, _ := os.UserHomeDir()
return home
}

View file

@ -5,6 +5,6 @@ package eventstreamapi
import "github.com/aws/aws-sdk-go/aws/request"
// This is a no-op for Go 1.18 and above.
// ApplyHTTPTransportFixes is a no-op for Go 1.18 and above.
func ApplyHTTPTransportFixes(r *request.Request) {
}

View file

@ -4,7 +4,6 @@ package jsonutil
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"math"
"reflect"
@ -16,6 +15,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const (
floatNaN = "NaN"
floatInf = "Infinity"
floatNegInf = "-Infinity"
)
var timeType = reflect.ValueOf(time.Time{}).Type()
var byteSliceType = reflect.ValueOf([]byte{}).Type()
@ -211,10 +216,16 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro
buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10))
case reflect.Float64:
f := value.Float()
if math.IsInf(f, 0) || math.IsNaN(f) {
return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)}
switch {
case math.IsNaN(f):
writeString(floatNaN, buf)
case math.IsInf(f, 1):
writeString(floatInf, buf)
case math.IsInf(f, -1):
writeString(floatNegInf, buf)
default:
buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64))
}
buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64))
default:
switch converted := value.Interface().(type) {
case time.Time:

View file

@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"math"
"math/big"
"reflect"
"strings"
@ -258,6 +259,18 @@ func (u unmarshaler) unmarshalScalar(value reflect.Value, data interface{}, tag
return err
}
value.Set(reflect.ValueOf(v))
case *float64:
// These are regular strings when parsed by encoding/json's unmarshaler.
switch {
case strings.EqualFold(d, floatNaN):
value.Set(reflect.ValueOf(aws.Float64(math.NaN())))
case strings.EqualFold(d, floatInf):
value.Set(reflect.ValueOf(aws.Float64(math.Inf(1))))
case strings.EqualFold(d, floatNegInf):
value.Set(reflect.ValueOf(aws.Float64(math.Inf(-1))))
default:
return fmt.Errorf("unknown JSON number value: %s", d)
}
default:
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
}

View file

@ -13,17 +13,46 @@ import (
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
)
const (
awsQueryError = "x-amzn-query-error"
// A valid header example - "x-amzn-query-error": "<QueryErrorCode>;<ErrorType>"
awsQueryErrorPartsCount = 2
)
// UnmarshalTypedError provides unmarshaling errors API response errors
// for both typed and untyped errors.
type UnmarshalTypedError struct {
exceptions map[string]func(protocol.ResponseMetadata) error
exceptions map[string]func(protocol.ResponseMetadata) error
queryExceptions map[string]func(protocol.ResponseMetadata, string) error
}
// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
// set of exception names to the error unmarshalers
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
return &UnmarshalTypedError{
exceptions: exceptions,
exceptions: exceptions,
queryExceptions: map[string]func(protocol.ResponseMetadata, string) error{},
}
}
// NewUnmarshalTypedErrorWithOptions works similar to NewUnmarshalTypedError applying options to the UnmarshalTypedError
// before returning it
func NewUnmarshalTypedErrorWithOptions(exceptions map[string]func(protocol.ResponseMetadata) error, optFns ...func(*UnmarshalTypedError)) *UnmarshalTypedError {
unmarshaledError := NewUnmarshalTypedError(exceptions)
for _, fn := range optFns {
fn(unmarshaledError)
}
return unmarshaledError
}
// WithQueryCompatibility is a helper function to construct a functional option for use with NewUnmarshalTypedErrorWithOptions.
// The queryExceptions given act as an override for unmarshalling errors when query compatible error codes are found.
// See also [awsQueryCompatible trait]
//
// [awsQueryCompatible trait]: https://smithy.io/2.0/aws/protocols/aws-query-protocol.html#aws-protocols-awsquerycompatible-trait
func WithQueryCompatibility(queryExceptions map[string]func(protocol.ResponseMetadata, string) error) func(*UnmarshalTypedError) {
return func(typedError *UnmarshalTypedError) {
typedError.queryExceptions = queryExceptions
}
}
@ -50,18 +79,32 @@ func (u *UnmarshalTypedError) UnmarshalError(
code := codeParts[len(codeParts)-1]
msg := jsonErr.Message
queryCodeParts := queryCodeParts(resp, u)
if fn, ok := u.exceptions[code]; ok {
// If exception code is know, use associated constructor to get a value
// If query-compatible exceptions are found and query-error-header is found,
// then use associated constructor to get exception with query error code.
//
// If exception code is known, use associated constructor to get a value
// for the exception that the JSON body can be unmarshaled into.
v := fn(respMeta)
var v error
queryErrFn, queryExceptionsFound := u.queryExceptions[code]
if len(queryCodeParts) == awsQueryErrorPartsCount && queryExceptionsFound {
v = queryErrFn(respMeta, queryCodeParts[0])
} else {
v = fn(respMeta)
}
err := jsonutil.UnmarshalJSONCaseInsensitive(v, body)
if err != nil {
return nil, err
}
return v, nil
}
if len(queryCodeParts) == awsQueryErrorPartsCount && len(u.queryExceptions) > 0 {
code = queryCodeParts[0]
}
// fallback to unmodeled generic exceptions
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
@ -70,6 +113,16 @@ func (u *UnmarshalTypedError) UnmarshalError(
), nil
}
// A valid header example - "x-amzn-query-error": "<QueryErrorCode>;<ErrorType>"
func queryCodeParts(resp *http.Response, u *UnmarshalTypedError) []string {
queryCodeHeader := resp.Header.Get(awsQueryError)
var queryCodeParts []string
if queryCodeHeader != "" && len(u.queryExceptions) > 0 {
queryCodeParts = strings.Split(queryCodeHeader, ";")
}
return queryCodeParts
}
// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc
// protocol request errors
var UnmarshalErrorHandler = request.NamedHandler{

View file

@ -3,6 +3,7 @@ package queryutil
import (
"encoding/base64"
"fmt"
"math"
"net/url"
"reflect"
"sort"
@ -13,6 +14,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const (
floatNaN = "NaN"
floatInf = "Infinity"
floatNegInf = "-Infinity"
)
// Parse parses an object i and fills a url.Values object. The isEC2 flag
// indicates if this is the EC2 Query sub-protocol.
func Parse(body url.Values, i interface{}, isEC2 bool) error {
@ -228,9 +235,32 @@ func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, ta
case int:
v.Set(name, strconv.Itoa(value))
case float64:
v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
var str string
switch {
case math.IsNaN(value):
str = floatNaN
case math.IsInf(value, 1):
str = floatInf
case math.IsInf(value, -1):
str = floatNegInf
default:
str = strconv.FormatFloat(value, 'f', -1, 64)
}
v.Set(name, str)
case float32:
v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
asFloat64 := float64(value)
var str string
switch {
case math.IsNaN(asFloat64):
str = floatNaN
case math.IsInf(asFloat64, 1):
str = floatInf
case math.IsInf(asFloat64, -1):
str = floatNegInf
default:
str = strconv.FormatFloat(asFloat64, 'f', -1, 32)
}
v.Set(name, str)
case time.Time:
const ISO8601UTC = "2006-01-02T15:04:05Z"
format := tag.Get("timestampFormat")

View file

@ -3,6 +3,7 @@ package query
import (
"encoding/xml"
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
@ -62,7 +63,7 @@ func UnmarshalError(r *request.Request) {
}
r.Error = awserr.NewRequestFailure(
awserr.New(respErr.Code, respErr.Message, nil),
awserr.New(strings.TrimSpace(respErr.Code), strings.TrimSpace(respErr.Message), nil),
r.HTTPResponse.StatusCode,
reqID,
)

View file

@ -6,6 +6,7 @@ import (
"encoding/base64"
"fmt"
"io"
"math"
"net/http"
"net/url"
"path"
@ -20,6 +21,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const (
floatNaN = "NaN"
floatInf = "Infinity"
floatNegInf = "-Infinity"
)
// Whether the byte value can be sent without escaping in AWS URLs
var noEscape [256]bool
@ -276,6 +283,29 @@ func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error)
value = base64.StdEncoding.EncodeToString([]byte(value))
}
str = value
case []*string:
if tag.Get("location") != "header" || tag.Get("enum") == "" {
return "", fmt.Errorf("%T is only supported with location header and enum shapes", value)
}
if len(value) == 0 {
return "", errValueNotSet
}
buff := &bytes.Buffer{}
for i, sv := range value {
if sv == nil || len(*sv) == 0 {
continue
}
if i != 0 {
buff.WriteRune(',')
}
item := *sv
if strings.Index(item, `,`) != -1 || strings.Index(item, `"`) != -1 {
item = strconv.Quote(item)
}
buff.WriteString(item)
}
str = string(buff.Bytes())
case []byte:
str = base64.StdEncoding.EncodeToString(value)
case bool:
@ -283,7 +313,16 @@ func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error)
case int64:
str = strconv.FormatInt(value, 10)
case float64:
str = strconv.FormatFloat(value, 'f', -1, 64)
switch {
case math.IsNaN(value):
str = floatNaN
case math.IsInf(value, 1):
str = floatInf
case math.IsInf(value, -1):
str = floatNegInf
default:
str = strconv.FormatFloat(value, 'f', -1, 64)
}
case time.Time:
format := tag.Get("timestampFormat")
if len(format) == 0 {

View file

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"io/ioutil"
"math"
"net/http"
"reflect"
"strconv"
@ -231,9 +232,20 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro
}
v.Set(reflect.ValueOf(&i))
case *float64:
f, err := strconv.ParseFloat(header, 64)
if err != nil {
return err
var f float64
switch {
case strings.EqualFold(header, floatNaN):
f = math.NaN()
case strings.EqualFold(header, floatInf):
f = math.Inf(1)
case strings.EqualFold(header, floatNegInf):
f = math.Inf(-1)
default:
var err error
f, err = strconv.ParseFloat(header, 64)
if err != nil {
return err
}
}
v.Set(reflect.ValueOf(&f))
case *time.Time:

View file

@ -2,6 +2,7 @@ package restjson
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
@ -40,52 +41,30 @@ func (u *UnmarshalTypedError) UnmarshalError(
resp *http.Response,
respMeta protocol.ResponseMetadata,
) (error, error) {
code := resp.Header.Get(errorTypeHeader)
msg := resp.Header.Get(errorMessageHeader)
body := resp.Body
if len(code) == 0 {
// If unable to get code from HTTP headers have to parse JSON message
// to determine what kind of exception this will be.
var buf bytes.Buffer
var jsonErr jsonErrorResponse
teeReader := io.TeeReader(resp.Body, &buf)
err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader)
if err != nil {
return nil, err
}
body = ioutil.NopCloser(&buf)
code = jsonErr.Code
msg = jsonErr.Message
code, msg, err := unmarshalErrorInfo(resp)
if err != nil {
return nil, err
}
// If code has colon separators remove them so can compare against modeled
// exception names.
code = strings.SplitN(code, ":", 2)[0]
if fn, ok := u.exceptions[code]; ok {
// If exception code is know, use associated constructor to get a value
// for the exception that the JSON body can be unmarshaled into.
v := fn(respMeta)
if err := jsonutil.UnmarshalJSONCaseInsensitive(v, body); err != nil {
return nil, err
}
if err := rest.UnmarshalResponse(resp, v, true); err != nil {
return nil, err
}
return v, nil
fn, ok := u.exceptions[code]
if !ok {
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
}
// fallback to unmodeled generic exceptions
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
v := fn(respMeta)
if err := jsonutil.UnmarshalJSONCaseInsensitive(v, resp.Body); err != nil {
return nil, err
}
if err := rest.UnmarshalResponse(resp, v, true); err != nil {
return nil, err
}
return v, nil
}
// UnmarshalErrorHandler is a named request handler for unmarshaling restjson
@ -99,36 +78,80 @@ var UnmarshalErrorHandler = request.NamedHandler{
func UnmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse
err := jsonutil.UnmarshalJSONError(&jsonErr, r.HTTPResponse.Body)
code, msg, err := unmarshalErrorInfo(r.HTTPResponse)
if err != nil {
r.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal response error", err),
awserr.New(request.ErrCodeSerialization, "failed to unmarshal response error", err),
r.HTTPResponse.StatusCode,
r.RequestID,
)
return
}
code := r.HTTPResponse.Header.Get(errorTypeHeader)
if code == "" {
code = jsonErr.Code
}
msg := r.HTTPResponse.Header.Get(errorMessageHeader)
if msg == "" {
msg = jsonErr.Message
}
code = strings.SplitN(code, ":", 2)[0]
r.Error = awserr.NewRequestFailure(
awserr.New(code, jsonErr.Message, nil),
awserr.New(code, msg, nil),
r.HTTPResponse.StatusCode,
r.RequestID,
)
}
type jsonErrorResponse struct {
Type string `json:"__type"`
Code string `json:"code"`
Message string `json:"message"`
}
func (j *jsonErrorResponse) SanitizedCode() string {
code := j.Code
if len(j.Type) > 0 {
code = j.Type
}
return sanitizeCode(code)
}
// Remove superfluous components from a restJson error code.
// - If a : character is present, then take only the contents before the
// first : character in the value.
// - If a # character is present, then take only the contents after the first
// # character in the value.
//
// All of the following error values resolve to FooError:
// - FooError
// - FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/
// - aws.protocoltests.restjson#FooError
// - aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/
func sanitizeCode(code string) string {
noColon := strings.SplitN(code, ":", 2)[0]
hashSplit := strings.SplitN(noColon, "#", 2)
return hashSplit[len(hashSplit)-1]
}
// attempt to garner error details from the response, preferring header values
// when present
func unmarshalErrorInfo(resp *http.Response) (code string, msg string, err error) {
code = sanitizeCode(resp.Header.Get(errorTypeHeader))
msg = resp.Header.Get(errorMessageHeader)
if len(code) > 0 && len(msg) > 0 {
return
}
// a modeled error will have to be re-deserialized later, so the body must
// be preserved
var buf bytes.Buffer
tee := io.TeeReader(resp.Body, &buf)
defer func() { resp.Body = ioutil.NopCloser(&buf) }()
var jsonErr jsonErrorResponse
if decodeErr := json.NewDecoder(tee).Decode(&jsonErr); decodeErr != nil && decodeErr != io.EOF {
err = awserr.NewUnmarshalError(decodeErr, "failed to decode response body", buf.Bytes())
return
}
if len(code) == 0 {
code = jsonErr.SanitizedCode()
}
if len(msg) == 0 {
msg = jsonErr.Message
}
return
}

View file

@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/xml"
"fmt"
"math"
"reflect"
"sort"
"strconv"
@ -14,6 +15,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const (
floatNaN = "NaN"
floatInf = "Infinity"
floatNegInf = "-Infinity"
)
// BuildXML will serialize params into an xml.Encoder. Error will be returned
// if the serialization of any of the params or nested values fails.
func BuildXML(params interface{}, e *xml.Encoder) error {
@ -275,6 +282,7 @@ func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect
// Error will be returned if the value type is unsupported.
func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
var str string
switch converted := value.Interface().(type) {
case string:
str = converted
@ -289,9 +297,29 @@ func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag refl
case int:
str = strconv.Itoa(converted)
case float64:
str = strconv.FormatFloat(converted, 'f', -1, 64)
switch {
case math.IsNaN(converted):
str = floatNaN
case math.IsInf(converted, 1):
str = floatInf
case math.IsInf(converted, -1):
str = floatNegInf
default:
str = strconv.FormatFloat(converted, 'f', -1, 64)
}
case float32:
str = strconv.FormatFloat(float64(converted), 'f', -1, 32)
// The SDK doesn't render float32 values in types, only float64. This case would never be hit currently.
asFloat64 := float64(converted)
switch {
case math.IsNaN(asFloat64):
str = floatNaN
case math.IsInf(asFloat64, 1):
str = floatInf
case math.IsInf(asFloat64, -1):
str = floatNegInf
default:
str = strconv.FormatFloat(asFloat64, 'f', -1, 32)
}
case time.Time:
format := tag.Get("timestampFormat")
if len(format) == 0 {

View file

@ -6,6 +6,7 @@ import (
"encoding/xml"
"fmt"
"io"
"math"
"reflect"
"strconv"
"strings"
@ -276,9 +277,20 @@ func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
}
r.Set(reflect.ValueOf(&v))
case *float64:
v, err := strconv.ParseFloat(node.Text, 64)
if err != nil {
return err
var v float64
switch {
case strings.EqualFold(node.Text, floatNaN):
v = math.NaN()
case strings.EqualFold(node.Text, floatInf):
v = math.Inf(1)
case strings.EqualFold(node.Text, floatNegInf):
v = math.Inf(-1)
default:
var err error
v, err = strconv.ParseFloat(node.Text, 64)
if err != nil {
return err
}
}
r.Set(reflect.ValueOf(&v))
case *time.Time:

View file

@ -81,37 +81,38 @@ func NewCookieSigner(keyID string, privKey *rsa.PrivateKey, opts ...func(*Cookie
// server's response.
//
// Example:
// s := sign.NewCookieSigner(keyID, privKey)
//
// // Get Signed cookies for a resource that will expire in 1 hour
// cookies, err := s.Sign("*", time.Now().Add(1 * time.Hour))
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
// s := sign.NewCookieSigner(keyID, privKey)
//
// // Or get Signed cookies for a resource that will expire in 1 hour
// // and set path and domain of cookies
// cookies, err := s.Sign("*", time.Now().Add(1 * time.Hour), func(o *sign.CookieOptions) {
// o.Path = "/"
// o.Domain = ".example.com"
// })
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
// // Get Signed cookies for a resource that will expire in 1 hour
// cookies, err := s.Sign("*", time.Now().Add(1 * time.Hour))
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
//
// // Server Response via http.ResponseWriter
// for _, c := range cookies {
// http.SetCookie(w, c)
// }
// // Or get Signed cookies for a resource that will expire in 1 hour
// // and set path and domain of cookies
// cookies, err := s.Sign("*", time.Now().Add(1 * time.Hour), func(o *sign.CookieOptions) {
// o.Path = "/"
// o.Domain = ".example.com"
// })
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
//
// // Client request via the cookie jar
// if client.CookieJar != nil {
// for _, c := range cookies {
// client.Cookie(w, c)
// }
// }
// // Server Response via http.ResponseWriter
// for _, c := range cookies {
// http.SetCookie(w, c)
// }
//
// // Client request via the cookie jar
// if client.CookieJar != nil {
// for _, c := range cookies {
// client.Cookie(w, c)
// }
// }
func (s CookieSigner) Sign(u string, expires time.Time, opts ...func(*CookieOptions)) ([]*http.Cookie, error) {
scheme, err := cookieURLScheme(u)
if err != nil {
@ -150,55 +151,56 @@ func cookieURLScheme(u string) (string, error) {
// server's response.
//
// Example:
// s := sign.NewCookieSigner(keyID, privKey)
//
// policy := &sign.Policy{
// Statements: []sign.Statement{
// {
// // Read the provided documentation on how to set this
// // correctly, you'll probably want to use wildcards.
// Resource: rawCloudFrontURL,
// Condition: sign.Condition{
// // Optional IP source address range
// IPAddress: &sign.IPAddress{SourceIP: "192.0.2.0/24"},
// // Optional date URL is not valid until
// DateGreaterThan: &sign.AWSEpochTime{time.Now().Add(30 * time.Minute)},
// // Required date the URL will expire after
// DateLessThan: &sign.AWSEpochTime{time.Now().Add(1 * time.Hour)},
// },
// },
// },
// }
// s := sign.NewCookieSigner(keyID, privKey)
//
// // Get Signed cookies for a resource that will expire in 1 hour
// cookies, err := s.SignWithPolicy(policy)
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
// policy := &sign.Policy{
// Statements: []sign.Statement{
// {
// // Read the provided documentation on how to set this
// // correctly, you'll probably want to use wildcards.
// Resource: rawCloudFrontURL,
// Condition: sign.Condition{
// // Optional IP source address range
// IPAddress: &sign.IPAddress{SourceIP: "192.0.2.0/24"},
// // Optional date URL is not valid until
// DateGreaterThan: &sign.AWSEpochTime{time.Now().Add(30 * time.Minute)},
// // Required date the URL will expire after
// DateLessThan: &sign.AWSEpochTime{time.Now().Add(1 * time.Hour)},
// },
// },
// },
// }
//
// // Or get Signed cookies for a resource that will expire in 1 hour
// // and set path and domain of cookies
// cookies, err := s.SignWithPolicy(policy, func(o *sign.CookieOptions) {
// o.Path = "/"
// o.Domain = ".example.com"
// })
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
// // Get Signed cookies for a resource that will expire in 1 hour
// cookies, err := s.SignWithPolicy(policy)
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
//
// // Server Response via http.ResponseWriter
// for _, c := range cookies {
// http.SetCookie(w, c)
// }
// // Or get Signed cookies for a resource that will expire in 1 hour
// // and set path and domain of cookies
// cookies, err := s.SignWithPolicy(policy, func(o *sign.CookieOptions) {
// o.Path = "/"
// o.Domain = ".example.com"
// })
// if err != nil {
// fmt.Println("failed to create signed cookies", err)
// return
// }
//
// // Client request via the cookie jar
// if client.CookieJar != nil {
// for _, c := range cookies {
// client.Cookie(w, c)
// }
// }
// // Server Response via http.ResponseWriter
// for _, c := range cookies {
// http.SetCookie(w, c)
// }
//
// // Client request via the cookie jar
// if client.CookieJar != nil {
// for _, c := range cookies {
// client.Cookie(w, c)
// }
// }
func (s CookieSigner) SignWithPolicy(p *Policy, opts ...func(*CookieOptions)) ([]*http.Cookie, error) {
return createCookies(p, s.keyID, s.privKey, s.Opts.apply(opts...))
}

View file

@ -9,13 +9,12 @@
//
// Example:
//
// // Sign URL to be valid for 1 hour from now.
// signer := sign.NewURLSigner(keyID, privKey)
// signedURL, err := signer.Sign(rawURL, time.Now().Add(1*time.Hour))
// if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// }
//
// // Sign URL to be valid for 1 hour from now.
// signer := sign.NewURLSigner(keyID, privKey)
// signedURL, err := signer.Sign(rawURL, time.Now().Add(1*time.Hour))
// if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// }
package sign
import (
@ -54,13 +53,12 @@ func NewURLSigner(keyID string, privKey *rsa.PrivateKey) *URLSigner {
//
// Example:
//
// // Sign URL to be valid for 1 hour from now.
// signer := sign.NewURLSigner(keyID, privKey)
// signedURL, err := signer.Sign(rawURL, time.Now().Add(1*time.Hour))
// if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// }
//
// // Sign URL to be valid for 1 hour from now.
// signer := sign.NewURLSigner(keyID, privKey)
// signedURL, err := signer.Sign(rawURL, time.Now().Add(1*time.Hour))
// if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// }
func (s URLSigner) Sign(url string, expires time.Time) (string, error) {
scheme, cleanedURL, err := cleanURLScheme(url)
if err != nil {
@ -87,30 +85,29 @@ func (s URLSigner) Sign(url string, expires time.Time) (string, error) {
//
// Example:
//
// // Sign URL to be valid for 30 minutes from now, expires one hour from now, and
// // restricted to the 192.0.2.0/24 IP address range.
// policy := &sign.Policy{
// Statements: []sign.Statement{
// {
// Resource: rawURL,
// Condition: sign.Condition{
// // Optional IP source address range
// IPAddress: &sign.IPAddress{SourceIP: "192.0.2.0/24"},
// // Optional date URL is not valid until
// DateGreaterThan: &sign.AWSEpochTime{time.Now().Add(30 * time.Minute)},
// // Required date the URL will expire after
// DateLessThan: &sign.AWSEpochTime{time.Now().Add(1 * time.Hour)},
// },
// },
// },
// }
//
// signer := sign.NewURLSigner(keyID, privKey)
// signedURL, err := signer.SignWithPolicy(rawURL, policy)
// if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// }
// // Sign URL to be valid for 30 minutes from now, expires one hour from now, and
// // restricted to the 192.0.2.0/24 IP address range.
// policy := &sign.Policy{
// Statements: []sign.Statement{
// {
// Resource: rawURL,
// Condition: sign.Condition{
// // Optional IP source address range
// IPAddress: &sign.IPAddress{SourceIP: "192.0.2.0/24"},
// // Optional date URL is not valid until
// DateGreaterThan: &sign.AWSEpochTime{time.Now().Add(30 * time.Minute)},
// // Required date the URL will expire after
// DateLessThan: &sign.AWSEpochTime{time.Now().Add(1 * time.Hour)},
// },
// },
// },
// }
//
// signer := sign.NewURLSigner(keyID, privKey)
// signedURL, err := signer.SignWithPolicy(rawURL, policy)
// if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// }
func (s URLSigner) SignWithPolicy(url string, p *Policy) (string, error) {
scheme, cleanedURL, err := cleanURLScheme(url)
if err != nil {

File diff suppressed because it is too large Load diff

View file

@ -39,11 +39,11 @@ func NormalizeBucketLocation(loc string) string {
// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
// for more information on the values that can be returned.
//
// req, result := svc.GetBucketLocationRequest(&s3.GetBucketLocationInput{
// Bucket: aws.String(bucket),
// })
// req.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
// err := req.Send()
// req, result := svc.GetBucketLocationRequest(&s3.GetBucketLocationInput{
// Bucket: aws.String(bucket),
// })
// req.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
// err := req.Send()
var NormalizeBucketLocationHandler = request.NamedHandler{
Name: "awssdk.s3.NormalizeBucketLocation",
Fn: func(req *request.Request) {
@ -65,12 +65,12 @@ var NormalizeBucketLocationHandler = request.NamedHandler{
// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
// for more information on the values that can be returned.
//
// result, err := svc.GetBucketLocationWithContext(ctx,
// &s3.GetBucketLocationInput{
// Bucket: aws.String(bucket),
// },
// s3.WithNormalizeBucketLocation,
// )
// result, err := svc.GetBucketLocationWithContext(ctx,
// &s3.GetBucketLocationInput{
// Bucket: aws.String(bucket),
// },
// s3.WithNormalizeBucketLocation,
// )
func WithNormalizeBucketLocation(r *request.Request) {
r.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
}

View file

@ -8,7 +8,7 @@
// See s3 package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
//
// Using the Client
// # Using the Client
//
// To contact Amazon Simple Storage Service with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.

View file

@ -6,99 +6,99 @@
// for optimizations if the Body satisfies that type. Once the Uploader instance
// is created you can call Upload concurrently from multiple goroutines safely.
//
// // The session the S3 Uploader will use
// sess := session.Must(session.NewSession())
// // The session the S3 Uploader will use
// sess := session.Must(session.NewSession())
//
// // Create an uploader with the session and default options
// uploader := s3manager.NewUploader(sess)
// // Create an uploader with the session and default options
// uploader := s3manager.NewUploader(sess)
//
// f, err := os.Open(filename)
// if err != nil {
// return fmt.Errorf("failed to open file %q, %v", filename, err)
// }
// f, err := os.Open(filename)
// if err != nil {
// return fmt.Errorf("failed to open file %q, %v", filename, err)
// }
//
// // Upload the file to S3.
// result, err := uploader.Upload(&s3manager.UploadInput{
// Bucket: aws.String(myBucket),
// Key: aws.String(myString),
// Body: f,
// })
// if err != nil {
// return fmt.Errorf("failed to upload file, %v", err)
// }
// fmt.Printf("file uploaded to, %s\n", aws.StringValue(result.Location))
// // Upload the file to S3.
// result, err := uploader.Upload(&s3manager.UploadInput{
// Bucket: aws.String(myBucket),
// Key: aws.String(myString),
// Body: f,
// })
// if err != nil {
// return fmt.Errorf("failed to upload file, %v", err)
// }
// fmt.Printf("file uploaded to, %s\n", aws.StringValue(result.Location))
//
// See the s3manager package's Uploader type documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Uploader
//
// Download Manager
// # Download Manager
//
// The s3manager package's Downloader provides concurrently downloading of Objects
// from S3. The Downloader will write S3 Object content with an io.WriterAt.
// Once the Downloader instance is created you can call Download concurrently from
// multiple goroutines safely.
//
// // The session the S3 Downloader will use
// sess := session.Must(session.NewSession())
// // The session the S3 Downloader will use
// sess := session.Must(session.NewSession())
//
// // Create a downloader with the session and default options
// downloader := s3manager.NewDownloader(sess)
// // Create a downloader with the session and default options
// downloader := s3manager.NewDownloader(sess)
//
// // Create a file to write the S3 Object contents to.
// f, err := os.Create(filename)
// if err != nil {
// return fmt.Errorf("failed to create file %q, %v", filename, err)
// }
// // Create a file to write the S3 Object contents to.
// f, err := os.Create(filename)
// if err != nil {
// return fmt.Errorf("failed to create file %q, %v", filename, err)
// }
//
// // Write the contents of S3 Object to the file
// n, err := downloader.Download(f, &s3.GetObjectInput{
// Bucket: aws.String(myBucket),
// Key: aws.String(myString),
// })
// if err != nil {
// return fmt.Errorf("failed to download file, %v", err)
// }
// fmt.Printf("file downloaded, %d bytes\n", n)
// // Write the contents of S3 Object to the file
// n, err := downloader.Download(f, &s3.GetObjectInput{
// Bucket: aws.String(myBucket),
// Key: aws.String(myString),
// })
// if err != nil {
// return fmt.Errorf("failed to download file, %v", err)
// }
// fmt.Printf("file downloaded, %d bytes\n", n)
//
// See the s3manager package's Downloader type documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Downloader
//
// Automatic URI cleaning
// # Automatic URI cleaning
//
// Interacting with objects whose keys contain adjacent slashes (e.g. bucketname/foo//bar/objectname)
// requires setting DisableRestProtocolURICleaning to true in the aws.Config struct
// used by the service client.
//
// svc := s3.New(sess, &aws.Config{
// DisableRestProtocolURICleaning: aws.Bool(true),
// })
// out, err := svc.GetObject(&s3.GetObjectInput {
// Bucket: aws.String("bucketname"),
// Key: aws.String("//foo//bar//moo"),
// })
// svc := s3.New(sess, &aws.Config{
// DisableRestProtocolURICleaning: aws.Bool(true),
// })
// out, err := svc.GetObject(&s3.GetObjectInput {
// Bucket: aws.String("bucketname"),
// Key: aws.String("//foo//bar//moo"),
// })
//
// Get Bucket Region
// # Get Bucket Region
//
// GetBucketRegion will attempt to get the region for a bucket using a region
// hint to determine which AWS partition to perform the query on. Use this utility
// to determine the region a bucket is in.
//
// sess := session.Must(session.NewSession())
// sess := session.Must(session.NewSession())
//
// bucket := "my-bucket"
// region, err := s3manager.GetBucketRegion(ctx, sess, bucket, "us-west-2")
// if err != nil {
// if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "NotFound" {
// fmt.Fprintf(os.Stderr, "unable to find bucket %s's region not found\n", bucket)
// }
// return err
// }
// fmt.Printf("Bucket %s is in %s region\n", bucket, region)
// bucket := "my-bucket"
// region, err := s3manager.GetBucketRegion(ctx, sess, bucket, "us-west-2")
// if err != nil {
// if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "NotFound" {
// fmt.Fprintf(os.Stderr, "unable to find bucket %s's region not found\n", bucket)
// }
// return err
// }
// fmt.Printf("Bucket %s is in %s region\n", bucket, region)
//
// See the s3manager package's GetBucketRegion function documentation for more information
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#GetBucketRegion
//
// S3 Crypto Client
// # S3 Crypto Client
//
// The s3crypto package provides the tools to upload and download encrypted
// content from S3. The Encryption and Decryption clients can be used concurrently
@ -106,5 +106,4 @@
//
// See the s3crypto package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3crypto/
//
package s3

View file

@ -52,9 +52,8 @@ func accessPointResourceParser(a awsarn.ARN) (arn.Resource, error) {
// outpost access-point resource.
//
// Supported Outpost AccessPoint ARN format:
// - ARN format: arn:{partition}:s3-outposts:{region}:{accountId}:outpost/{outpostId}/accesspoint/{accesspointName}
// - example: arn:aws:s3-outposts:us-west-2:012345678901:outpost/op-1234567890123456/accesspoint/myaccesspoint
//
// - ARN format: arn:{partition}:s3-outposts:{region}:{accountId}:outpost/{outpostId}/accesspoint/{accesspointName}
// - example: arn:aws:s3-outposts:us-west-2:012345678901:outpost/op-1234567890123456/accesspoint/myaccesspoint
func parseOutpostAccessPointResource(a awsarn.ARN, resParts []string) (arn.OutpostAccessPointARN, error) {
// outpost accesspoint arn is only valid if service is s3-outposts
if a.Service != "s3-outposts" {

View file

@ -37,7 +37,6 @@ type accessPointEndpointBuilder arn.AccessPointARN
// - example : myaccesspoint-012345678901.s3-accesspoint.us-west-2.amazonaws.com
//
// Access Point Endpoint requests are signed using "s3" as signing name.
//
func (a accessPointEndpointBuilder) build(req *request.Request) error {
resolveService := arn.AccessPointARN(a).Service
resolveRegion := arn.AccessPointARN(a).Region
@ -92,7 +91,6 @@ type s3ObjectLambdaAccessPointEndpointBuilder arn.S3ObjectLambdaAccessPointARN
// - example : myaccesspoint-012345678901.s3-object-lambda.us-west-2.amazonaws.com
//
// Access Point Endpoint requests are signed using "s3-object-lambda" as signing name.
//
func (a s3ObjectLambdaAccessPointEndpointBuilder) build(req *request.Request) error {
resolveRegion := arn.S3ObjectLambdaAccessPointARN(a).Region
@ -147,7 +145,6 @@ type outpostAccessPointEndpointBuilder arn.OutpostAccessPointARN
// - example : myaccesspoint-012345678901.op-01234567890123456.s3-outposts.us-west-2.amazonaws.com
//
// Outpost AccessPoint Endpoint request are signed using "s3-outposts" as signing name.
//
func (o outpostAccessPointEndpointBuilder) build(req *request.Request) error {
resolveRegion := o.Region
resolveService := o.Service

View file

@ -25,5 +25,5 @@ func add100Continue(r *request.Request) {
return
}
r.HTTPRequest.Header.Set("Expect", "100-Continue")
r.HTTPRequest.Header.Set("Expect", "100-continue")
}

View file

@ -39,13 +39,14 @@ const (
// aws.Config parameter to add your extra config.
//
// Example:
// mySession := session.Must(session.NewSession())
//
// // Create a S3 client from just a session.
// svc := s3.New(mySession)
// mySession := session.Must(session.NewSession())
//
// // Create a S3 client with additional configuration
// svc := s3.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
// // Create a S3 client from just a session.
// svc := s3.New(mySession)
//
// // Create a S3 client with additional configuration
// svc := s3.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *S3 {
c := p.ClientConfig(EndpointsID, cfgs...)
if c.SigningNameDerived || len(c.SigningName) == 0 {

View file

@ -29,14 +29,13 @@ const opGetRoleCredentials = "GetRoleCredentials"
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
// // Example sending a request using the GetRoleCredentialsRequest method.
// req, resp := client.GetRoleCredentialsRequest(params)
//
// // Example sending a request using the GetRoleCredentialsRequest method.
// req, resp := client.GetRoleCredentialsRequest(params)
//
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/GetRoleCredentials
func (c *SSO) GetRoleCredentialsRequest(input *GetRoleCredentialsInput) (req *request.Request, output *GetRoleCredentialsOutput) {
@ -69,20 +68,21 @@ func (c *SSO) GetRoleCredentialsRequest(input *GetRoleCredentialsInput) (req *re
// API operation GetRoleCredentials for usage and error information.
//
// Returned Error Types:
// * InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
// - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
//
// * ResourceNotFoundException
// The specified resource doesn't exist.
// - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
//
// - ResourceNotFoundException
// The specified resource doesn't exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/GetRoleCredentials
func (c *SSO) GetRoleCredentials(input *GetRoleCredentialsInput) (*GetRoleCredentialsOutput, error) {
@ -122,14 +122,13 @@ const opListAccountRoles = "ListAccountRoles"
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
// // Example sending a request using the ListAccountRolesRequest method.
// req, resp := client.ListAccountRolesRequest(params)
//
// // Example sending a request using the ListAccountRolesRequest method.
// req, resp := client.ListAccountRolesRequest(params)
//
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccountRoles
func (c *SSO) ListAccountRolesRequest(input *ListAccountRolesInput) (req *request.Request, output *ListAccountRolesOutput) {
@ -167,20 +166,21 @@ func (c *SSO) ListAccountRolesRequest(input *ListAccountRolesInput) (req *reques
// API operation ListAccountRoles for usage and error information.
//
// Returned Error Types:
// * InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
// - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
//
// * ResourceNotFoundException
// The specified resource doesn't exist.
// - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
//
// - ResourceNotFoundException
// The specified resource doesn't exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccountRoles
func (c *SSO) ListAccountRoles(input *ListAccountRolesInput) (*ListAccountRolesOutput, error) {
@ -212,15 +212,14 @@ func (c *SSO) ListAccountRolesWithContext(ctx aws.Context, input *ListAccountRol
//
// Note: This operation can generate multiple requests to a service.
//
// // Example iterating over at most 3 pages of a ListAccountRoles operation.
// pageNum := 0
// err := client.ListAccountRolesPages(params,
// func(page *sso.ListAccountRolesOutput, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
//
// // Example iterating over at most 3 pages of a ListAccountRoles operation.
// pageNum := 0
// err := client.ListAccountRolesPages(params,
// func(page *sso.ListAccountRolesOutput, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
func (c *SSO) ListAccountRolesPages(input *ListAccountRolesInput, fn func(*ListAccountRolesOutput, bool) bool) error {
return c.ListAccountRolesPagesWithContext(aws.BackgroundContext(), input, fn)
}
@ -272,14 +271,13 @@ const opListAccounts = "ListAccounts"
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
// // Example sending a request using the ListAccountsRequest method.
// req, resp := client.ListAccountsRequest(params)
//
// // Example sending a request using the ListAccountsRequest method.
// req, resp := client.ListAccountsRequest(params)
//
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccounts
func (c *SSO) ListAccountsRequest(input *ListAccountsInput) (req *request.Request, output *ListAccountsOutput) {
@ -310,7 +308,8 @@ func (c *SSO) ListAccountsRequest(input *ListAccountsInput) (req *request.Reques
// Lists all AWS accounts assigned to the user. These AWS accounts are assigned
// by the administrator of the account. For more information, see Assign User
// Access (https://docs.aws.amazon.com/singlesignon/latest/userguide/useraccess.html#assignusers)
// in the AWS SSO User Guide. This operation returns a paginated response.
// in the IAM Identity Center User Guide. This operation returns a paginated
// response.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
@ -320,20 +319,21 @@ func (c *SSO) ListAccountsRequest(input *ListAccountsInput) (req *request.Reques
// API operation ListAccounts for usage and error information.
//
// Returned Error Types:
// * InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
// - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
//
// * ResourceNotFoundException
// The specified resource doesn't exist.
// - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
//
// - ResourceNotFoundException
// The specified resource doesn't exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccounts
func (c *SSO) ListAccounts(input *ListAccountsInput) (*ListAccountsOutput, error) {
@ -365,15 +365,14 @@ func (c *SSO) ListAccountsWithContext(ctx aws.Context, input *ListAccountsInput,
//
// Note: This operation can generate multiple requests to a service.
//
// // Example iterating over at most 3 pages of a ListAccounts operation.
// pageNum := 0
// err := client.ListAccountsPages(params,
// func(page *sso.ListAccountsOutput, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
//
// // Example iterating over at most 3 pages of a ListAccounts operation.
// pageNum := 0
// err := client.ListAccountsPages(params,
// func(page *sso.ListAccountsOutput, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
func (c *SSO) ListAccountsPages(input *ListAccountsInput, fn func(*ListAccountsOutput, bool) bool) error {
return c.ListAccountsPagesWithContext(aws.BackgroundContext(), input, fn)
}
@ -425,14 +424,13 @@ const opLogout = "Logout"
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
// // Example sending a request using the LogoutRequest method.
// req, resp := client.LogoutRequest(params)
//
// // Example sending a request using the LogoutRequest method.
// req, resp := client.LogoutRequest(params)
//
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
// err := req.Send()
// if err == nil { // resp is now filled
// fmt.Println(resp)
// }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/Logout
func (c *SSO) LogoutRequest(input *LogoutInput) (req *request.Request, output *LogoutOutput) {
@ -455,7 +453,21 @@ func (c *SSO) LogoutRequest(input *LogoutInput) (req *request.Request, output *L
// Logout API operation for AWS Single Sign-On.
//
// Removes the client- and server-side session that is associated with the user.
// Removes the locally stored SSO tokens from the client-side cache and sends
// an API call to the IAM Identity Center service to invalidate the corresponding
// server-side IAM Identity Center sign in session.
//
// If a user uses IAM Identity Center to access the AWS CLI, the users IAM
// Identity Center sign in session is used to obtain an IAM session, as specified
// in the corresponding IAM Identity Center permission set. More specifically,
// IAM Identity Center assumes an IAM role in the target account on behalf of
// the user, and the corresponding temporary AWS credentials are returned to
// the client.
//
// After user logout, any existing IAM role sessions that were created by using
// IAM Identity Center permission sets continue based on the duration configured
// in the permission set. For more information, see User authentications (https://docs.aws.amazon.com/singlesignon/latest/userguide/authconcept.html)
// in the IAM Identity Center User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
@ -465,17 +477,18 @@ func (c *SSO) LogoutRequest(input *LogoutInput) (req *request.Request, output *L
// API operation Logout for usage and error information.
//
// Returned Error Types:
// * InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range.
//
// * TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
// - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request.
//
// - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than
// what the server can handle.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/Logout
func (c *SSO) Logout(input *LogoutInput) (*LogoutOutput, error) {
@ -554,7 +567,7 @@ type GetRoleCredentialsInput struct {
// The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
// in the AWS SSO OIDC API Reference Guide.
// in the IAM Identity Center OIDC API Reference Guide.
//
// AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by GetRoleCredentialsInput's
@ -730,7 +743,7 @@ type ListAccountRolesInput struct {
// The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
// in the AWS SSO OIDC API Reference Guide.
// in the IAM Identity Center OIDC API Reference Guide.
//
// AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by ListAccountRolesInput's
@ -859,7 +872,7 @@ type ListAccountsInput struct {
// The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
// in the AWS SSO OIDC API Reference Guide.
// in the IAM Identity Center OIDC API Reference Guide.
//
// AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by ListAccountsInput's
@ -974,7 +987,7 @@ type LogoutInput struct {
// The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
// in the AWS SSO OIDC API Reference Guide.
// in the IAM Identity Center OIDC API Reference Guide.
//
// AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by LogoutInput's

View file

@ -3,30 +3,31 @@
// Package sso provides the client and types for making API
// requests to AWS Single Sign-On.
//
// AWS Single Sign-On Portal is a web service that makes it easy for you to
// assign user access to AWS SSO resources such as the user portal. Users can
// get AWS account applications and roles assigned to them and get federated
// into the application.
// AWS IAM Identity Center (successor to AWS Single Sign-On) Portal is a web
// service that makes it easy for you to assign user access to IAM Identity
// Center resources such as the AWS access portal. Users can get AWS account
// applications and roles assigned to them and get federated into the application.
//
// For general information about AWS SSO, see What is AWS Single Sign-On? (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
// in the AWS SSO User Guide.
// Although AWS Single Sign-On was renamed, the sso and identitystore API namespaces
// will continue to retain their original name for backward compatibility purposes.
// For more information, see IAM Identity Center rename (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed).
//
// This API reference guide describes the AWS SSO Portal operations that you
// can call programatically and includes detailed information on data types
// and errors.
// This reference guide describes the IAM Identity Center Portal operations
// that you can call programatically and includes detailed information on data
// types and errors.
//
// AWS provides SDKs that consist of libraries and sample code for various programming
// languages and platforms, such as Java, Ruby, .Net, iOS, or Android. The SDKs
// provide a convenient way to create programmatic access to AWS SSO and other
// AWS services. For more information about the AWS SDKs, including how to download
// and install them, see Tools for Amazon Web Services (http://aws.amazon.com/tools/).
// provide a convenient way to create programmatic access to IAM Identity Center
// and other AWS services. For more information about the AWS SDKs, including
// how to download and install them, see Tools for Amazon Web Services (http://aws.amazon.com/tools/).
//
// See https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10 for more information on this service.
//
// See sso package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/sso/
//
// Using the Client
// # Using the Client
//
// To contact AWS Single Sign-On with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.

View file

@ -40,13 +40,14 @@ const (
// aws.Config parameter to add your extra config.
//
// Example:
// mySession := session.Must(session.NewSession())
//
// // Create a SSO client from just a session.
// svc := sso.New(mySession)
// mySession := session.Must(session.NewSession())
//
// // Create a SSO client with additional configuration
// svc := sso.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
// // Create a SSO client from just a session.
// svc := sso.New(mySession)
//
// // Create a SSO client with additional configuration
// svc := sso.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SSO {
c := p.ClientConfig(EndpointsID, cfgs...)
if c.SigningNameDerived || len(c.SigningName) == 0 {

View file

@ -23,37 +23,37 @@ import (
// can be stubbed out for unit testing your code with the SDK without needing
// to inject custom request handlers into the SDK's request pipeline.
//
// // myFunc uses an SDK service client to make a request to
// // AWS Single Sign-On.
// func myFunc(svc ssoiface.SSOAPI) bool {
// // Make svc.GetRoleCredentials request
// }
// // myFunc uses an SDK service client to make a request to
// // AWS Single Sign-On.
// func myFunc(svc ssoiface.SSOAPI) bool {
// // Make svc.GetRoleCredentials request
// }
//
// func main() {
// sess := session.New()
// svc := sso.New(sess)
// func main() {
// sess := session.New()
// svc := sso.New(sess)
//
// myFunc(svc)
// }
// myFunc(svc)
// }
//
// In your _test.go file:
//
// // Define a mock struct to be used in your unit tests of myFunc.
// type mockSSOClient struct {
// ssoiface.SSOAPI
// }
// func (m *mockSSOClient) GetRoleCredentials(input *sso.GetRoleCredentialsInput) (*sso.GetRoleCredentialsOutput, error) {
// // mock response/functionality
// }
// // Define a mock struct to be used in your unit tests of myFunc.
// type mockSSOClient struct {
// ssoiface.SSOAPI
// }
// func (m *mockSSOClient) GetRoleCredentials(input *sso.GetRoleCredentialsInput) (*sso.GetRoleCredentialsOutput, error) {
// // mock response/functionality
// }
//
// func TestMyFunc(t *testing.T) {
// // Setup Test
// mockSvc := &mockSSOClient{}
// func TestMyFunc(t *testing.T) {
// // Setup Test
// mockSvc := &mockSSOClient{}
//
// myfunc(mockSvc)
// myfunc(mockSvc)
//
// // Verify myFunc's functionality
// }
// // Verify myFunc's functionality
// }
//
// It is important to note that this interface will have breaking changes
// when the service model is updated and adds new API operations, paginators,

1682
vendor/github.com/aws/aws-sdk-go/service/ssooidc/api.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
// Package ssooidc provides the client and types for making API
// requests to AWS SSO OIDC.
//
// AWS IAM Identity Center (successor to AWS Single Sign-On) OpenID Connect
// (OIDC) is a web service that enables a client (such as AWS CLI or a native
// application) to register with IAM Identity Center. The service also enables
// the client to fetch the users access token upon successful authentication
// and authorization with IAM Identity Center.
//
// Although AWS Single Sign-On was renamed, the sso and identitystore API namespaces
// will continue to retain their original name for backward compatibility purposes.
// For more information, see IAM Identity Center rename (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed).
//
// # Considerations for Using This Guide
//
// Before you begin using this guide, we recommend that you first review the
// following important information about how the IAM Identity Center OIDC service
// works.
//
// - The IAM Identity Center OIDC service currently implements only the portions
// of the OAuth 2.0 Device Authorization Grant standard (https://tools.ietf.org/html/rfc8628
// (https://tools.ietf.org/html/rfc8628)) that are necessary to enable single
// sign-on authentication with the AWS CLI. Support for other OIDC flows
// frequently needed for native applications, such as Authorization Code
// Flow (+ PKCE), will be addressed in future releases.
//
// - The service emits only OIDC access tokens, such that obtaining a new
// token (For example, token refresh) requires explicit user re-authentication.
//
// - The access tokens provided by this service grant access to all AWS account
// entitlements assigned to an IAM Identity Center user, not just a particular
// application.
//
// - The documentation in this guide does not describe the mechanism to convert
// the access token into AWS Auth (“sigv4”) credentials for use with
// IAM-protected AWS service endpoints. For more information, see GetRoleCredentials
// (https://docs.aws.amazon.com/singlesignon/latest/PortalAPIReference/API_GetRoleCredentials.html)
// in the IAM Identity Center Portal API Reference Guide.
//
// For general information about IAM Identity Center, see What is IAM Identity
// Center? (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
// in the IAM Identity Center User Guide.
//
// See https://docs.aws.amazon.com/goto/WebAPI/sso-oidc-2019-06-10 for more information on this service.
//
// See ssooidc package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/ssooidc/
//
// # Using the Client
//
// To contact AWS SSO OIDC with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently.
//
// See the SDK's documentation for more information on how to use the SDK.
// https://docs.aws.amazon.com/sdk-for-go/api/
//
// See aws.Config documentation for more information on configuring SDK clients.
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
//
// See the AWS SSO OIDC client SSOOIDC for more
// information on creating client for this service.
// https://docs.aws.amazon.com/sdk-for-go/api/service/ssooidc/#New
package ssooidc

View file

@ -0,0 +1,107 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package ssooidc
import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const (
// ErrCodeAccessDeniedException for service response error code
// "AccessDeniedException".
//
// You do not have sufficient access to perform this action.
ErrCodeAccessDeniedException = "AccessDeniedException"
// ErrCodeAuthorizationPendingException for service response error code
// "AuthorizationPendingException".
//
// Indicates that a request to authorize a client with an access user session
// token is pending.
ErrCodeAuthorizationPendingException = "AuthorizationPendingException"
// ErrCodeExpiredTokenException for service response error code
// "ExpiredTokenException".
//
// Indicates that the token issued by the service is expired and is no longer
// valid.
ErrCodeExpiredTokenException = "ExpiredTokenException"
// ErrCodeInternalServerException for service response error code
// "InternalServerException".
//
// Indicates that an error from the service occurred while trying to process
// a request.
ErrCodeInternalServerException = "InternalServerException"
// ErrCodeInvalidClientException for service response error code
// "InvalidClientException".
//
// Indicates that the clientId or clientSecret in the request is invalid. For
// example, this can occur when a client sends an incorrect clientId or an expired
// clientSecret.
ErrCodeInvalidClientException = "InvalidClientException"
// ErrCodeInvalidClientMetadataException for service response error code
// "InvalidClientMetadataException".
//
// Indicates that the client information sent in the request during registration
// is invalid.
ErrCodeInvalidClientMetadataException = "InvalidClientMetadataException"
// ErrCodeInvalidGrantException for service response error code
// "InvalidGrantException".
//
// Indicates that a request contains an invalid grant. This can occur if a client
// makes a CreateToken request with an invalid grant type.
ErrCodeInvalidGrantException = "InvalidGrantException"
// ErrCodeInvalidRequestException for service response error code
// "InvalidRequestException".
//
// Indicates that something is wrong with the input to the request. For example,
// a required parameter might be missing or out of range.
ErrCodeInvalidRequestException = "InvalidRequestException"
// ErrCodeInvalidScopeException for service response error code
// "InvalidScopeException".
//
// Indicates that the scope provided in the request is invalid.
ErrCodeInvalidScopeException = "InvalidScopeException"
// ErrCodeSlowDownException for service response error code
// "SlowDownException".
//
// Indicates that the client is making the request too frequently and is more
// than the service can handle.
ErrCodeSlowDownException = "SlowDownException"
// ErrCodeUnauthorizedClientException for service response error code
// "UnauthorizedClientException".
//
// Indicates that the client is not currently authorized to make the request.
// This can happen when a clientId is not issued for a public client.
ErrCodeUnauthorizedClientException = "UnauthorizedClientException"
// ErrCodeUnsupportedGrantTypeException for service response error code
// "UnsupportedGrantTypeException".
//
// Indicates that the grant type in the request is not supported by the service.
ErrCodeUnsupportedGrantTypeException = "UnsupportedGrantTypeException"
)
var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{
"AccessDeniedException": newErrorAccessDeniedException,
"AuthorizationPendingException": newErrorAuthorizationPendingException,
"ExpiredTokenException": newErrorExpiredTokenException,
"InternalServerException": newErrorInternalServerException,
"InvalidClientException": newErrorInvalidClientException,
"InvalidClientMetadataException": newErrorInvalidClientMetadataException,
"InvalidGrantException": newErrorInvalidGrantException,
"InvalidRequestException": newErrorInvalidRequestException,
"InvalidScopeException": newErrorInvalidScopeException,
"SlowDownException": newErrorSlowDownException,
"UnauthorizedClientException": newErrorUnauthorizedClientException,
"UnsupportedGrantTypeException": newErrorUnsupportedGrantTypeException,
}

View file

@ -0,0 +1,106 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package ssooidc
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/restjson"
)
// SSOOIDC provides the API operation methods for making requests to
// AWS SSO OIDC. See this package's package overview docs
// for details on the service.
//
// SSOOIDC methods are safe to use concurrently. It is not safe to
// modify mutate any of the struct's properties though.
type SSOOIDC struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// Service information constants
const (
ServiceName = "SSO OIDC" // Name of service.
EndpointsID = "oidc" // ID to lookup a service endpoint with.
ServiceID = "SSO OIDC" // ServiceID is a unique identifier of a specific service.
)
// New creates a new instance of the SSOOIDC client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
//
// mySession := session.Must(session.NewSession())
//
// // Create a SSOOIDC client from just a session.
// svc := ssooidc.New(mySession)
//
// // Create a SSOOIDC client with additional configuration
// svc := ssooidc.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SSOOIDC {
c := p.ClientConfig(EndpointsID, cfgs...)
if c.SigningNameDerived || len(c.SigningName) == 0 {
c.SigningName = "awsssooidc"
}
return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName, c.ResolvedRegion)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName, resolvedRegion string) *SSOOIDC {
svc := &SSOOIDC{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName,
SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint,
APIVersion: "2019-06-10",
ResolvedRegion: resolvedRegion,
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
svc.Handlers.Build.PushBackNamed(restjson.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(
protocol.NewUnmarshalErrorHandler(restjson.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(),
)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a SSOOIDC operation and runs any
// custom request initialization.
func (c *SSOOIDC) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

File diff suppressed because it is too large Load diff

View file

@ -4,17 +4,16 @@
// requests to AWS Security Token Service.
//
// Security Token Service (STS) enables you to request temporary, limited-privilege
// credentials for Identity and Access Management (IAM) users or for users that
// you authenticate (federated users). This guide provides descriptions of the
// STS API. For more information about using this service, see Temporary Security
// Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
// credentials for users. This guide provides descriptions of the STS API. For
// more information about using this service, see Temporary Security Credentials
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
//
// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service.
//
// See sts package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/
//
// Using the Client
// # Using the Client
//
// To contact AWS Security Token Service with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.

View file

@ -39,13 +39,14 @@ const (
// aws.Config parameter to add your extra config.
//
// Example:
// mySession := session.Must(session.NewSession())
//
// // Create a STS client from just a session.
// svc := sts.New(mySession)
// mySession := session.Must(session.NewSession())
//
// // Create a STS client with additional configuration
// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
// // Create a STS client from just a session.
// svc := sts.New(mySession)
//
// // Create a STS client with additional configuration
// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS {
c := p.ClientConfig(EndpointsID, cfgs...)
if c.SigningNameDerived || len(c.SigningName) == 0 {

View file

@ -23,37 +23,37 @@ import (
// can be stubbed out for unit testing your code with the SDK without needing
// to inject custom request handlers into the SDK's request pipeline.
//
// // myFunc uses an SDK service client to make a request to
// // AWS Security Token Service.
// func myFunc(svc stsiface.STSAPI) bool {
// // Make svc.AssumeRole request
// }
// // myFunc uses an SDK service client to make a request to
// // AWS Security Token Service.
// func myFunc(svc stsiface.STSAPI) bool {
// // Make svc.AssumeRole request
// }
//
// func main() {
// sess := session.New()
// svc := sts.New(sess)
// func main() {
// sess := session.New()
// svc := sts.New(sess)
//
// myFunc(svc)
// }
// myFunc(svc)
// }
//
// In your _test.go file:
//
// // Define a mock struct to be used in your unit tests of myFunc.
// type mockSTSClient struct {
// stsiface.STSAPI
// }
// func (m *mockSTSClient) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
// // mock response/functionality
// }
// // Define a mock struct to be used in your unit tests of myFunc.
// type mockSTSClient struct {
// stsiface.STSAPI
// }
// func (m *mockSTSClient) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
// // mock response/functionality
// }
//
// func TestMyFunc(t *testing.T) {
// // Setup Test
// mockSvc := &mockSTSClient{}
// func TestMyFunc(t *testing.T) {
// // Setup Test
// mockSvc := &mockSTSClient{}
//
// myfunc(mockSvc)
// myfunc(mockSvc)
//
// // Verify myFunc's functionality
// }
// // Verify myFunc's functionality
// }
//
// It is important to note that this interface will have breaking changes
// when the service model is updated and adds new API operations, paginators,

4
vendor/modules.txt vendored
View file

@ -94,10 +94,11 @@ github.com/AzureAD/microsoft-authentication-library-for-go/apps/public
# github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d
## explicit
github.com/Shopify/logrus-bugsnag
# github.com/aws/aws-sdk-go v1.43.16
# github.com/aws/aws-sdk-go v1.44.325
## explicit; go 1.11
github.com/aws/aws-sdk-go/aws
github.com/aws/aws-sdk-go/aws/arn
github.com/aws/aws-sdk-go/aws/auth/bearer
github.com/aws/aws-sdk-go/aws/awserr
github.com/aws/aws-sdk-go/aws/awsutil
github.com/aws/aws-sdk-go/aws/client
@ -144,6 +145,7 @@ github.com/aws/aws-sdk-go/service/cloudfront/sign
github.com/aws/aws-sdk-go/service/s3
github.com/aws/aws-sdk-go/service/sso
github.com/aws/aws-sdk-go/service/sso/ssoiface
github.com/aws/aws-sdk-go/service/ssooidc
github.com/aws/aws-sdk-go/service/sts
github.com/aws/aws-sdk-go/service/sts/stsiface
# github.com/beorn7/perks v1.0.1