Skip to content

Commit f43530b

Browse files
harshavardhanaminio-trusted
authored andcommitted
api: Add NewWithCredentials()
Fixes #643
1 parent 2f03aba commit f43530b

29 files changed

Lines changed: 1843 additions & 94 deletions

api-presigned.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,21 +122,40 @@ func (c Client) PresignedPostPolicy(p *PostPolicy) (u *url.URL, formData map[str
122122
return nil, nil, err
123123
}
124124

125+
// Get credentials from the configured credentials provider.
126+
credValues, err := c.credsProvider.Get()
127+
if err != nil {
128+
return nil, nil, err
129+
}
130+
131+
signerType := c.signature
132+
// Check if the signature type is default, it means caller didn't
133+
// ask for anything specific signature style.. Check if the
134+
// credentials set returned the type of signature that should
135+
// be used, if not proceed to use default.
136+
if signerType == SignatureDefault && credValues.SignatureType != "" {
137+
signerType = parseSignatureType(credValues.SignatureType)
138+
}
139+
140+
sessionToken := credValues.SessionToken
141+
accessKeyID := credValues.AccessKeyID
142+
secretAccessKey := credValues.SecretAccessKey
143+
125144
// Keep time.
126145
t := time.Now().UTC()
127146
// For signature version '2' handle here.
128-
if c.signature.isV2() {
147+
if signerType.isV2() {
129148
policyBase64 := p.base64()
130149
p.formData["policy"] = policyBase64
131150
// For Google endpoint set this value to be 'GoogleAccessId'.
132151
if s3utils.IsGoogleEndpoint(c.endpointURL) {
133-
p.formData["GoogleAccessId"] = c.accessKeyID
152+
p.formData["GoogleAccessId"] = accessKeyID
134153
} else {
135154
// For all other endpoints set this value to be 'AWSAccessKeyId'.
136-
p.formData["AWSAccessKeyId"] = c.accessKeyID
155+
p.formData["AWSAccessKeyId"] = accessKeyID
137156
}
138157
// Sign the policy.
139-
p.formData["signature"] = s3signer.PostPresignSignatureV2(policyBase64, c.secretAccessKey)
158+
p.formData["signature"] = s3signer.PostPresignSignatureV2(policyBase64, secretAccessKey)
140159
return u, p.formData, nil
141160
}
142161

@@ -159,7 +178,7 @@ func (c Client) PresignedPostPolicy(p *PostPolicy) (u *url.URL, formData map[str
159178
}
160179

161180
// Add a credential policy.
162-
credential := s3signer.GetCredential(c.accessKeyID, location, t)
181+
credential := s3signer.GetCredential(accessKeyID, location, t)
163182
if err = p.addNewPolicy(policyCondition{
164183
matchType: "eq",
165184
condition: "$x-amz-credential",
@@ -168,13 +187,27 @@ func (c Client) PresignedPostPolicy(p *PostPolicy) (u *url.URL, formData map[str
168187
return nil, nil, err
169188
}
170189

190+
if sessionToken != "" {
191+
if err = p.addNewPolicy(policyCondition{
192+
matchType: "eq",
193+
condition: "$x-amz-security-token",
194+
value: sessionToken,
195+
}); err != nil {
196+
return nil, nil, err
197+
}
198+
}
199+
171200
// Get base64 encoded policy.
172201
policyBase64 := p.base64()
202+
173203
// Fill in the form data.
174204
p.formData["policy"] = policyBase64
175205
p.formData["x-amz-algorithm"] = signV4Algorithm
176206
p.formData["x-amz-credential"] = credential
177207
p.formData["x-amz-date"] = t.Format(iso8601DateFormat)
178-
p.formData["x-amz-signature"] = s3signer.PostPresignSignatureV4(policyBase64, t, c.secretAccessKey, location)
208+
if sessionToken != "" {
209+
p.formData["x-amz-security-token"] = sessionToken
210+
}
211+
p.formData["x-amz-signature"] = s3signer.PostPresignSignatureV4(policyBase64, t, secretAccessKey, location)
179212
return u, p.formData, nil
180213
}

api-put-bucket.go

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"net/url"
2929
"path"
3030

31+
"github.com/minio/minio-go/pkg/credentials"
3132
"github.com/minio/minio-go/pkg/policy"
3233
"github.com/minio/minio-go/pkg/s3signer"
3334
)
@@ -135,9 +136,39 @@ func (c Client) makeBucketRequest(bucketName string, location string) (*http.Req
135136
// set UserAgent for the request.
136137
c.setUserAgent(req)
137138

138-
// set sha256 sum for signature calculation only with
139-
// signature version '4'.
140-
if c.signature.isV4() {
139+
var (
140+
signerType = c.signature
141+
accessKeyID string
142+
secretAccessKey string
143+
sessionToken string
144+
)
145+
146+
var value credentials.Value
147+
if c.credsProvider != nil {
148+
// Get credentials from the configured credentials provider.
149+
value, err = c.credsProvider.Get()
150+
if err != nil {
151+
return nil, err
152+
}
153+
154+
// Check if the signature type is default, it means caller didn't
155+
// ask for anything specific signature style.. Check if the
156+
// credentials set returned the type of signature that should
157+
// be used, if not proceed to use default.
158+
if signerType == SignatureDefault && value.SignatureType != "" {
159+
signerType = parseSignatureType(value.SignatureType)
160+
}
161+
162+
accessKeyID = value.AccessKeyID
163+
secretAccessKey = value.SecretAccessKey
164+
sessionToken = value.SessionToken
165+
} else {
166+
// No credentials provider set, will be treated as anonymous request.
167+
signerType = SignatureAnonymous
168+
}
169+
170+
// set sha256 sum for signature calculation only with signature version '4'.
171+
if signerType.isV4() {
141172
req.Header.Set("X-Amz-Content-Sha256", hex.EncodeToString(sum256([]byte{})))
142173
}
143174

@@ -155,19 +186,19 @@ func (c Client) makeBucketRequest(bucketName string, location string) (*http.Req
155186
req.ContentLength = int64(len(createBucketConfigBytes))
156187
// Set content-md5.
157188
req.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(sumMD5(createBucketConfigBytes)))
158-
if c.signature.isV4() {
189+
if signerType.isV4() {
159190
// Set sha256.
160191
req.Header.Set("X-Amz-Content-Sha256", hex.EncodeToString(sum256(createBucketConfigBytes)))
161192
}
162193
}
163194

164195
// Sign the request.
165-
if c.signature.isV4() {
196+
if signerType.isV4() {
166197
// Signature calculated for MakeBucket request should be for 'us-east-1',
167198
// regardless of the bucket's location constraint.
168-
req = s3signer.SignV4(*req, c.accessKeyID, c.secretAccessKey, "us-east-1")
169-
} else if c.signature.isV2() {
170-
req = s3signer.SignV2(*req, c.accessKeyID, c.secretAccessKey)
199+
req = s3signer.SignV4(*req, accessKeyID, secretAccessKey, sessionToken, "us-east-1")
200+
} else if signerType.isV2() {
201+
req = s3signer.SignV2(*req, accessKeyID, secretAccessKey)
171202
}
172203

173204
// Return signed request.

api-put-bucket_test.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"path"
2828
"testing"
2929

30+
"github.com/minio/minio-go/pkg/credentials"
3031
"github.com/minio/minio-go/pkg/s3signer"
3132
)
3233

@@ -48,8 +49,39 @@ func TestMakeBucketRequest(t *testing.T) {
4849
// set UserAgent for the request.
4950
c.setUserAgent(req)
5051

52+
var (
53+
signerType = c.signature
54+
accessKeyID string
55+
secretAccessKey string
56+
sessionToken string
57+
)
58+
59+
var value credentials.Value
60+
if c.credsProvider != nil {
61+
// Get credentials from the configured credentials provider.
62+
value, err = c.credsProvider.Get()
63+
if err != nil {
64+
return nil, err
65+
}
66+
67+
// Check if the signature type is default, it means caller didn't
68+
// ask for anything specific signature style.. Check if the
69+
// credentials set returned the type of signature that should
70+
// be used, if not proceed to use default.
71+
if signerType == SignatureDefault && value.SignatureType != "" {
72+
signerType = parseSignatureType(value.SignatureType)
73+
}
74+
75+
accessKeyID = value.AccessKeyID
76+
secretAccessKey = value.SecretAccessKey
77+
sessionToken = value.SessionToken
78+
} else {
79+
// No credentials provider set, will be treated as anonymous request.
80+
signerType = SignatureAnonymous
81+
}
82+
5183
// set sha256 sum for signature calculation only with signature version '4'.
52-
if c.signature.isV4() {
84+
if signerType.isV4() {
5385
req.Header.Set("X-Amz-Content-Sha256", hex.EncodeToString(sum256([]byte{})))
5486
}
5587

@@ -67,19 +99,19 @@ func TestMakeBucketRequest(t *testing.T) {
6799
req.ContentLength = int64(len(createBucketConfigBytes))
68100
// Set content-md5.
69101
req.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(sumMD5(createBucketConfigBytes)))
70-
if c.signature.isV4() {
102+
if signerType.isV4() {
71103
// Set sha256.
72104
req.Header.Set("X-Amz-Content-Sha256", hex.EncodeToString(sum256(createBucketConfigBytes)))
73105
}
74106
}
75107

76108
// Sign the request.
77-
if c.signature.isV4() {
109+
if signerType.isV4() {
78110
// Signature calculated for MakeBucket request should be for 'us-east-1',
79111
// regardless of the bucket's location constraint.
80-
req = s3signer.SignV4(*req, c.accessKeyID, c.secretAccessKey, "us-east-1")
112+
req = s3signer.SignV4(*req, accessKeyID, secretAccessKey, sessionToken, "us-east-1")
81113
} else if c.signature.isV2() {
82-
req = s3signer.SignV2(*req, c.accessKeyID, c.secretAccessKey)
114+
req = s3signer.SignV2(*req, accessKeyID, secretAccessKey)
83115
}
84116

85117
// Return signed request.
@@ -246,7 +278,7 @@ func TestMakeBucketRequest(t *testing.T) {
246278
}
247279

248280
if expectedReq.Header.Get("X-Amz-Content-Sha256") != actualReq.Header.Get("X-Amz-Content-Sha256") {
249-
t.Errorf("Test %d: 'X-Amz-Content-Sha256' header of the expected request doesn't match with that of the actual request", i+1)
281+
t.Errorf("Test %d: 'X-Amz-Content-Sha256' header of the expected request %s doesn't match with that of the actual request %s", i+1, expectedReq.Header.Get("X-Amz-Content-Sha256"), actualReq.Header.Get("X-Amz-Content-Sha256"))
250282
}
251283
if expectedReq.Header.Get("User-Agent") != actualReq.Header.Get("User-Agent") {
252284
t.Errorf("Test %d: Expected 'User-Agent' header to be \"%s\",but found \"%s\" instead", i+1, expectedReq.Header.Get("User-Agent"), actualReq.Header.Get("User-Agent"))

api-put-object-progress.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ func (c Client) PutObjectWithMetadata(bucketName, objectName string, reader io.R
103103
if size < minPartSize && size >= 0 {
104104
return c.putObjectSingle(bucketName, objectName, reader, size, metaData, progress)
105105
}
106+
106107
// For all sizes greater than 5MiB do multipart.
107108
n, err = c.putObjectMultipart(bucketName, objectName, reader, size, metaData, progress)
108109
if err != nil {

0 commit comments

Comments
 (0)