diff options
Diffstat (limited to 'vendor/github.com/goamz/goamz/sts')
-rw-r--r-- | vendor/github.com/goamz/goamz/sts/responses_test.go | 84 | ||||
-rw-r--r-- | vendor/github.com/goamz/goamz/sts/sts.go | 273 | ||||
-rw-r--r-- | vendor/github.com/goamz/goamz/sts/sts_test.go | 151 |
3 files changed, 508 insertions, 0 deletions
diff --git a/vendor/github.com/goamz/goamz/sts/responses_test.go b/vendor/github.com/goamz/goamz/sts/responses_test.go new file mode 100644 index 000000000..b25f495e2 --- /dev/null +++ b/vendor/github.com/goamz/goamz/sts/responses_test.go @@ -0,0 +1,84 @@ +package sts_test + +var AssumeRoleResponse = ` +<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/ +2011-06-15/"> + <AssumeRoleResult> + <Credentials> + <SessionToken> + AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQW + LWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGd + QrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU + 9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz + +scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== + </SessionToken> + <SecretAccessKey> + wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY + </SecretAccessKey> + <Expiration>2011-07-15T23:28:33.359Z</Expiration> + <AccessKeyId>AKIAIOSFODNN7EXAMPLE</AccessKeyId> + </Credentials> + <AssumedRoleUser> + <Arn>arn:aws:sts::123456789012:assumed-role/demo/Bob</Arn> + <AssumedRoleId>ARO123EXAMPLE123:Bob</AssumedRoleId> + </AssumedRoleUser> + <PackedPolicySize>6</PackedPolicySize> + </AssumeRoleResult> + <ResponseMetadata> + <RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId> + </ResponseMetadata> +</AssumeRoleResponse> +` + +var GetFederationTokenResponse = ` +<GetFederationTokenResponse xmlns="https://sts.amazonaws.com/doc/ +2011-06-15/"> + <GetFederationTokenResult> + <Credentials> + <SessionToken> + AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQW + LWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGd + QrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU + 9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz + +scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== + </SessionToken> + <SecretAccessKey> + wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY + </SecretAccessKey> + <Expiration>2011-07-15T23:28:33.359Z</Expiration> + <AccessKeyId>AKIAIOSFODNN7EXAMPLE</AccessKeyId> + </Credentials> + <FederatedUser> + <Arn>arn:aws:sts::123456789012:federated-user/Bob</Arn> + <FederatedUserId>123456789012:Bob</FederatedUserId> + </FederatedUser> + <PackedPolicySize>6</PackedPolicySize> + </GetFederationTokenResult> + <ResponseMetadata> + <RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId> + </ResponseMetadata> +</GetFederationTokenResponse> +` + +var GetSessionTokenResponse = ` +<GetSessionTokenResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/"> + <GetSessionTokenResult> + <Credentials> + <SessionToken> + AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/L + To6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3z + rkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtp + Z3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE + </SessionToken> + <SecretAccessKey> + wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY + </SecretAccessKey> + <Expiration>2011-07-11T19:55:29.611Z</Expiration> + <AccessKeyId>AKIAIOSFODNN7EXAMPLE</AccessKeyId> + </Credentials> + </GetSessionTokenResult> + <ResponseMetadata> + <RequestId>58c5dbae-abef-11e0-8cfe-09039844ac7d</RequestId> + </ResponseMetadata> +</GetSessionTokenResponse> +` diff --git a/vendor/github.com/goamz/goamz/sts/sts.go b/vendor/github.com/goamz/goamz/sts/sts.go new file mode 100644 index 000000000..973969223 --- /dev/null +++ b/vendor/github.com/goamz/goamz/sts/sts.go @@ -0,0 +1,273 @@ +// +// sts: This package provides types and functions to interact with the AWS STS API +// +// Depends on https://github.com/goamz/goamz +// + +package sts + +import ( + "encoding/xml" + "fmt" + "log" + "net/http" + "net/http/httputil" + "net/url" + "strconv" + "strings" + "time" + + "github.com/goamz/goamz/aws" +) + +// The STS type encapsulates operations within a specific EC2 region. +type STS struct { + aws.Auth + aws.Region + private byte // Reserve the right of using private data. +} + +// New creates a new STS Client. +// We can only use us-east for region because AWS.. +func New(auth aws.Auth, region aws.Region) *STS { + // Make sure we can run the package tests + if region.Name == "" { + return &STS{auth, region, 0} + } + return &STS{auth, aws.Regions["us-east-1"], 0} +} + +const debug = false + +// ---------------------------------------------------------------------------- +// Request dispatching logic. + +// Error encapsulates an error returned by the AWS STS API. +// +// See http://goo.gl/zDZbuQ for more details. +type Error struct { + // HTTP status code (200, 403, ...) + StatusCode int + // STS error code + Code string + // The human-oriented error message + Message string + RequestId string `xml:"RequestID"` +} + +func (err *Error) Error() string { + if err.Code == "" { + return err.Message + } + + return fmt.Sprintf("%s (%s)", err.Message, err.Code) +} + +type xmlErrors struct { + RequestId string `xml:"RequestId"` + Errors []Error `xml:"Error"` +} + +func (sts *STS) query(params map[string]string, resp interface{}) error { + params["Version"] = "2011-06-15" + + data := strings.NewReader(multimap(params).Encode()) + + hreq, err := http.NewRequest("POST", sts.Region.STSEndpoint+"/", data) + if err != nil { + return err + } + + hreq.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") + + token := sts.Auth.Token() + if token != "" { + hreq.Header.Set("X-Amz-Security-Token", token) + } + + signer := aws.NewV4Signer(sts.Auth, "sts", sts.Region) + signer.Sign(hreq) + + if debug { + log.Printf("%v -> {\n", hreq) + } + r, err := http.DefaultClient.Do(hreq) + + if err != nil { + log.Printf("Error calling Amazon") + return err + } + + defer r.Body.Close() + + if debug { + dump, _ := httputil.DumpResponse(r, true) + log.Printf("response:\n") + log.Printf("%v\n}\n", string(dump)) + } + if r.StatusCode != 200 { + return buildError(r) + } + err = xml.NewDecoder(r.Body).Decode(resp) + return err +} + +func buildError(r *http.Response) error { + var ( + err Error + errors xmlErrors + ) + xml.NewDecoder(r.Body).Decode(&errors) + if len(errors.Errors) > 0 { + err = errors.Errors[0] + } + + err.RequestId = errors.RequestId + err.StatusCode = r.StatusCode + if err.Message == "" { + err.Message = r.Status + } + return &err +} + +func makeParams(action string) map[string]string { + params := make(map[string]string) + params["Action"] = action + return params +} + +func multimap(p map[string]string) url.Values { + q := make(url.Values, len(p)) + for k, v := range p { + q[k] = []string{v} + } + return q +} + +// options for the AssumeRole function +// +// See http://goo.gl/Ld6Dbk for details +type AssumeRoleParams struct { + DurationSeconds int + ExternalId string + Policy string + RoleArn string + RoleSessionName string +} + +type AssumedRoleUser struct { + Arn string `xml:"Arn"` + AssumedRoleId string `xml:"AssumedRoleId"` +} + +type Credentials struct { + AccessKeyId string `xml:"AccessKeyId"` + Expiration time.Time `xml:"Expiration"` + SecretAccessKey string `xml:"SecretAccessKey"` + SessionToken string `xml:"SessionToken"` +} + +type AssumeRoleResult struct { + AssumedRoleUser AssumedRoleUser `xml:"AssumeRoleResult>AssumedRoleUser"` + Credentials Credentials `xml:"AssumeRoleResult>Credentials"` + PackedPolicySize int `xml:"AssumeRoleResult>PackedPolicySize"` + RequestId string `xml:"ResponseMetadata>RequestId"` +} + +// AssumeRole assumes the specified role +// +// See http://goo.gl/zDZbuQ for more details. +func (sts *STS) AssumeRole(options *AssumeRoleParams) (resp *AssumeRoleResult, err error) { + params := makeParams("AssumeRole") + + params["RoleArn"] = options.RoleArn + params["RoleSessionName"] = options.RoleSessionName + + if options.DurationSeconds != 0 { + params["DurationSeconds"] = strconv.Itoa(options.DurationSeconds) + } + if options.ExternalId != "" { + params["ExternalId"] = options.ExternalId + } + if options.Policy != "" { + params["Policy"] = options.Policy + } + + resp = new(AssumeRoleResult) + if err := sts.query(params, resp); err != nil { + return nil, err + } + return resp, nil +} + +// FederatedUser presents dentifiers for the federated user that is associated with the credentials. +// +// See http://goo.gl/uPtr7V for more details +type FederatedUser struct { + Arn string `xml:"Arn"` + FederatedUserId string `xml:"FederatedUserId"` +} + +// GetFederationToken wraps GetFederationToken response +// +// See http://goo.gl/Iujjeg for more details +type GetFederationTokenResult struct { + Credentials Credentials `xml:"GetFederationTokenResult>Credentials"` + FederatedUser FederatedUser `xml:"GetFederationTokenResult>FederatedUser"` + PackedPolicySize int `xml:"GetFederationTokenResult>PackedPolicySize"` + RequestId string `xml:"ResponseMetadata>RequestId"` +} + +// GetFederationToken returns a set of temporary credentials for an AWS account or IAM user +// +// See http://goo.gl/Iujjeg for more details +func (sts *STS) GetFederationToken(name, policy string, durationSeconds int) ( + resp *GetFederationTokenResult, err error) { + params := makeParams("GetFederationToken") + params["Name"] = name + + if durationSeconds != 0 { + params["DurationSeconds"] = strconv.Itoa(durationSeconds) + } + if policy != "" { + params["Policy"] = policy + } + + resp = new(GetFederationTokenResult) + if err := sts.query(params, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSessionToken wraps GetSessionToken response +// +// See http://goo.gl/v8s5Y for more details +type GetSessionTokenResult struct { + Credentials Credentials `xml:"GetSessionTokenResult>Credentials"` + RequestId string `xml:"ResponseMetadata>RequestId"` +} + +// GetSessionToken returns a set of temporary credentials for an AWS account or IAM user +// +// See http://goo.gl/v8s5Y for more details +func (sts *STS) GetSessionToken(durationSeconds int, serialnNumber, tokenCode string) ( + resp *GetSessionTokenResult, err error) { + params := makeParams("GetSessionToken") + + if durationSeconds != 0 { + params["DurationSeconds"] = strconv.Itoa(durationSeconds) + } + if serialnNumber != "" { + params["SerialNumber"] = serialnNumber + } + if tokenCode != "" { + params["TokenCode"] = tokenCode + } + + resp = new(GetSessionTokenResult) + if err := sts.query(params, resp); err != nil { + return nil, err + } + return resp, nil +} diff --git a/vendor/github.com/goamz/goamz/sts/sts_test.go b/vendor/github.com/goamz/goamz/sts/sts_test.go new file mode 100644 index 000000000..354c6272f --- /dev/null +++ b/vendor/github.com/goamz/goamz/sts/sts_test.go @@ -0,0 +1,151 @@ +package sts_test + +import ( + "testing" + "time" + + . "gopkg.in/check.v1" + + "github.com/goamz/goamz/aws" + "github.com/goamz/goamz/sts" + "github.com/goamz/goamz/testutil" +) + +func Test(t *testing.T) { + TestingT(t) +} + +var _ = Suite(&S{}) + +type S struct { + sts *sts.STS +} + +var testServer = testutil.NewHTTPServer() + +var mockTest bool + +func (s *S) SetUpSuite(c *C) { + testServer.Start() + auth := aws.Auth{AccessKey: "abc", SecretKey: "123"} + s.sts = sts.New(auth, aws.Region{STSEndpoint: testServer.URL}) +} + +func (s *S) TearDownTest(c *C) { + testServer.Flush() +} + +func (s *S) TestAssumeRole(c *C) { + testServer.Response(200, nil, AssumeRoleResponse) + request := &sts.AssumeRoleParams{ + DurationSeconds: 3600, + ExternalId: "123ABC", + Policy: `{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:*","Resource":"*"}]}`, + RoleArn: "arn:aws:iam::123456789012:role/demo", + RoleSessionName: "Bob", + } + resp, err := s.sts.AssumeRole(request) + c.Assert(err, IsNil) + values := testServer.WaitRequest().PostForm + // Post request test + c.Assert(values.Get("Version"), Equals, "2011-06-15") + c.Assert(values.Get("Action"), Equals, "AssumeRole") + c.Assert(values.Get("DurationSeconds"), Equals, "3600") + c.Assert(values.Get("ExternalId"), Equals, "123ABC") + c.Assert(values.Get("Policy"), Equals, `{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:*","Resource":"*"}]}`) + c.Assert(values.Get("RoleArn"), Equals, "arn:aws:iam::123456789012:role/demo") + c.Assert(values.Get("RoleSessionName"), Equals, "Bob") + // Response test + exp, _ := time.Parse(time.RFC3339, "2011-07-15T23:28:33.359Z") + c.Assert(resp.RequestId, Equals, "c6104cbe-af31-11e0-8154-cbc7ccf896c7") + c.Assert(resp.PackedPolicySize, Equals, 6) + c.Assert(resp.AssumedRoleUser, DeepEquals, sts.AssumedRoleUser{ + Arn: "arn:aws:sts::123456789012:assumed-role/demo/Bob", + AssumedRoleId: "ARO123EXAMPLE123:Bob", + }) + c.Assert(resp.Credentials, DeepEquals, sts.Credentials{ + SessionToken: ` + AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQW + LWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGd + QrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU + 9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz + +scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== + `, + SecretAccessKey: ` + wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY + `, + AccessKeyId: "AKIAIOSFODNN7EXAMPLE", + Expiration: exp, + }) + +} + +func (s *S) TestGetFederationToken(c *C) { + testServer.Response(200, nil, GetFederationTokenResponse) + resp, err := s.sts.GetFederationToken( + "Bob", + `{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:*","Resource":"*"}]}`, + 3600, + ) + c.Assert(err, IsNil) + values := testServer.WaitRequest().PostForm + // Post request test + c.Assert(values.Get("Version"), Equals, "2011-06-15") + c.Assert(values.Get("Action"), Equals, "GetFederationToken") + c.Assert(values.Get("DurationSeconds"), Equals, "3600") + c.Assert(values.Get("Policy"), Equals, `{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:*","Resource":"*"}]}`) + c.Assert(values.Get("Name"), Equals, "Bob") + // Response test + exp, _ := time.Parse(time.RFC3339, "2011-07-15T23:28:33.359Z") + c.Assert(resp.RequestId, Equals, "c6104cbe-af31-11e0-8154-cbc7ccf896c7") + c.Assert(resp.PackedPolicySize, Equals, 6) + c.Assert(resp.FederatedUser, DeepEquals, sts.FederatedUser{ + Arn: "arn:aws:sts::123456789012:federated-user/Bob", + FederatedUserId: "123456789012:Bob", + }) + c.Assert(resp.Credentials, DeepEquals, sts.Credentials{ + SessionToken: ` + AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQW + LWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGd + QrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU + 9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz + +scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== + `, + SecretAccessKey: ` + wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY + `, + AccessKeyId: "AKIAIOSFODNN7EXAMPLE", + Expiration: exp, + }) + +} + +func (s *S) TestGetSessionToken(c *C) { + testServer.Response(200, nil, GetSessionTokenResponse) + resp, err := s.sts.GetSessionToken(3600, "YourMFADeviceSerialNumber", "123456") + c.Assert(err, IsNil) + values := testServer.WaitRequest().PostForm + // Post request test + c.Assert(values.Get("Version"), Equals, "2011-06-15") + c.Assert(values.Get("Action"), Equals, "GetSessionToken") + c.Assert(values.Get("DurationSeconds"), Equals, "3600") + c.Assert(values.Get("SerialNumber"), Equals, "YourMFADeviceSerialNumber") + c.Assert(values.Get("TokenCode"), Equals, "123456") + // Response test + exp, _ := time.Parse(time.RFC3339, "2011-07-11T19:55:29.611Z") + c.Assert(resp.RequestId, Equals, "58c5dbae-abef-11e0-8cfe-09039844ac7d") + c.Assert(resp.Credentials, DeepEquals, sts.Credentials{ + SessionToken: ` + AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/L + To6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3z + rkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtp + Z3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE + `, + SecretAccessKey: ` + wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY + `, + AccessKeyId: "AKIAIOSFODNN7EXAMPLE", + Expiration: exp, + }) + +} |