diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go')
| -rw-r--r-- | vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go | 242 |
1 files changed, 0 insertions, 242 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go deleted file mode 100644 index 800c4a2..0000000 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go +++ /dev/null | |||
| @@ -1,242 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * MinIO Go Library for Amazon S3 Compatible Cloud Storage | ||
| 3 | * Copyright 2020 MinIO, Inc. | ||
| 4 | * | ||
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | * you may not use this file except in compliance with the License. | ||
| 7 | * You may obtain a copy of the License at | ||
| 8 | * | ||
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | * | ||
| 11 | * Unless required by applicable law or agreed to in writing, software | ||
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | * See the License for the specific language governing permissions and | ||
| 15 | * limitations under the License. | ||
| 16 | */ | ||
| 17 | |||
| 18 | package credentials | ||
| 19 | |||
| 20 | import ( | ||
| 21 | "bytes" | ||
| 22 | "crypto/sha256" | ||
| 23 | "encoding/hex" | ||
| 24 | "encoding/xml" | ||
| 25 | "errors" | ||
| 26 | "io" | ||
| 27 | "net/http" | ||
| 28 | "net/url" | ||
| 29 | "strconv" | ||
| 30 | "strings" | ||
| 31 | "time" | ||
| 32 | |||
| 33 | "github.com/minio/minio-go/v7/pkg/signer" | ||
| 34 | ) | ||
| 35 | |||
| 36 | // AssumeRoleResponse contains the result of successful AssumeRole request. | ||
| 37 | type AssumeRoleResponse struct { | ||
| 38 | XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleResponse" json:"-"` | ||
| 39 | |||
| 40 | Result AssumeRoleResult `xml:"AssumeRoleResult"` | ||
| 41 | ResponseMetadata struct { | ||
| 42 | RequestID string `xml:"RequestId,omitempty"` | ||
| 43 | } `xml:"ResponseMetadata,omitempty"` | ||
| 44 | } | ||
| 45 | |||
| 46 | // AssumeRoleResult - Contains the response to a successful AssumeRole | ||
| 47 | // request, including temporary credentials that can be used to make | ||
| 48 | // MinIO API requests. | ||
| 49 | type AssumeRoleResult struct { | ||
| 50 | // The identifiers for the temporary security credentials that the operation | ||
| 51 | // returns. | ||
| 52 | AssumedRoleUser AssumedRoleUser `xml:",omitempty"` | ||
| 53 | |||
| 54 | // The temporary security credentials, which include an access key ID, a secret | ||
| 55 | // access key, and a security (or session) token. | ||
| 56 | // | ||
| 57 | // Note: The size of the security token that STS APIs return is not fixed. We | ||
| 58 | // strongly recommend that you make no assumptions about the maximum size. As | ||
| 59 | // of this writing, the typical size is less than 4096 bytes, but that can vary. | ||
| 60 | // Also, future updates to AWS might require larger sizes. | ||
| 61 | Credentials struct { | ||
| 62 | AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"` | ||
| 63 | SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"` | ||
| 64 | Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"` | ||
| 65 | SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"` | ||
| 66 | } `xml:",omitempty"` | ||
| 67 | |||
| 68 | // A percentage value that indicates the size of the policy in packed form. | ||
| 69 | // The service rejects any policy with a packed size greater than 100 percent, | ||
| 70 | // which means the policy exceeded the allowed space. | ||
| 71 | PackedPolicySize int `xml:",omitempty"` | ||
| 72 | } | ||
| 73 | |||
| 74 | // A STSAssumeRole retrieves credentials from MinIO service, and keeps track if | ||
| 75 | // those credentials are expired. | ||
| 76 | type STSAssumeRole struct { | ||
| 77 | Expiry | ||
| 78 | |||
| 79 | // Required http Client to use when connecting to MinIO STS service. | ||
| 80 | Client *http.Client | ||
| 81 | |||
| 82 | // STS endpoint to fetch STS credentials. | ||
| 83 | STSEndpoint string | ||
| 84 | |||
| 85 | // various options for this request. | ||
| 86 | Options STSAssumeRoleOptions | ||
| 87 | } | ||
| 88 | |||
| 89 | // STSAssumeRoleOptions collection of various input options | ||
| 90 | // to obtain AssumeRole credentials. | ||
| 91 | type STSAssumeRoleOptions struct { | ||
| 92 | // Mandatory inputs. | ||
| 93 | AccessKey string | ||
| 94 | SecretKey string | ||
| 95 | |||
| 96 | SessionToken string // Optional if the first request is made with temporary credentials. | ||
| 97 | Policy string // Optional to assign a policy to the assumed role | ||
| 98 | |||
| 99 | Location string // Optional commonly needed with AWS STS. | ||
| 100 | DurationSeconds int // Optional defaults to 1 hour. | ||
| 101 | |||
| 102 | // Optional only valid if using with AWS STS | ||
| 103 | RoleARN string | ||
| 104 | RoleSessionName string | ||
| 105 | ExternalID string | ||
| 106 | } | ||
| 107 | |||
| 108 | // NewSTSAssumeRole returns a pointer to a new | ||
| 109 | // Credentials object wrapping the STSAssumeRole. | ||
| 110 | func NewSTSAssumeRole(stsEndpoint string, opts STSAssumeRoleOptions) (*Credentials, error) { | ||
| 111 | if stsEndpoint == "" { | ||
| 112 | return nil, errors.New("STS endpoint cannot be empty") | ||
| 113 | } | ||
| 114 | if opts.AccessKey == "" || opts.SecretKey == "" { | ||
| 115 | return nil, errors.New("AssumeRole credentials access/secretkey is mandatory") | ||
| 116 | } | ||
| 117 | return New(&STSAssumeRole{ | ||
| 118 | Client: &http.Client{ | ||
| 119 | Transport: http.DefaultTransport, | ||
| 120 | }, | ||
| 121 | STSEndpoint: stsEndpoint, | ||
| 122 | Options: opts, | ||
| 123 | }), nil | ||
| 124 | } | ||
| 125 | |||
| 126 | const defaultDurationSeconds = 3600 | ||
| 127 | |||
| 128 | // closeResponse close non nil response with any response Body. | ||
| 129 | // convenient wrapper to drain any remaining data on response body. | ||
| 130 | // | ||
| 131 | // Subsequently this allows golang http RoundTripper | ||
| 132 | // to re-use the same connection for future requests. | ||
| 133 | func closeResponse(resp *http.Response) { | ||
| 134 | // Callers should close resp.Body when done reading from it. | ||
| 135 | // If resp.Body is not closed, the Client's underlying RoundTripper | ||
| 136 | // (typically Transport) may not be able to re-use a persistent TCP | ||
| 137 | // connection to the server for a subsequent "keep-alive" request. | ||
| 138 | if resp != nil && resp.Body != nil { | ||
| 139 | // Drain any remaining Body and then close the connection. | ||
| 140 | // Without this closing connection would disallow re-using | ||
| 141 | // the same connection for future uses. | ||
| 142 | // - http://stackoverflow.com/a/17961593/4465767 | ||
| 143 | io.Copy(io.Discard, resp.Body) | ||
| 144 | resp.Body.Close() | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | func getAssumeRoleCredentials(clnt *http.Client, endpoint string, opts STSAssumeRoleOptions) (AssumeRoleResponse, error) { | ||
| 149 | v := url.Values{} | ||
| 150 | v.Set("Action", "AssumeRole") | ||
| 151 | v.Set("Version", STSVersion) | ||
| 152 | if opts.RoleARN != "" { | ||
| 153 | v.Set("RoleArn", opts.RoleARN) | ||
| 154 | } | ||
| 155 | if opts.RoleSessionName != "" { | ||
| 156 | v.Set("RoleSessionName", opts.RoleSessionName) | ||
| 157 | } | ||
| 158 | if opts.DurationSeconds > defaultDurationSeconds { | ||
| 159 | v.Set("DurationSeconds", strconv.Itoa(opts.DurationSeconds)) | ||
| 160 | } else { | ||
| 161 | v.Set("DurationSeconds", strconv.Itoa(defaultDurationSeconds)) | ||
| 162 | } | ||
| 163 | if opts.Policy != "" { | ||
| 164 | v.Set("Policy", opts.Policy) | ||
| 165 | } | ||
| 166 | if opts.ExternalID != "" { | ||
| 167 | v.Set("ExternalId", opts.ExternalID) | ||
| 168 | } | ||
| 169 | |||
| 170 | u, err := url.Parse(endpoint) | ||
| 171 | if err != nil { | ||
| 172 | return AssumeRoleResponse{}, err | ||
| 173 | } | ||
| 174 | u.Path = "/" | ||
| 175 | |||
| 176 | postBody := strings.NewReader(v.Encode()) | ||
| 177 | hash := sha256.New() | ||
| 178 | if _, err = io.Copy(hash, postBody); err != nil { | ||
| 179 | return AssumeRoleResponse{}, err | ||
| 180 | } | ||
| 181 | postBody.Seek(0, 0) | ||
| 182 | |||
| 183 | req, err := http.NewRequest(http.MethodPost, u.String(), postBody) | ||
| 184 | if err != nil { | ||
| 185 | return AssumeRoleResponse{}, err | ||
| 186 | } | ||
| 187 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | ||
| 188 | req.Header.Set("X-Amz-Content-Sha256", hex.EncodeToString(hash.Sum(nil))) | ||
| 189 | if opts.SessionToken != "" { | ||
| 190 | req.Header.Set("X-Amz-Security-Token", opts.SessionToken) | ||
| 191 | } | ||
| 192 | req = signer.SignV4STS(*req, opts.AccessKey, opts.SecretKey, opts.Location) | ||
| 193 | |||
| 194 | resp, err := clnt.Do(req) | ||
| 195 | if err != nil { | ||
| 196 | return AssumeRoleResponse{}, err | ||
| 197 | } | ||
| 198 | defer closeResponse(resp) | ||
| 199 | if resp.StatusCode != http.StatusOK { | ||
| 200 | var errResp ErrorResponse | ||
| 201 | buf, err := io.ReadAll(resp.Body) | ||
| 202 | if err != nil { | ||
| 203 | return AssumeRoleResponse{}, err | ||
| 204 | } | ||
| 205 | _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp) | ||
| 206 | if err != nil { | ||
| 207 | var s3Err Error | ||
| 208 | if _, err = xmlDecodeAndBody(bytes.NewReader(buf), &s3Err); err != nil { | ||
| 209 | return AssumeRoleResponse{}, err | ||
| 210 | } | ||
| 211 | errResp.RequestID = s3Err.RequestID | ||
| 212 | errResp.STSError.Code = s3Err.Code | ||
| 213 | errResp.STSError.Message = s3Err.Message | ||
| 214 | } | ||
| 215 | return AssumeRoleResponse{}, errResp | ||
| 216 | } | ||
| 217 | |||
| 218 | a := AssumeRoleResponse{} | ||
| 219 | if _, err = xmlDecodeAndBody(resp.Body, &a); err != nil { | ||
| 220 | return AssumeRoleResponse{}, err | ||
| 221 | } | ||
| 222 | return a, nil | ||
| 223 | } | ||
| 224 | |||
| 225 | // Retrieve retrieves credentials from the MinIO service. | ||
| 226 | // Error will be returned if the request fails. | ||
| 227 | func (m *STSAssumeRole) Retrieve() (Value, error) { | ||
| 228 | a, err := getAssumeRoleCredentials(m.Client, m.STSEndpoint, m.Options) | ||
| 229 | if err != nil { | ||
| 230 | return Value{}, err | ||
| 231 | } | ||
| 232 | |||
| 233 | // Expiry window is set to 10secs. | ||
| 234 | m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow) | ||
| 235 | |||
| 236 | return Value{ | ||
| 237 | AccessKeyID: a.Result.Credentials.AccessKey, | ||
| 238 | SecretAccessKey: a.Result.Credentials.SecretKey, | ||
| 239 | SessionToken: a.Result.Credentials.SessionToken, | ||
| 240 | SignerType: SignatureV4, | ||
| 241 | }, nil | ||
| 242 | } | ||