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/azidentity v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.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/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/bshuster-repo/logrus-logstash-hook v1.0.0
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c 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-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-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 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.44.325 h1:jF/L99fJSq/BfiLmUOflO/aM+LwcqBm0Fe/qTK5xxuI=
github.com/aws/aws-sdk-go v1.43.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= 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 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.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 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.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/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.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 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= 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= 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-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-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-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 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= 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= 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.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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.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-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/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-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-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-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-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 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= 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= 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-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-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-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-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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-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-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-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 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-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.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.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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/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.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 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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= 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-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-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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

@ -192,6 +192,23 @@ type Config struct {
// //
EC2MetadataDisableTimeoutOverride *bool 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 // Instructs the endpoint to be generated for a service client to
// be the dual stack endpoint. The dual stack endpoint will support // be the dual stack endpoint. The dual stack endpoint will support
// both IPv4 and IPv6 addressing. // both IPv4 and IPv6 addressing.
@ -432,6 +449,13 @@ func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
return c 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 // WithSleepDelay overrides the function used to sleep while waiting for the
// next retry. Defaults to time.Sleep. // next retry. Defaults to time.Sleep.
func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config { func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
@ -576,6 +600,10 @@ func mergeInConfig(dst *Config, other *Config) {
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
} }
if other.EC2MetadataEnableFallback != nil {
dst.EC2MetadataEnableFallback = other.EC2MetadataEnableFallback
}
if other.SleepDelay != nil { if other.SleepDelay != nil {
dst.SleepDelay = other.SleepDelay dst.SleepDelay = other.SleepDelay
} }

View file

@ -226,11 +226,23 @@ func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider))
return credentials.NewCredentials(p) return credentials.NewCredentials(p)
} }
type credentialProcessResponse struct { // 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 Version int
// The access key ID that identifies the temporary security credentials.
AccessKeyID string `json:"AccessKeyId"` AccessKeyID string `json:"AccessKeyId"`
// The secret access key that can be used to sign requests.
SecretAccessKey string SecretAccessKey string
// The token that users must pass to the service API to use the temporary credentials.
SessionToken string SessionToken string
// The date on which the current credentials expire.
Expiration *time.Time Expiration *time.Time
} }
@ -242,7 +254,7 @@ func (p *ProcessProvider) Retrieve() (credentials.Value, error) {
} }
// Serialize and validate response // Serialize and validate response
resp := &credentialProcessResponse{} resp := &CredentialProcessResponse{}
if err = json.Unmarshal(out, resp); err != nil { if err = json.Unmarshal(out, resp); err != nil {
return credentials.Value{ProviderName: ProviderName}, awserr.New( return credentials.Value{ProviderName: ProviderName}, awserr.New(
ErrCodeProcessProviderParse, ErrCodeProcessProviderParse,

View file

@ -4,13 +4,13 @@ import (
"crypto/sha1" "crypto/sha1"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
"github.com/aws/aws-sdk-go/aws" "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/awserr"
"github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/credentials" "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. // The URL that points to the organization's AWS Single Sign-On (AWS SSO) user portal.
StartURL string 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 // 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 // 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. // by exchanging the accessToken present in ~/.aws/sso/cache.
func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) { func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
tokenFile, err := loadTokenFile(p.StartURL) var accessToken *string
if p.TokenProvider != nil {
token, err := p.TokenProvider.RetrieveBearerToken(ctx)
if err != nil { if err != nil {
return credentials.Value{}, err 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{ output, err := p.Client.GetRoleCredentialsWithContext(ctx, &sso.GetRoleCredentialsInput{
AccessToken: &tokenFile.AccessToken, AccessToken: accessToken,
AccountId: &p.AccountID, AccountId: &p.AccountID,
RoleName: &p.RoleName, RoleName: &p.RoleName,
}) })
@ -114,32 +145,13 @@ func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Val
}, nil }, nil
} }
func getCacheFileName(url string) (string, error) { func getCachedFilePath(startUrl string) (string, error) {
hash := sha1.New() hash := sha1.New()
_, err := hash.Write([]byte(url)) _, err := hash.Write([]byte(startUrl))
if err != nil { if err != nil {
return "", err return "", err
} }
return strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json", nil return filepath.Join(defaultCacheLocation(), 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
} }
type token struct { type token struct {
@ -153,13 +165,8 @@ func (t token) Expired() bool {
return nowTime().Round(0).After(time.Time(t.ExpiresAt)) return nowTime().Round(0).After(time.Time(t.ExpiresAt))
} }
func loadTokenFile(startURL string) (t token, err error) { func loadTokenFile(cachedTokenPath string) (t token, err error) {
key, err := getCacheFileName(startURL) fileBytes, err := ioutil.ReadFile(cachedTokenPath)
if err != nil {
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
}
fileBytes, err := ioutil.ReadFile(filepath.Join(defaultCacheLocation(), key))
if err != nil { if err != nil {
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err) 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 ensure synchronous usage of the AssumeRoleProvider if the value is shared
between multiple Credentials, Sessions or service clients. 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 To assume an IAM role using STS with the SDK you can create a new Credentials
with the SDKs's stscreds package. with the SDKs's stscreds package.
@ -27,7 +27,7 @@ with the SDKs's stscreds package.
// from assumed role. // from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds}) 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 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 directly or provide a function to prompt the user each time the credentials
@ -49,7 +49,7 @@ credentials.
// from assumed role. // from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds}) 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 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 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 // Create service client value configured for credentials
// from assumed role. // from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds}) svc := s3.New(sess, &aws.Config{Credentials: creds})
*/ */
package stscreds 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). // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
SerialNumber *string 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 // 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 // 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 // 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, Tags: p.Tags,
PolicyArns: p.PolicyArns, PolicyArns: p.PolicyArns,
TransitiveTagKeys: p.TransitiveTagKeys, TransitiveTagKeys: p.TransitiveTagKeys,
SourceIdentity: p.SourceIdentity,
} }
if p.Policy != nil { if p.Policy != nil {
input.Policy = p.Policy input.Policy = p.Policy

View file

@ -57,8 +57,8 @@ type EC2Metadata struct {
// New creates a new instance of the EC2Metadata client with a session. // New creates a new instance of the EC2Metadata client with a session.
// This client is safe to use across multiple goroutines. // This client is safe to use across multiple goroutines.
// //
//
// Example: // Example:
//
// // Create a EC2Metadata client from just a session. // // Create a EC2Metadata client from just a session.
// svc := ec2metadata.New(mySession) // svc := ec2metadata.New(mySession)
// //

View file

@ -1,6 +1,7 @@
package ec2metadata package ec2metadata
import ( import (
"fmt"
"net/http" "net/http"
"sync/atomic" "sync/atomic"
"time" "time"
@ -33,11 +34,15 @@ func newTokenProvider(c *EC2Metadata, duration time.Duration) *tokenProvider {
return &tokenProvider{client: c, configuredTTL: duration} 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. // fetchTokenHandler fetches token for EC2Metadata service client by default.
func (t *tokenProvider) fetchTokenHandler(r *request.Request) { func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
// short-circuits to insecure data flow if tokenProvider is disabled. // 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 return
} }
@ -49,23 +54,21 @@ func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
output, err := t.client.getToken(r.Context(), t.configuredTTL) output, err := t.client.getToken(r.Context(), t.configuredTTL)
if err != nil { 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, // change the disabled flag on token provider to true and fallback
// when error is request timeout error.
if requestFailureError, ok := err.(awserr.RequestFailure); ok { if requestFailureError, ok := err.(awserr.RequestFailure); ok {
switch requestFailureError.StatusCode() { switch requestFailureError.StatusCode() {
case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed: case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
atomic.StoreUint32(&t.disabled, 1) 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: case http.StatusBadRequest:
r.Error = requestFailureError 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 return
} }

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
// AWS GovCloud (US) (aws-us-gov). // 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 // Casting the Resolver returned by DefaultResolver to a EnumPartitions interface
// will allow you to get access to the list of underlying Partitions with the // will allow you to get access to the list of underlying Partitions with the
@ -32,7 +32,7 @@
// } // }
// } // }
// //
// Using Custom Endpoints // # Using Custom Endpoints
// //
// The endpoints package also gives you the ability to use your own logic how // 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 // endpoints are resolved. This is a great way to define a custom endpoint
@ -47,7 +47,6 @@
// of Resolver.EndpointFor, converting it to a type that satisfies the // of Resolver.EndpointFor, converting it to a type that satisfies the
// Resolver interface. // Resolver interface.
// //
//
// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { // myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
// if service == endpoints.S3ServiceID { // if service == endpoints.S3ServiceID {
// return endpoints.ResolvedEndpoint{ // return endpoints.ResolvedEndpoint{

View file

@ -353,9 +353,11 @@ type EnumPartitions interface {
// as the second parameter. // as the second parameter.
// //
// This example shows how to get the regions for DynamoDB in the AWS partition. // 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. // 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) { func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
for _, p := range ps { for _, p := range ps {
@ -423,8 +425,8 @@ func (p Partition) ID() string { return p.id }
// of new regions and services expansions. // of new regions and services expansions.
// //
// Errors that can be returned. // Errors that can be returned.
// * UnknownServiceError // - UnknownServiceError
// * UnknownEndpointError // - UnknownEndpointError
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
return p.p.EndpointFor(service, region, opts...) 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 // WithSetRequestHeaders updates the operation request's HTTP header to contain
// the header key value pairs provided. If the header key already exists in the // 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. // 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 { func WithSetRequestHeaders(h map[string]string) Option {
return withRequestHeader(h).SetRequestHeaders return withRequestHeader(h).SetRequestHeaders
} }
@ -338,6 +341,6 @@ type withRequestHeader map[string]string
func (h withRequestHeader) SetRequestHeaders(r *Request) { func (h withRequestHeader) SetRequestHeaders(r *Request) {
for k, v := range h { 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/defaults"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults" "github.com/aws/aws-sdk-go/internal/shareddefaults"
"github.com/aws/aws-sdk-go/service/ssooidc"
"github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/service/sts"
) )
@ -23,6 +24,10 @@ type CredentialsProviderOptions struct {
// WebIdentityRoleProviderOptions configures a WebIdentityRoleProvider, // WebIdentityRoleProviderOptions configures a WebIdentityRoleProvider,
// such as setting its ExpiryWindow. // such as setting its ExpiryWindow.
WebIdentityRoleProviderOptions func(*stscreds.WebIdentityRoleProvider) WebIdentityRoleProviderOptions func(*stscreds.WebIdentityRoleProvider)
// ProcessProviderOptions configures a ProcessProvider,
// such as setting its Timeout.
ProcessProviderOptions func(*processcreds.ProcessProvider)
} }
func resolveCredentials(cfg *aws.Config, func resolveCredentials(cfg *aws.Config,
@ -33,7 +38,7 @@ func resolveCredentials(cfg *aws.Config,
switch { switch {
case len(sessOpts.Profile) != 0: 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. // so load that profile from shared config first.
// Github(aws/aws-sdk-go#2727) // Github(aws/aws-sdk-go#2727)
return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts) return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts)
@ -134,7 +139,11 @@ func resolveCredsFromProfile(cfg *aws.Config,
case len(sharedCfg.CredentialProcess) != 0: case len(sharedCfg.CredentialProcess) != 0:
// Get credentials from CredentialProcess // 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: default:
// Fallback to default credentials provider, include mock errors for // 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 return nil, err
} }
var optFns []func(provider *ssocreds.Provider)
cfgCopy := cfg.Copy() cfgCopy := cfg.Copy()
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 cfgCopy.Region = &sharedCfg.SSORegion
}
return ssocreds.NewCredentials( return ssocreds.NewCredentials(
&Session{ &Session{
@ -184,6 +213,7 @@ func resolveSSOCredentials(cfg *aws.Config, sharedCfg sharedConfig, handlers req
sharedCfg.SSOAccountID, sharedCfg.SSOAccountID,
sharedCfg.SSORoleName, sharedCfg.SSORoleName,
sharedCfg.SSOStartURL, sharedCfg.SSOStartURL,
optFns...,
), nil ), nil
} }

View file

@ -37,7 +37,7 @@ const (
// ErrSharedConfigSourceCollision will be returned if a section contains both // ErrSharedConfigSourceCollision will be returned if a section contains both
// source_profile and credential_source // 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 // ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
// variables are empty and Environment was set as the credential source // 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 // Options provides the means to control how a Session is created and what
// configuration values will be loaded. // configuration values will be loaded.
//
type Options struct { type Options struct {
// Provides config values for the SDK to use when creating service clients // 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 // 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. // from stdin for the MFA token code.
// //
// This field is only used if the shared configuration is enabled, and // 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) AssumeRoleTokenProvider func() (string, error)
// When the SDK's shared config is configured to assume a role this option // When the SDK's shared config is configured to assume a role this option
@ -780,16 +779,6 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, ec2IMDSEndpoint, endpointMode) 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 cfg.S3UseARNRegion = userCfg.S3UseARNRegion
if cfg.S3UseARNRegion == nil { if cfg.S3UseARNRegion == nil {
cfg.S3UseARNRegion = &envCfg.S3UseARNRegion 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 return nil
} }

View file

@ -26,6 +26,13 @@ const (
roleSessionNameKey = `role_session_name` // optional roleSessionNameKey = `role_session_name` // optional
roleDurationSecondsKey = "duration_seconds" // 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 // AWS Single Sign-On (AWS SSO) group
ssoAccountIDKey = "sso_account_id" ssoAccountIDKey = "sso_account_id"
ssoRegionKey = "sso_region" ssoRegionKey = "sso_region"
@ -99,6 +106,10 @@ type sharedConfig struct {
CredentialProcess string CredentialProcess string
WebIdentityTokenFile string WebIdentityTokenFile string
// SSO session options
SSOSessionName string
SSOSession *ssoSession
SSOAccountID string SSOAccountID string
SSORegion string SSORegion string
SSORoleName string SSORoleName string
@ -186,6 +197,20 @@ type sharedConfigFile struct {
IniData ini.Sections 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 // loadSharedConfig retrieves the configuration from the list of files using
// the profile provided. The order the files are listed will determine // the profile provided. The order the files are listed will determine
// precedence. Values in subsequent files will overwrite values defined in // 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. // profile only have credential provider options.
cfg.clearAssumeRoleOptions() cfg.clearAssumeRoleOptions()
} else { } else {
// First time a profile has been seen, It must either be a assume role // First time a profile has been seen. Assert if the credential type
// credentials, or SSO. Assert if the credential type requires a role ARN, // requires a role ARN, the ARN is also set
// the ARN is also set, or validate that the SSO configuration is complete.
if err := cfg.validateCredentialsConfig(profile); err != nil { if err := cfg.validateCredentialsConfig(profile); err != nil {
return err return err
} }
} }
profiles[profile] = struct{}{} profiles[profile] = struct{}{}
if err := cfg.validateCredentialType(); err != nil { if err := cfg.validateCredentialType(); err != nil {
@ -308,6 +333,30 @@ func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile s
cfg.SourceProfile = srcCfg 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 return nil
} }
@ -363,6 +412,10 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
cfg.S3UsEast1RegionalEndpoint = sre cfg.S3UsEast1RegionalEndpoint = sre
} }
// AWS Single Sign-On (AWS SSO)
// SSO session options
updateString(&cfg.SSOSessionName, section, ssoSessionNameKey)
// AWS Single Sign-On (AWS SSO) // AWS Single Sign-On (AWS SSO)
updateString(&cfg.SSOAccountID, section, ssoAccountIDKey) updateString(&cfg.SSOAccountID, section, ssoAccountIDKey)
updateString(&cfg.SSORegion, section, ssoRegionKey) updateString(&cfg.SSORegion, section, ssoRegionKey)
@ -461,32 +514,20 @@ func (cfg *sharedConfig) validateCredentialType() error {
} }
func (cfg *sharedConfig) validateSSOConfiguration() error { func (cfg *sharedConfig) validateSSOConfiguration() error {
if !cfg.hasSSOConfiguration() { if cfg.hasSSOTokenProviderConfiguration() {
err := cfg.validateSSOTokenProviderConfiguration()
if err != nil {
return err
}
return nil return nil
} }
var missing []string if cfg.hasLegacySSOConfiguration() {
if len(cfg.SSOAccountID) == 0 { err := cfg.validateLegacySSOConfiguration()
missing = append(missing, ssoAccountIDKey) 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 return nil
} }
@ -525,15 +566,76 @@ func (cfg *sharedConfig) clearAssumeRoleOptions() {
} }
func (cfg *sharedConfig) hasSSOConfiguration() bool { func (cfg *sharedConfig) hasSSOConfiguration() bool {
switch { return cfg.hasSSOTokenProviderConfiguration() || cfg.hasLegacySSOConfiguration()
case len(cfg.SSOAccountID) != 0: }
case len(cfg.SSORegion) != 0:
case len(cfg.SSORoleName) != 0: func (c *sharedConfig) hasSSOTokenProviderConfiguration() bool {
case len(cfg.SSOStartURL) != 0: return len(c.SSOSessionName) > 0
default: }
return false
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 { func oneOrNone(bs ...bool) bool {

View file

@ -3,12 +3,12 @@
// Provides request signing for request that need to be signed with // Provides request signing for request that need to be signed with
// AWS V4 Signatures. // AWS V4 Signatures.
// //
// Standalone Signer // # Standalone Signer
// //
// Generally using the signer outside of the SDK should not require any additional // 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 // 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 // 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. // to the service as.
// //
// The signer will first check the URL.Opaque field, and use its value if set. // The signer will first check the URL.Opaque field, and use its value if set.
@ -695,7 +695,8 @@ func (ctx *signingCtx) buildBodyDigest() error {
includeSHA256Header := ctx.unsignedPayload || includeSHA256Header := ctx.unsignedPayload ||
ctx.ServiceName == "s3" || ctx.ServiceName == "s3" ||
ctx.ServiceName == "s3-object-lambda" || ctx.ServiceName == "s3-object-lambda" ||
ctx.ServiceName == "glacier" ctx.ServiceName == "glacier" ||
ctx.ServiceName == "s3-outposts"
s3Presign := ctx.isPresign && s3Presign := ctx.isPresign &&
(ctx.ServiceName == "s3" || (ctx.ServiceName == "s3" ||

View file

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // 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 package shareddefaults
import ( import (
"os" "os/user"
"path/filepath" "path/filepath"
"runtime"
) )
// SharedCredentialsFilename returns the SDK's default file path // 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 // UserHomeDir returns the home directory for the user the process is
// running under. // running under.
func UserHomeDir() string { func UserHomeDir() string {
if runtime.GOOS == "windows" { // Windows var home string
return os.Getenv("USERPROFILE")
home = userHomeDir()
if len(home) > 0 {
return home
} }
// *nix currUser, _ := user.Current()
return os.Getenv("HOME") 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" 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) { func ApplyHTTPTransportFixes(r *request.Request) {
} }

View file

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

View file

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"math"
"math/big" "math/big"
"reflect" "reflect"
"strings" "strings"
@ -258,6 +259,18 @@ func (u unmarshaler) unmarshalScalar(value reflect.Value, data interface{}, tag
return err return err
} }
value.Set(reflect.ValueOf(v)) 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: default:
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
} }

View file

@ -13,10 +13,17 @@ import (
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" "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 // UnmarshalTypedError provides unmarshaling errors API response errors
// for both typed and untyped errors. // for both typed and untyped errors.
type UnmarshalTypedError struct { 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 // NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
@ -24,6 +31,28 @@ type UnmarshalTypedError struct {
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError { func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
return &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] code := codeParts[len(codeParts)-1]
msg := jsonErr.Message msg := jsonErr.Message
queryCodeParts := queryCodeParts(resp, u)
if fn, ok := u.exceptions[code]; ok { 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. // 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) err := jsonutil.UnmarshalJSONCaseInsensitive(v, body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return v, nil return v, nil
} }
if len(queryCodeParts) == awsQueryErrorPartsCount && len(u.queryExceptions) > 0 {
code = queryCodeParts[0]
}
// fallback to unmodeled generic exceptions // fallback to unmodeled generic exceptions
return awserr.NewRequestFailure( return awserr.NewRequestFailure(
awserr.New(code, msg, nil), awserr.New(code, msg, nil),
@ -70,6 +113,16 @@ func (u *UnmarshalTypedError) UnmarshalError(
), nil ), 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 // UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc
// protocol request errors // protocol request errors
var UnmarshalErrorHandler = request.NamedHandler{ var UnmarshalErrorHandler = request.NamedHandler{

View file

@ -3,6 +3,7 @@ package queryutil
import ( import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"math"
"net/url" "net/url"
"reflect" "reflect"
"sort" "sort"
@ -13,6 +14,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol" "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 // Parse parses an object i and fills a url.Values object. The isEC2 flag
// indicates if this is the EC2 Query sub-protocol. // indicates if this is the EC2 Query sub-protocol.
func Parse(body url.Values, i interface{}, isEC2 bool) error { 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: case int:
v.Set(name, strconv.Itoa(value)) v.Set(name, strconv.Itoa(value))
case float64: 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: 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: case time.Time:
const ISO8601UTC = "2006-01-02T15:04:05Z" const ISO8601UTC = "2006-01-02T15:04:05Z"
format := tag.Get("timestampFormat") format := tag.Get("timestampFormat")

View file

@ -3,6 +3,7 @@ package query
import ( import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
@ -62,7 +63,7 @@ func UnmarshalError(r *request.Request) {
} }
r.Error = awserr.NewRequestFailure( 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, r.HTTPResponse.StatusCode,
reqID, reqID,
) )

View file

@ -6,6 +6,7 @@ import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"io" "io"
"math"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
@ -20,6 +21,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol" "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 // Whether the byte value can be sent without escaping in AWS URLs
var noEscape [256]bool 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)) value = base64.StdEncoding.EncodeToString([]byte(value))
} }
str = 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: case []byte:
str = base64.StdEncoding.EncodeToString(value) str = base64.StdEncoding.EncodeToString(value)
case bool: case bool:
@ -283,7 +313,16 @@ func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error)
case int64: case int64:
str = strconv.FormatInt(value, 10) str = strconv.FormatInt(value, 10)
case float64: case float64:
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) str = strconv.FormatFloat(value, 'f', -1, 64)
}
case time.Time: case time.Time:
format := tag.Get("timestampFormat") format := tag.Get("timestampFormat")
if len(format) == 0 { if len(format) == 0 {

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math"
"net/http" "net/http"
"reflect" "reflect"
"strconv" "strconv"
@ -231,10 +232,21 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro
} }
v.Set(reflect.ValueOf(&i)) v.Set(reflect.ValueOf(&i))
case *float64: case *float64:
f, err := strconv.ParseFloat(header, 64) 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 { if err != nil {
return err return err
} }
}
v.Set(reflect.ValueOf(&f)) v.Set(reflect.ValueOf(&f))
case *time.Time: case *time.Time:
format := tag.Get("timestampFormat") format := tag.Get("timestampFormat")

View file

@ -2,6 +2,7 @@ package restjson
import ( import (
"bytes" "bytes"
"encoding/json"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -40,36 +41,22 @@ func (u *UnmarshalTypedError) UnmarshalError(
resp *http.Response, resp *http.Response,
respMeta protocol.ResponseMetadata, respMeta protocol.ResponseMetadata,
) (error, error) { ) (error, error) {
code, msg, err := unmarshalErrorInfo(resp)
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 { if err != nil {
return nil, err return nil, err
} }
body = ioutil.NopCloser(&buf) fn, ok := u.exceptions[code]
code = jsonErr.Code if !ok {
msg = jsonErr.Message return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
} }
// 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) v := fn(respMeta)
if err := jsonutil.UnmarshalJSONCaseInsensitive(v, body); err != nil { if err := jsonutil.UnmarshalJSONCaseInsensitive(v, resp.Body); err != nil {
return nil, err return nil, err
} }
@ -78,14 +65,6 @@ func (u *UnmarshalTypedError) UnmarshalError(
} }
return v, nil return v, nil
}
// fallback to unmodeled generic exceptions
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
} }
// UnmarshalErrorHandler is a named request handler for unmarshaling restjson // UnmarshalErrorHandler is a named request handler for unmarshaling restjson
@ -99,36 +78,80 @@ var UnmarshalErrorHandler = request.NamedHandler{
func UnmarshalError(r *request.Request) { func UnmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse code, msg, err := unmarshalErrorInfo(r.HTTPResponse)
err := jsonutil.UnmarshalJSONError(&jsonErr, r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization, awserr.New(request.ErrCodeSerialization, "failed to unmarshal response error", err),
"failed to unmarshal response error", err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )
return 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( r.Error = awserr.NewRequestFailure(
awserr.New(code, jsonErr.Message, nil), awserr.New(code, msg, nil),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )
} }
type jsonErrorResponse struct { type jsonErrorResponse struct {
Type string `json:"__type"`
Code string `json:"code"` Code string `json:"code"`
Message string `json:"message"` 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/base64"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"math"
"reflect" "reflect"
"sort" "sort"
"strconv" "strconv"
@ -14,6 +15,12 @@ import (
"github.com/aws/aws-sdk-go/private/protocol" "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 // BuildXML will serialize params into an xml.Encoder. Error will be returned
// if the serialization of any of the params or nested values fails. // if the serialization of any of the params or nested values fails.
func BuildXML(params interface{}, e *xml.Encoder) error { 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. // Error will be returned if the value type is unsupported.
func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
var str string var str string
switch converted := value.Interface().(type) { switch converted := value.Interface().(type) {
case string: case string:
str = converted str = converted
@ -289,9 +297,29 @@ func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag refl
case int: case int:
str = strconv.Itoa(converted) str = strconv.Itoa(converted)
case float64: case float64:
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) str = strconv.FormatFloat(converted, 'f', -1, 64)
}
case float32: 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: case time.Time:
format := tag.Get("timestampFormat") format := tag.Get("timestampFormat")
if len(format) == 0 { if len(format) == 0 {

View file

@ -6,6 +6,7 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"math"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
@ -276,10 +277,21 @@ func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
} }
r.Set(reflect.ValueOf(&v)) r.Set(reflect.ValueOf(&v))
case *float64: case *float64:
v, err := strconv.ParseFloat(node.Text, 64) 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 { if err != nil {
return err return err
} }
}
r.Set(reflect.ValueOf(&v)) r.Set(reflect.ValueOf(&v))
case *time.Time: case *time.Time:
format := tag.Get("timestampFormat") format := tag.Get("timestampFormat")

View file

@ -81,6 +81,7 @@ func NewCookieSigner(keyID string, privKey *rsa.PrivateKey, opts ...func(*Cookie
// server's response. // server's response.
// //
// Example: // Example:
//
// s := sign.NewCookieSigner(keyID, privKey) // s := sign.NewCookieSigner(keyID, privKey)
// //
// // Get Signed cookies for a resource that will expire in 1 hour // // Get Signed cookies for a resource that will expire in 1 hour
@ -150,6 +151,7 @@ func cookieURLScheme(u string) (string, error) {
// server's response. // server's response.
// //
// Example: // Example:
//
// s := sign.NewCookieSigner(keyID, privKey) // s := sign.NewCookieSigner(keyID, privKey)
// //
// policy := &sign.Policy{ // policy := &sign.Policy{

View file

@ -15,7 +15,6 @@
// if err != nil { // if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error()) // log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// } // }
//
package sign package sign
import ( import (
@ -60,7 +59,6 @@ func NewURLSigner(keyID string, privKey *rsa.PrivateKey) *URLSigner {
// if err != nil { // if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error()) // log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// } // }
//
func (s URLSigner) Sign(url string, expires time.Time) (string, error) { func (s URLSigner) Sign(url string, expires time.Time) (string, error) {
scheme, cleanedURL, err := cleanURLScheme(url) scheme, cleanedURL, err := cleanURLScheme(url)
if err != nil { if err != nil {
@ -110,7 +108,6 @@ func (s URLSigner) Sign(url string, expires time.Time) (string, error) {
// if err != nil { // if err != nil {
// log.Fatalf("Failed to sign url, err: %s\n", err.Error()) // log.Fatalf("Failed to sign url, err: %s\n", err.Error())
// } // }
//
func (s URLSigner) SignWithPolicy(url string, p *Policy) (string, error) { func (s URLSigner) SignWithPolicy(url string, p *Policy) (string, error) {
scheme, cleanedURL, err := cleanURLScheme(url) scheme, cleanedURL, err := cleanURLScheme(url)
if err != nil { if err != nil {

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@
// See s3 package documentation for more information. // See s3 package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ // 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 // 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. // a new service client. With that client you can make API requests to the service.

View file

@ -31,7 +31,7 @@
// See the s3manager package's Uploader type documentation for more information. // See the s3manager package's Uploader type documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Uploader // 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 // The s3manager package's Downloader provides concurrently downloading of Objects
// from S3. The Downloader will write S3 Object content with an io.WriterAt. // from S3. The Downloader will write S3 Object content with an io.WriterAt.
@ -63,7 +63,7 @@
// See the s3manager package's Downloader type documentation for more information. // See the s3manager package's Downloader type documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Downloader // 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) // Interacting with objects whose keys contain adjacent slashes (e.g. bucketname/foo//bar/objectname)
// requires setting DisableRestProtocolURICleaning to true in the aws.Config struct // requires setting DisableRestProtocolURICleaning to true in the aws.Config struct
@ -77,7 +77,7 @@
// Key: aws.String("//foo//bar//moo"), // 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 // 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 // hint to determine which AWS partition to perform the query on. Use this utility
@ -98,7 +98,7 @@
// See the s3manager package's GetBucketRegion function documentation for more information // See the s3manager package's GetBucketRegion function documentation for more information
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#GetBucketRegion // 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 // The s3crypto package provides the tools to upload and download encrypted
// content from S3. The Encryption and Decryption clients can be used concurrently // content from S3. The Encryption and Decryption clients can be used concurrently
@ -106,5 +106,4 @@
// //
// See the s3crypto package documentation for more information. // See the s3crypto package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3crypto/ // https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3crypto/
//
package s3 package s3

View file

@ -54,7 +54,6 @@ func accessPointResourceParser(a awsarn.ARN) (arn.Resource, error) {
// Supported Outpost AccessPoint ARN format: // Supported Outpost AccessPoint ARN format:
// - ARN format: arn:{partition}:s3-outposts:{region}:{accountId}:outpost/{outpostId}/accesspoint/{accesspointName} // - 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 // - example: arn:aws:s3-outposts:us-west-2:012345678901:outpost/op-1234567890123456/accesspoint/myaccesspoint
//
func parseOutpostAccessPointResource(a awsarn.ARN, resParts []string) (arn.OutpostAccessPointARN, error) { func parseOutpostAccessPointResource(a awsarn.ARN, resParts []string) (arn.OutpostAccessPointARN, error) {
// outpost accesspoint arn is only valid if service is s3-outposts // outpost accesspoint arn is only valid if service is s3-outposts
if a.Service != "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 // - example : myaccesspoint-012345678901.s3-accesspoint.us-west-2.amazonaws.com
// //
// Access Point Endpoint requests are signed using "s3" as signing name. // Access Point Endpoint requests are signed using "s3" as signing name.
//
func (a accessPointEndpointBuilder) build(req *request.Request) error { func (a accessPointEndpointBuilder) build(req *request.Request) error {
resolveService := arn.AccessPointARN(a).Service resolveService := arn.AccessPointARN(a).Service
resolveRegion := arn.AccessPointARN(a).Region resolveRegion := arn.AccessPointARN(a).Region
@ -92,7 +91,6 @@ type s3ObjectLambdaAccessPointEndpointBuilder arn.S3ObjectLambdaAccessPointARN
// - example : myaccesspoint-012345678901.s3-object-lambda.us-west-2.amazonaws.com // - example : myaccesspoint-012345678901.s3-object-lambda.us-west-2.amazonaws.com
// //
// Access Point Endpoint requests are signed using "s3-object-lambda" as signing name. // Access Point Endpoint requests are signed using "s3-object-lambda" as signing name.
//
func (a s3ObjectLambdaAccessPointEndpointBuilder) build(req *request.Request) error { func (a s3ObjectLambdaAccessPointEndpointBuilder) build(req *request.Request) error {
resolveRegion := arn.S3ObjectLambdaAccessPointARN(a).Region 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 // - example : myaccesspoint-012345678901.op-01234567890123456.s3-outposts.us-west-2.amazonaws.com
// //
// Outpost AccessPoint Endpoint request are signed using "s3-outposts" as signing name. // Outpost AccessPoint Endpoint request are signed using "s3-outposts" as signing name.
//
func (o outpostAccessPointEndpointBuilder) build(req *request.Request) error { func (o outpostAccessPointEndpointBuilder) build(req *request.Request) error {
resolveRegion := o.Region resolveRegion := o.Region
resolveService := o.Service resolveService := o.Service

View file

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

View file

@ -39,6 +39,7 @@ const (
// aws.Config parameter to add your extra config. // aws.Config parameter to add your extra config.
// //
// Example: // Example:
//
// mySession := session.Must(session.NewSession()) // mySession := session.Must(session.NewSession())
// //
// // Create a S3 client from just a session. // // Create a S3 client from just a session.

View file

@ -29,7 +29,6 @@ const opGetRoleCredentials = "GetRoleCredentials"
// This method is useful when you want to inject custom logic or configuration // 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. // into the SDK's request lifecycle. Such as custom headers, or retry logic.
// //
//
// // Example sending a request using the GetRoleCredentialsRequest method. // // Example sending a request using the GetRoleCredentialsRequest method.
// req, resp := client.GetRoleCredentialsRequest(params) // req, resp := client.GetRoleCredentialsRequest(params)
// //
@ -69,19 +68,20 @@ func (c *SSO) GetRoleCredentialsRequest(input *GetRoleCredentialsInput) (req *re
// API operation GetRoleCredentials for usage and error information. // API operation GetRoleCredentials for usage and error information.
// //
// Returned Error Types: // Returned Error Types:
// * InvalidRequestException //
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example, // Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range. // a required parameter might be missing or out of range.
// //
// * UnauthorizedException // - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid // Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request. // access token in the request.
// //
// * TooManyRequestsException // - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than // Indicates that the request is being made too frequently and is more than
// what the server can handle. // what the server can handle.
// //
// * ResourceNotFoundException // - ResourceNotFoundException
// The specified resource doesn't exist. // The specified resource doesn't exist.
// //
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/GetRoleCredentials // See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/GetRoleCredentials
@ -122,7 +122,6 @@ const opListAccountRoles = "ListAccountRoles"
// This method is useful when you want to inject custom logic or configuration // 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. // into the SDK's request lifecycle. Such as custom headers, or retry logic.
// //
//
// // Example sending a request using the ListAccountRolesRequest method. // // Example sending a request using the ListAccountRolesRequest method.
// req, resp := client.ListAccountRolesRequest(params) // req, resp := client.ListAccountRolesRequest(params)
// //
@ -167,19 +166,20 @@ func (c *SSO) ListAccountRolesRequest(input *ListAccountRolesInput) (req *reques
// API operation ListAccountRoles for usage and error information. // API operation ListAccountRoles for usage and error information.
// //
// Returned Error Types: // Returned Error Types:
// * InvalidRequestException //
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example, // Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range. // a required parameter might be missing or out of range.
// //
// * UnauthorizedException // - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid // Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request. // access token in the request.
// //
// * TooManyRequestsException // - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than // Indicates that the request is being made too frequently and is more than
// what the server can handle. // what the server can handle.
// //
// * ResourceNotFoundException // - ResourceNotFoundException
// The specified resource doesn't exist. // The specified resource doesn't exist.
// //
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccountRoles // See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccountRoles
@ -220,7 +220,6 @@ func (c *SSO) ListAccountRolesWithContext(ctx aws.Context, input *ListAccountRol
// fmt.Println(page) // fmt.Println(page)
// return pageNum <= 3 // return pageNum <= 3
// }) // })
//
func (c *SSO) ListAccountRolesPages(input *ListAccountRolesInput, fn func(*ListAccountRolesOutput, bool) bool) error { func (c *SSO) ListAccountRolesPages(input *ListAccountRolesInput, fn func(*ListAccountRolesOutput, bool) bool) error {
return c.ListAccountRolesPagesWithContext(aws.BackgroundContext(), input, fn) return c.ListAccountRolesPagesWithContext(aws.BackgroundContext(), input, fn)
} }
@ -272,7 +271,6 @@ const opListAccounts = "ListAccounts"
// This method is useful when you want to inject custom logic or configuration // 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. // into the SDK's request lifecycle. Such as custom headers, or retry logic.
// //
//
// // Example sending a request using the ListAccountsRequest method. // // Example sending a request using the ListAccountsRequest method.
// req, resp := client.ListAccountsRequest(params) // req, resp := client.ListAccountsRequest(params)
// //
@ -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 // 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 // by the administrator of the account. For more information, see Assign User
// Access (https://docs.aws.amazon.com/singlesignon/latest/userguide/useraccess.html#assignusers) // 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 // 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 // with awserr.Error's Code and Message methods to get detailed information about
@ -320,19 +319,20 @@ func (c *SSO) ListAccountsRequest(input *ListAccountsInput) (req *request.Reques
// API operation ListAccounts for usage and error information. // API operation ListAccounts for usage and error information.
// //
// Returned Error Types: // Returned Error Types:
// * InvalidRequestException //
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example, // Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range. // a required parameter might be missing or out of range.
// //
// * UnauthorizedException // - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid // Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request. // access token in the request.
// //
// * TooManyRequestsException // - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than // Indicates that the request is being made too frequently and is more than
// what the server can handle. // what the server can handle.
// //
// * ResourceNotFoundException // - ResourceNotFoundException
// The specified resource doesn't exist. // The specified resource doesn't exist.
// //
// See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccounts // See also, https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10/ListAccounts
@ -373,7 +373,6 @@ func (c *SSO) ListAccountsWithContext(ctx aws.Context, input *ListAccountsInput,
// fmt.Println(page) // fmt.Println(page)
// return pageNum <= 3 // return pageNum <= 3
// }) // })
//
func (c *SSO) ListAccountsPages(input *ListAccountsInput, fn func(*ListAccountsOutput, bool) bool) error { func (c *SSO) ListAccountsPages(input *ListAccountsInput, fn func(*ListAccountsOutput, bool) bool) error {
return c.ListAccountsPagesWithContext(aws.BackgroundContext(), input, fn) return c.ListAccountsPagesWithContext(aws.BackgroundContext(), input, fn)
} }
@ -425,7 +424,6 @@ const opLogout = "Logout"
// This method is useful when you want to inject custom logic or configuration // 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. // into the SDK's request lifecycle. Such as custom headers, or retry logic.
// //
//
// // Example sending a request using the LogoutRequest method. // // Example sending a request using the LogoutRequest method.
// req, resp := client.LogoutRequest(params) // req, resp := client.LogoutRequest(params)
// //
@ -455,7 +453,21 @@ func (c *SSO) LogoutRequest(input *LogoutInput) (req *request.Request, output *L
// Logout API operation for AWS Single Sign-On. // 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 // 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 // with awserr.Error's Code and Message methods to get detailed information about
@ -465,15 +477,16 @@ func (c *SSO) LogoutRequest(input *LogoutInput) (req *request.Request, output *L
// API operation Logout for usage and error information. // API operation Logout for usage and error information.
// //
// Returned Error Types: // Returned Error Types:
// * InvalidRequestException //
// - InvalidRequestException
// Indicates that a problem occurred with the input to the request. For example, // Indicates that a problem occurred with the input to the request. For example,
// a required parameter might be missing or out of range. // a required parameter might be missing or out of range.
// //
// * UnauthorizedException // - UnauthorizedException
// Indicates that the request is not authorized. This can happen due to an invalid // Indicates that the request is not authorized. This can happen due to an invalid
// access token in the request. // access token in the request.
// //
// * TooManyRequestsException // - TooManyRequestsException
// Indicates that the request is being made too frequently and is more than // Indicates that the request is being made too frequently and is more than
// what the server can handle. // what the server can handle.
// //
@ -554,7 +567,7 @@ type GetRoleCredentialsInput struct {
// The token issued by the CreateToken API call. For more information, see CreateToken // The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html) // (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 // AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by GetRoleCredentialsInput's // 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 // The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html) // (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 // AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by ListAccountRolesInput's // 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 // The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html) // (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 // AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by ListAccountsInput's // 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 // The token issued by the CreateToken API call. For more information, see CreateToken
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html) // (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 // AccessToken is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by LogoutInput's // 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 // Package sso provides the client and types for making API
// requests to AWS Single Sign-On. // requests to AWS Single Sign-On.
// //
// AWS Single Sign-On Portal is a web service that makes it easy for you to // AWS IAM Identity Center (successor to AWS Single Sign-On) Portal is a web
// assign user access to AWS SSO resources such as the user portal. Users can // service that makes it easy for you to assign user access to IAM Identity
// get AWS account applications and roles assigned to them and get federated // Center resources such as the AWS access portal. Users can get AWS account
// into the application. // 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) // Although AWS Single Sign-On was renamed, the sso and identitystore API namespaces
// in the AWS SSO User Guide. // 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 // This reference guide describes the IAM Identity Center Portal operations
// can call programatically and includes detailed information on data types // that you can call programatically and includes detailed information on data
// and errors. // types and errors.
// //
// AWS provides SDKs that consist of libraries and sample code for various programming // 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 // 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 // provide a convenient way to create programmatic access to IAM Identity Center
// AWS services. For more information about the AWS SDKs, including how to download // and other AWS services. For more information about the AWS SDKs, including
// and install them, see Tools for Amazon Web Services (http://aws.amazon.com/tools/). // 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 https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10 for more information on this service.
// //
// See sso package documentation for more information. // See sso package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/sso/ // 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 // 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. // a new service client. With that client you can make API requests to the service.

View file

@ -40,6 +40,7 @@ const (
// aws.Config parameter to add your extra config. // aws.Config parameter to add your extra config.
// //
// Example: // Example:
//
// mySession := session.Must(session.NewSession()) // mySession := session.Must(session.NewSession())
// //
// // Create a SSO client from just a session. // // Create a SSO client from just a session.

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. // requests to AWS Security Token Service.
// //
// Security Token Service (STS) enables you to request temporary, limited-privilege // Security Token Service (STS) enables you to request temporary, limited-privilege
// credentials for Identity and Access Management (IAM) users or for users that // credentials for users. This guide provides descriptions of the STS API. For
// you authenticate (federated users). This guide provides descriptions of the // more information about using this service, see Temporary Security Credentials
// STS API. For more information about using this service, see Temporary Security // (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
// 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 https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service.
// //
// See sts package documentation for more information. // See sts package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/ // 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 // 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. // a new service client. With that client you can make API requests to the service.

View file

@ -39,6 +39,7 @@ const (
// aws.Config parameter to add your extra config. // aws.Config parameter to add your extra config.
// //
// Example: // Example:
//
// mySession := session.Must(session.NewSession()) // mySession := session.Must(session.NewSession())
// //
// // Create a STS client from just a session. // // Create a STS client from just a session.

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 # github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d
## explicit ## explicit
github.com/Shopify/logrus-bugsnag 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 ## explicit; go 1.11
github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws
github.com/aws/aws-sdk-go/aws/arn 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/awserr
github.com/aws/aws-sdk-go/aws/awsutil github.com/aws/aws-sdk-go/aws/awsutil
github.com/aws/aws-sdk-go/aws/client 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/s3
github.com/aws/aws-sdk-go/service/sso github.com/aws/aws-sdk-go/service/sso
github.com/aws/aws-sdk-go/service/sso/ssoiface 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
github.com/aws/aws-sdk-go/service/sts/stsiface github.com/aws/aws-sdk-go/service/sts/stsiface
# github.com/beorn7/perks v1.0.1 # github.com/beorn7/perks v1.0.1