diff options
author | Christopher Speller <crspeller@gmail.com> | 2018-04-16 05:37:14 -0700 |
---|---|---|
committer | Joram Wilander <jwawilander@gmail.com> | 2018-04-16 08:37:14 -0400 |
commit | 6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch) | |
tree | 3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/github.com/minio/minio-go/pkg | |
parent | bf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff) | |
download | chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2 chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip |
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/github.com/minio/minio-go/pkg')
16 files changed, 0 insertions, 4090 deletions
diff --git a/vendor/github.com/minio/minio-go/pkg/credentials/chain_test.go b/vendor/github.com/minio/minio-go/pkg/credentials/chain_test.go deleted file mode 100644 index d26e376ff..000000000 --- a/vendor/github.com/minio/minio-go/pkg/credentials/chain_test.go +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package credentials - -import ( - "errors" - "testing" -) - -type testCredProvider struct { - creds Value - expired bool - err error -} - -func (s *testCredProvider) Retrieve() (Value, error) { - s.expired = false - return s.creds, s.err -} -func (s *testCredProvider) IsExpired() bool { - return s.expired -} - -func TestChainGet(t *testing.T) { - p := &Chain{ - Providers: []Provider{ - &credProvider{err: errors.New("FirstError")}, - &credProvider{err: errors.New("SecondError")}, - &testCredProvider{ - creds: Value{ - AccessKeyID: "AKIF", - SecretAccessKey: "NOSECRET", - SessionToken: "", - }, - }, - &credProvider{ - creds: Value{ - AccessKeyID: "AKID", - SecretAccessKey: "SECRET", - SessionToken: "", - }, - }, - }, - } - - creds, err := p.Retrieve() - if err != nil { - t.Fatal(err) - } - - // Also check credentials - if creds.AccessKeyID != "AKIF" { - t.Fatalf("Expected 'AKIF', got %s", creds.AccessKeyID) - } - if creds.SecretAccessKey != "NOSECRET" { - t.Fatalf("Expected 'NOSECRET', got %s", creds.SecretAccessKey) - } - if creds.SessionToken != "" { - t.Fatalf("Expected empty token, got %s", creds.SessionToken) - } -} - -func TestChainIsExpired(t *testing.T) { - credProvider := &credProvider{ - creds: Value{ - AccessKeyID: "UXHW", - SecretAccessKey: "MYSECRET", - SessionToken: "", - }, - expired: true, - } - p := &Chain{ - Providers: []Provider{ - credProvider, - }, - } - - if !p.IsExpired() { - t.Fatal("Expected expired to be true before any Retrieve") - } - - _, err := p.Retrieve() - if err != nil { - t.Fatal(err) - } - - if p.IsExpired() { - t.Fatal("Expected to be not expired after Retrieve") - } -} - -func TestChainWithNoProvider(t *testing.T) { - p := &Chain{ - Providers: []Provider{}, - } - if !p.IsExpired() { - t.Fatal("Expected to be expired with no providers") - } - _, err := p.Retrieve() - if err != nil { - if err.Error() != "No valid providers found []" { - t.Error(err) - } - } -} - -func TestChainProviderWithNoValidProvider(t *testing.T) { - errs := []error{ - errors.New("FirstError"), - errors.New("SecondError"), - } - p := &Chain{ - Providers: []Provider{ - &credProvider{err: errs[0]}, - &credProvider{err: errs[1]}, - }, - } - - if !p.IsExpired() { - t.Fatal("Expected to be expired with no providers") - } - - _, err := p.Retrieve() - if err != nil { - if err.Error() != "No valid providers found [FirstError SecondError]" { - t.Error(err) - } - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/credentials/credentials_test.go b/vendor/github.com/minio/minio-go/pkg/credentials/credentials_test.go deleted file mode 100644 index 92c77c4cb..000000000 --- a/vendor/github.com/minio/minio-go/pkg/credentials/credentials_test.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package credentials - -import ( - "errors" - "testing" -) - -type credProvider struct { - creds Value - expired bool - err error -} - -func (s *credProvider) Retrieve() (Value, error) { - s.expired = false - return s.creds, s.err -} -func (s *credProvider) IsExpired() bool { - return s.expired -} - -func TestCredentialsGet(t *testing.T) { - c := New(&credProvider{ - creds: Value{ - AccessKeyID: "UXHW", - SecretAccessKey: "MYSECRET", - SessionToken: "", - }, - expired: true, - }) - - creds, err := c.Get() - if err != nil { - t.Fatal(err) - } - if "UXHW" != creds.AccessKeyID { - t.Errorf("Expected \"UXHW\", got %s", creds.AccessKeyID) - } - if "MYSECRET" != creds.SecretAccessKey { - t.Errorf("Expected \"MYSECRET\", got %s", creds.SecretAccessKey) - } - if creds.SessionToken != "" { - t.Errorf("Expected session token to be empty, got %s", creds.SessionToken) - } -} - -func TestCredentialsGetWithError(t *testing.T) { - c := New(&credProvider{err: errors.New("Custom error")}) - - _, err := c.Get() - if err != nil { - if err.Error() != "Custom error" { - t.Errorf("Expected \"Custom error\", got %s", err.Error()) - } - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/credentials/env_test.go b/vendor/github.com/minio/minio-go/pkg/credentials/env_test.go deleted file mode 100644 index 09cd77f7a..000000000 --- a/vendor/github.com/minio/minio-go/pkg/credentials/env_test.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package credentials - -import ( - "os" - "reflect" - "testing" -) - -func TestEnvAWSRetrieve(t *testing.T) { - os.Clearenv() - os.Setenv("AWS_ACCESS_KEY_ID", "access") - os.Setenv("AWS_SECRET_ACCESS_KEY", "secret") - os.Setenv("AWS_SESSION_TOKEN", "token") - - e := EnvAWS{} - if !e.IsExpired() { - t.Error("Expect creds to be expired before retrieve.") - } - - creds, err := e.Retrieve() - if err != nil { - t.Fatal(err) - } - - expectedCreds := Value{ - AccessKeyID: "access", - SecretAccessKey: "secret", - SessionToken: "token", - SignerType: SignatureV4, - } - if !reflect.DeepEqual(creds, expectedCreds) { - t.Errorf("Expected %v, got %v", expectedCreds, creds) - } - - if e.IsExpired() { - t.Error("Expect creds to not be expired after retrieve.") - } - - os.Clearenv() - os.Setenv("AWS_ACCESS_KEY", "access") - os.Setenv("AWS_SECRET_KEY", "secret") - - expectedCreds = Value{ - AccessKeyID: "access", - SecretAccessKey: "secret", - SignerType: SignatureV4, - } - - creds, err = e.Retrieve() - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(creds, expectedCreds) { - t.Errorf("Expected %v, got %v", expectedCreds, creds) - } - -} - -func TestEnvMinioRetrieve(t *testing.T) { - os.Clearenv() - - os.Setenv("MINIO_ACCESS_KEY", "access") - os.Setenv("MINIO_SECRET_KEY", "secret") - - e := EnvMinio{} - if !e.IsExpired() { - t.Error("Expect creds to be expired before retrieve.") - } - - creds, err := e.Retrieve() - if err != nil { - t.Fatal(err) - } - - expectedCreds := Value{ - AccessKeyID: "access", - SecretAccessKey: "secret", - SignerType: SignatureV4, - } - if !reflect.DeepEqual(creds, expectedCreds) { - t.Errorf("Expected %v, got %v", expectedCreds, creds) - } - - if e.IsExpired() { - t.Error("Expect creds to not be expired after retrieve.") - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/credentials/file_test.go b/vendor/github.com/minio/minio-go/pkg/credentials/file_test.go deleted file mode 100644 index c85c10494..000000000 --- a/vendor/github.com/minio/minio-go/pkg/credentials/file_test.go +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package credentials - -import ( - "os" - "path/filepath" - "testing" -) - -func TestFileAWS(t *testing.T) { - os.Clearenv() - - creds := NewFileAWSCredentials("credentials.sample", "") - credValues, err := creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "accessKey" { - t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "secret" { - t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey) - } - if credValues.SessionToken != "token" { - t.Errorf("Expected 'token', got %s'", credValues.SessionToken) - } - - os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "credentials.sample") - creds = NewFileAWSCredentials("", "") - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "accessKey" { - t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "secret" { - t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey) - } - if credValues.SessionToken != "token" { - t.Errorf("Expected 'token', got %s'", credValues.SessionToken) - } - - wd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - - os.Setenv("AWS_SHARED_CREDENTIALS_FILE", filepath.Join(wd, "credentials.sample")) - creds = NewFileAWSCredentials("", "") - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "accessKey" { - t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "secret" { - t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey) - } - if credValues.SessionToken != "token" { - t.Errorf("Expected 'token', got %s'", credValues.SessionToken) - } - - os.Clearenv() - os.Setenv("AWS_PROFILE", "no_token") - - creds = NewFileAWSCredentials("credentials.sample", "") - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "accessKey" { - t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "secret" { - t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey) - } - - os.Clearenv() - - creds = NewFileAWSCredentials("credentials.sample", "no_token") - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "accessKey" { - t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "secret" { - t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey) - } - - creds = NewFileAWSCredentials("credentials-non-existent.sample", "no_token") - _, err = creds.Get() - if !os.IsNotExist(err) { - t.Errorf("Expected open non-existent.json: no such file or directory, got %s", err) - } - if !creds.IsExpired() { - t.Error("Should be expired if not loaded") - } -} - -func TestFileMinioClient(t *testing.T) { - os.Clearenv() - - creds := NewFileMinioClient("config.json.sample", "") - credValues, err := creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "accessKey" { - t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "secret" { - t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey) - } - if credValues.SignerType != SignatureV4 { - t.Errorf("Expected 'S3v4', got %s'", credValues.SignerType) - } - - os.Clearenv() - os.Setenv("MINIO_ALIAS", "play") - - creds = NewFileMinioClient("config.json.sample", "") - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "Q3AM3UQ867SPQQA43P2F" { - t.Errorf("Expected 'Q3AM3UQ867SPQQA43P2F', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" { - t.Errorf("Expected 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG', got %s'", credValues.SecretAccessKey) - } - if credValues.SignerType != SignatureV2 { - t.Errorf("Expected 'S3v2', got %s'", credValues.SignerType) - } - - os.Clearenv() - - creds = NewFileMinioClient("config.json.sample", "play") - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if credValues.AccessKeyID != "Q3AM3UQ867SPQQA43P2F" { - t.Errorf("Expected 'Q3AM3UQ867SPQQA43P2F', got %s'", credValues.AccessKeyID) - } - if credValues.SecretAccessKey != "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" { - t.Errorf("Expected 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG', got %s'", credValues.SecretAccessKey) - } - if credValues.SignerType != SignatureV2 { - t.Errorf("Expected 'S3v2', got %s'", credValues.SignerType) - } - - creds = NewFileMinioClient("non-existent.json", "play") - _, err = creds.Get() - if !os.IsNotExist(err) { - t.Errorf("Expected open non-existent.json: no such file or directory, got %s", err) - } - if !creds.IsExpired() { - t.Error("Should be expired if not loaded") - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/credentials/iam_aws_test.go b/vendor/github.com/minio/minio-go/pkg/credentials/iam_aws_test.go deleted file mode 100644 index 86ea66bf6..000000000 --- a/vendor/github.com/minio/minio-go/pkg/credentials/iam_aws_test.go +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package credentials - -import ( - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" -) - -const credsRespTmpl = `{ - "Code": "Success", - "Type": "AWS-HMAC", - "AccessKeyId" : "accessKey", - "SecretAccessKey" : "secret", - "Token" : "token", - "Expiration" : "%s", - "LastUpdated" : "2009-11-23T0:00:00Z" -}` - -const credsFailRespTmpl = `{ - "Code": "ErrorCode", - "Message": "ErrorMsg", - "LastUpdated": "2009-11-23T0:00:00Z" -}` - -func initTestFailServer() *httptest.Server { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - http.Error(w, "Not allowed", http.StatusBadRequest) - })) - return server -} - -func initTestServerNoRoles() *httptest.Server { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("")) - })) - return server -} - -func initTestServer(expireOn string, failAssume bool) *httptest.Server { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/latest/meta-data/iam/security-credentials" { - fmt.Fprintln(w, "RoleName") - } else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" { - if failAssume { - fmt.Fprintf(w, credsFailRespTmpl) - } else { - fmt.Fprintf(w, credsRespTmpl, expireOn) - } - } else { - http.Error(w, "bad request", http.StatusBadRequest) - } - })) - - return server -} - -func TestIAMMalformedEndpoint(t *testing.T) { - creds := NewIAM("%%%%") - _, err := creds.Get() - if err == nil { - t.Fatal("Unexpected should fail here") - } - if err.Error() != `parse %%%%: invalid URL escape "%%%"` { - t.Fatalf("Expected parse %%%%%%%%: invalid URL escape \"%%%%%%\", got %s", err) - } -} - -func TestIAMFailServer(t *testing.T) { - server := initTestFailServer() - defer server.Close() - - creds := NewIAM(server.URL) - - _, err := creds.Get() - if err == nil { - t.Fatal("Unexpected should fail here") - } - if err.Error() != "400 Bad Request" { - t.Fatalf("Expected '400 Bad Request', got %s", err) - } -} - -func TestIAMNoRoles(t *testing.T) { - server := initTestServerNoRoles() - defer server.Close() - - creds := NewIAM(server.URL) - _, err := creds.Get() - if err == nil { - t.Fatal("Unexpected should fail here") - } - if err.Error() != "No IAM roles attached to this EC2 service" { - t.Fatalf("Expected 'No IAM roles attached to this EC2 service', got %s", err) - } -} - -func TestIAM(t *testing.T) { - server := initTestServer("2014-12-16T01:51:37Z", false) - defer server.Close() - - p := &IAM{ - Client: http.DefaultClient, - endpoint: server.URL, - } - - creds, err := p.Retrieve() - if err != nil { - t.Fatal(err) - } - - if "accessKey" != creds.AccessKeyID { - t.Errorf("Expected \"accessKey\", got %s", creds.AccessKeyID) - } - - if "secret" != creds.SecretAccessKey { - t.Errorf("Expected \"secret\", got %s", creds.SecretAccessKey) - } - - if "token" != creds.SessionToken { - t.Errorf("Expected \"token\", got %s", creds.SessionToken) - } - - if !p.IsExpired() { - t.Error("Expected creds to be expired.") - } -} - -func TestIAMFailAssume(t *testing.T) { - server := initTestServer("2014-12-16T01:51:37Z", true) - defer server.Close() - - p := &IAM{ - Client: http.DefaultClient, - endpoint: server.URL, - } - - _, err := p.Retrieve() - if err == nil { - t.Fatal("Unexpected success, should fail") - } - if err.Error() != "ErrorMsg" { - t.Errorf("Expected \"ErrorMsg\", got %s", err) - } -} - -func TestIAMIsExpired(t *testing.T) { - server := initTestServer("2014-12-16T01:51:37Z", false) - defer server.Close() - - p := &IAM{ - Client: http.DefaultClient, - endpoint: server.URL, - } - p.CurrentTime = func() time.Time { - return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC) - } - - if !p.IsExpired() { - t.Error("Expected creds to be expired before retrieve.") - } - - _, err := p.Retrieve() - if err != nil { - t.Fatal(err) - } - - if p.IsExpired() { - t.Error("Expected creds to not be expired after retrieve.") - } - - p.CurrentTime = func() time.Time { - return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC) - } - - if !p.IsExpired() { - t.Error("Expected creds to be expired when curren time has changed") - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/credentials/static_test.go b/vendor/github.com/minio/minio-go/pkg/credentials/static_test.go deleted file mode 100644 index f1d2d856c..000000000 --- a/vendor/github.com/minio/minio-go/pkg/credentials/static_test.go +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package credentials - -import "testing" - -func TestStaticGet(t *testing.T) { - creds := NewStatic("UXHW", "SECRET", "", SignatureV4) - credValues, err := creds.Get() - if err != nil { - t.Fatal(err) - } - - if "UXHW" != credValues.AccessKeyID { - t.Errorf("Expected access key ID to match \"UXHW\", got %s", credValues.AccessKeyID) - } - if "SECRET" != credValues.SecretAccessKey { - t.Errorf("Expected secret access key to match \"SECRET\", got %s", credValues.SecretAccessKey) - } - - if credValues.SessionToken != "" { - t.Error("Expected session token to match") - } - - if credValues.SignerType != SignatureV4 { - t.Errorf("Expected 'S3v4', got %s", credValues.SignerType) - } - - if creds.IsExpired() { - t.Error("Static credentials should never expire") - } - - creds = NewStatic("", "", "", SignatureDefault) - credValues, err = creds.Get() - if err != nil { - t.Fatal(err) - } - - if "" != credValues.AccessKeyID { - t.Errorf("Expected access key ID to match empty string, got %s", credValues.AccessKeyID) - } - if "" != credValues.SecretAccessKey { - t.Errorf("Expected secret access key to match empty string, got %s", credValues.SecretAccessKey) - } - - if !credValues.SignerType.IsAnonymous() { - t.Errorf("Expected 'Anonymous', got %s", credValues.SignerType) - } - - if creds.IsExpired() { - t.Error("Static credentials should never expire") - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition_test.go b/vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition_test.go deleted file mode 100644 index 9e4aa8fb6..000000000 --- a/vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition_test.go +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package policy - -import ( - "encoding/json" - "testing" - - "github.com/minio/minio-go/pkg/set" -) - -// ConditionKeyMap.Add() is called and the result is validated. -func TestConditionKeyMapAdd(t *testing.T) { - condKeyMap := make(ConditionKeyMap) - testCases := []struct { - key string - value set.StringSet - expectedResult string - }{ - // Add new key and value. - {"s3:prefix", set.CreateStringSet("hello"), `{"s3:prefix":["hello"]}`}, - // Add existing key and value. - {"s3:prefix", set.CreateStringSet("hello"), `{"s3:prefix":["hello"]}`}, - // Add existing key and not value. - {"s3:prefix", set.CreateStringSet("world"), `{"s3:prefix":["hello","world"]}`}, - } - - for _, testCase := range testCases { - condKeyMap.Add(testCase.key, testCase.value) - if data, err := json.Marshal(condKeyMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// ConditionKeyMap.Remove() is called and the result is validated. -func TestConditionKeyMapRemove(t *testing.T) { - condKeyMap := make(ConditionKeyMap) - condKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world")) - - testCases := []struct { - key string - value set.StringSet - expectedResult string - }{ - // Remove non-existent key and value. - {"s3:myprefix", set.CreateStringSet("hello"), `{"s3:prefix":["hello","world"]}`}, - // Remove existing key and value. - {"s3:prefix", set.CreateStringSet("hello"), `{"s3:prefix":["world"]}`}, - // Remove existing key to make the key also removed. - {"s3:prefix", set.CreateStringSet("world"), `{}`}, - } - - for _, testCase := range testCases { - condKeyMap.Remove(testCase.key, testCase.value) - if data, err := json.Marshal(condKeyMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// ConditionKeyMap.RemoveKey() is called and the result is validated. -func TestConditionKeyMapRemoveKey(t *testing.T) { - condKeyMap := make(ConditionKeyMap) - condKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world")) - - testCases := []struct { - key string - expectedResult string - }{ - // Remove non-existent key. - {"s3:myprefix", `{"s3:prefix":["hello","world"]}`}, - // Remove existing key. - {"s3:prefix", `{}`}, - } - - for _, testCase := range testCases { - condKeyMap.RemoveKey(testCase.key) - if data, err := json.Marshal(condKeyMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// CopyConditionKeyMap() is called and the result is validated. -func TestCopyConditionKeyMap(t *testing.T) { - emptyCondKeyMap := make(ConditionKeyMap) - nonEmptyCondKeyMap := make(ConditionKeyMap) - nonEmptyCondKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world")) - - testCases := []struct { - condKeyMap ConditionKeyMap - expectedResult string - }{ - // To test empty ConditionKeyMap. - {emptyCondKeyMap, `{}`}, - // To test non-empty ConditionKeyMap. - {nonEmptyCondKeyMap, `{"s3:prefix":["hello","world"]}`}, - } - - for _, testCase := range testCases { - condKeyMap := CopyConditionKeyMap(testCase.condKeyMap) - if data, err := json.Marshal(condKeyMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// mergeConditionKeyMap() is called and the result is validated. -func TestMergeConditionKeyMap(t *testing.T) { - condKeyMap1 := make(ConditionKeyMap) - condKeyMap1.Add("s3:prefix", set.CreateStringSet("hello")) - - condKeyMap2 := make(ConditionKeyMap) - condKeyMap2.Add("s3:prefix", set.CreateStringSet("world")) - - condKeyMap3 := make(ConditionKeyMap) - condKeyMap3.Add("s3:myprefix", set.CreateStringSet("world")) - - testCases := []struct { - condKeyMap1 ConditionKeyMap - condKeyMap2 ConditionKeyMap - expectedResult string - }{ - // Both arguments are empty. - {make(ConditionKeyMap), make(ConditionKeyMap), `{}`}, - // First argument is empty. - {make(ConditionKeyMap), condKeyMap1, `{"s3:prefix":["hello"]}`}, - // Second argument is empty. - {condKeyMap1, make(ConditionKeyMap), `{"s3:prefix":["hello"]}`}, - // Both arguments are same value. - {condKeyMap1, condKeyMap1, `{"s3:prefix":["hello"]}`}, - // Value of second argument will be merged. - {condKeyMap1, condKeyMap2, `{"s3:prefix":["hello","world"]}`}, - // second argument will be added. - {condKeyMap1, condKeyMap3, `{"s3:myprefix":["world"],"s3:prefix":["hello"]}`}, - } - - for _, testCase := range testCases { - condKeyMap := mergeConditionKeyMap(testCase.condKeyMap1, testCase.condKeyMap2) - if data, err := json.Marshal(condKeyMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// ConditionMap.Add() is called and the result is validated. -func TestConditionMapAdd(t *testing.T) { - condMap := make(ConditionMap) - - condKeyMap1 := make(ConditionKeyMap) - condKeyMap1.Add("s3:prefix", set.CreateStringSet("hello")) - - condKeyMap2 := make(ConditionKeyMap) - condKeyMap2.Add("s3:prefix", set.CreateStringSet("hello", "world")) - - testCases := []struct { - key string - value ConditionKeyMap - expectedResult string - }{ - // Add new key and value. - {"StringEquals", condKeyMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`}, - // Add existing key and value. - {"StringEquals", condKeyMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`}, - // Add existing key and not value. - {"StringEquals", condKeyMap2, `{"StringEquals":{"s3:prefix":["hello","world"]}}`}, - } - - for _, testCase := range testCases { - condMap.Add(testCase.key, testCase.value) - if data, err := json.Marshal(condMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// ConditionMap.Remove() is called and the result is validated. -func TestConditionMapRemove(t *testing.T) { - condMap := make(ConditionMap) - condKeyMap := make(ConditionKeyMap) - condKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world")) - condMap.Add("StringEquals", condKeyMap) - - testCases := []struct { - key string - expectedResult string - }{ - // Remove non-existent key. - {"StringNotEquals", `{"StringEquals":{"s3:prefix":["hello","world"]}}`}, - // Remove existing key. - {"StringEquals", `{}`}, - } - - for _, testCase := range testCases { - condMap.Remove(testCase.key) - if data, err := json.Marshal(condMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// mergeConditionMap() is called and the result is validated. -func TestMergeConditionMap(t *testing.T) { - condKeyMap1 := make(ConditionKeyMap) - condKeyMap1.Add("s3:prefix", set.CreateStringSet("hello")) - condMap1 := make(ConditionMap) - condMap1.Add("StringEquals", condKeyMap1) - - condKeyMap2 := make(ConditionKeyMap) - condKeyMap2.Add("s3:prefix", set.CreateStringSet("world")) - condMap2 := make(ConditionMap) - condMap2.Add("StringEquals", condKeyMap2) - - condMap3 := make(ConditionMap) - condMap3.Add("StringNotEquals", condKeyMap2) - - testCases := []struct { - condMap1 ConditionMap - condMap2 ConditionMap - expectedResult string - }{ - // Both arguments are empty. - {make(ConditionMap), make(ConditionMap), `{}`}, - // First argument is empty. - {make(ConditionMap), condMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`}, - // Second argument is empty. - {condMap1, make(ConditionMap), `{"StringEquals":{"s3:prefix":["hello"]}}`}, - // Both arguments are same value. - {condMap1, condMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`}, - // Value of second argument will be merged. - {condMap1, condMap2, `{"StringEquals":{"s3:prefix":["hello","world"]}}`}, - // second argument will be added. - {condMap1, condMap3, `{"StringEquals":{"s3:prefix":["hello"]},"StringNotEquals":{"s3:prefix":["world"]}}`}, - } - - for _, testCase := range testCases { - condMap := mergeConditionMap(testCase.condMap1, testCase.condMap2) - if data, err := json.Marshal(condMap); err != nil { - t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err) - } else { - if string(data) != testCase.expectedResult { - t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/policy/bucket-policy_test.go b/vendor/github.com/minio/minio-go/pkg/policy/bucket-policy_test.go deleted file mode 100644 index 1e5196f7c..000000000 --- a/vendor/github.com/minio/minio-go/pkg/policy/bucket-policy_test.go +++ /dev/null @@ -1,1823 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package policy - -import ( - "encoding/json" - "fmt" - "reflect" - "testing" - - "github.com/minio/minio-go/pkg/set" -) - -// isValidStatement() is called and the result is validated. -func TestIsValidStatement(t *testing.T) { - testCases := []struct { - statement Statement - bucketName string - expectedResult bool - }{ - // Empty statement and bucket name. - {Statement{}, "", false}, - // Empty statement. - {Statement{}, "mybucket", false}, - // Empty bucket name. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false}, - // Statement with unknown actions. - {Statement{ - Actions: set.CreateStringSet("s3:ListBucketVersions"), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "mybucket", false}, - // Statement with unknown effect. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Deny", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "mybucket", false}, - // Statement with nil Principal.AWS. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "mybucket", false}, - // Statement with unknown Principal.AWS. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("arn:aws:iam::AccountNumberWithoutHyphens:root")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "mybucket", false}, - // Statement with different bucket name. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }, "mybucket", false}, - // Statement with bucket name with suffixed string. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybuckettest/myobject"), - }, "mybucket", false}, - // Statement with bucket name and object name. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/myobject"), - }, "mybucket", true}, - // Statement with condition, bucket name and object name. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/myobject"), - }, "mybucket", true}, - } - - for _, testCase := range testCases { - if result := isValidStatement(testCase.statement, testCase.bucketName); result != testCase.expectedResult { - t.Fatalf("%+v: expected: %t, got: %t", testCase, testCase.expectedResult, result) - } - } -} - -// newStatements() is called and the result is validated. -func TestNewStatements(t *testing.T) { - testCases := []struct { - policy BucketPolicy - bucketName string - prefix string - expectedResult string - }{ - // BucketPolicyNone: with empty bucket name and prefix. - {BucketPolicyNone, "", "", `[]`}, - // BucketPolicyNone: with bucket name and empty prefix. - {BucketPolicyNone, "mybucket", "", `[]`}, - // BucketPolicyNone: with empty bucket name empty prefix. - {BucketPolicyNone, "", "hello", `[]`}, - // BucketPolicyNone: with bucket name prefix. - {BucketPolicyNone, "mybucket", "hello", `[]`}, - // BucketPolicyReadOnly: with empty bucket name and prefix. - {BucketPolicyReadOnly, "", "", `[]`}, - // BucketPolicyReadOnly: with bucket name and empty prefix. - {BucketPolicyReadOnly, "mybucket", "", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // BucketPolicyReadOnly: with empty bucket name empty prefix. - {BucketPolicyReadOnly, "", "hello", `[]`}, - // BucketPolicyReadOnly: with bucket name prefix. - {BucketPolicyReadOnly, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // BucketPolicyReadWrite: with empty bucket name and prefix. - {BucketPolicyReadWrite, "", "", `[]`}, - // BucketPolicyReadWrite: with bucket name and empty prefix. - {BucketPolicyReadWrite, "mybucket", "", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // BucketPolicyReadWrite: with empty bucket name empty prefix. - {BucketPolicyReadWrite, "", "hello", `[]`}, - // BucketPolicyReadWrite: with bucket name prefix. - {BucketPolicyReadWrite, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // BucketPolicyWriteOnly: with empty bucket name and prefix. - {BucketPolicyWriteOnly, "", "", `[]`}, - // BucketPolicyWriteOnly: with bucket name and empty prefix. - {BucketPolicyWriteOnly, "mybucket", "", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // BucketPolicyWriteOnly: with empty bucket name empty prefix. - {BucketPolicyWriteOnly, "", "hello", `[]`}, - // BucketPolicyWriteOnly: with bucket name prefix. - {BucketPolicyWriteOnly, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - } - - for _, testCase := range testCases { - statements := newStatements(testCase.policy, testCase.bucketName, testCase.prefix) - if data, err := json.Marshal(statements); err == nil { - if string(data) != testCase.expectedResult { - t.Fatalf("%+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } - } -} - -// getInUsePolicy() is called and the result is validated. -func TestGetInUsePolicy(t *testing.T) { - testCases := []struct { - statements []Statement - bucketName string - prefix string - expectedResult1 bool - expectedResult2 bool - }{ - // All empty statements, bucket name and prefix. - {[]Statement{}, "", "", false, false}, - // Non-empty statements, empty bucket name and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "", "", false, false}, - // Non-empty statements, non-empty bucket name and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", false, false}, - // Non-empty statements, empty bucket name and non-empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "", "hello", false, false}, - // Empty statements, non-empty bucket name and empty prefix. - {[]Statement{}, "mybucket", "", false, false}, - // Empty statements, non-empty bucket name non-empty prefix. - {[]Statement{}, "mybucket", "hello", false, false}, - // Empty statements, empty bucket name and non-empty prefix. - {[]Statement{}, "", "hello", false, false}, - // Non-empty statements, non-empty bucket name, non-empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", false, false}, - // different bucket statements and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, "mybucket", "", false, false}, - // different bucket statements. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, "mybucket", "hello", false, false}, - // different bucket multi-statements and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }, { - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket/world"), - }}, "mybucket", "", false, false}, - // different bucket multi-statements. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }, { - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket/world"), - }}, "mybucket", "hello", false, false}, - // read-only in use. - {[]Statement{{ - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", true, false}, - // write-only in use. - {[]Statement{{ - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", false, true}, - // read-write in use. - {[]Statement{{ - Actions: readWriteObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", true, true}, - // read-write multi-statements. - {[]Statement{{ - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/ground"), - }}, "mybucket", "hello", true, true}, - } - - for _, testCase := range testCases { - result1, result2 := getInUsePolicy(testCase.statements, testCase.bucketName, testCase.prefix) - if !(result1 == testCase.expectedResult1 && result2 == testCase.expectedResult2) { - t.Fatalf("%+v: expected: [%t,%t], got: [%t,%t]", testCase, - testCase.expectedResult1, testCase.expectedResult2, - result1, result2) - } - } -} - -// removeStatements() is called and the result is validated. -func TestRemoveStatements(t *testing.T) { - unknownCondMap1 := make(ConditionMap) - unknownCondKeyMap1 := make(ConditionKeyMap) - unknownCondKeyMap1.Add("s3:prefix", set.CreateStringSet("hello")) - unknownCondMap1.Add("StringNotEquals", unknownCondKeyMap1) - - unknownCondMap11 := make(ConditionMap) - unknownCondKeyMap11 := make(ConditionKeyMap) - unknownCondKeyMap11.Add("s3:prefix", set.CreateStringSet("hello")) - unknownCondMap11.Add("StringNotEquals", unknownCondKeyMap11) - - unknownCondMap12 := make(ConditionMap) - unknownCondKeyMap12 := make(ConditionKeyMap) - unknownCondKeyMap12.Add("s3:prefix", set.CreateStringSet("hello")) - unknownCondMap12.Add("StringNotEquals", unknownCondKeyMap12) - - knownCondMap1 := make(ConditionMap) - knownCondKeyMap1 := make(ConditionKeyMap) - knownCondKeyMap1.Add("s3:prefix", set.CreateStringSet("hello")) - knownCondMap1.Add("StringEquals", knownCondKeyMap1) - - knownCondMap11 := make(ConditionMap) - knownCondKeyMap11 := make(ConditionKeyMap) - knownCondKeyMap11.Add("s3:prefix", set.CreateStringSet("hello")) - knownCondMap11.Add("StringEquals", knownCondKeyMap11) - - knownCondMap12 := make(ConditionMap) - knownCondKeyMap12 := make(ConditionKeyMap) - knownCondKeyMap12.Add("s3:prefix", set.CreateStringSet("hello")) - knownCondMap12.Add("StringEquals", knownCondKeyMap12) - - knownCondMap13 := make(ConditionMap) - knownCondKeyMap13 := make(ConditionKeyMap) - knownCondKeyMap13.Add("s3:prefix", set.CreateStringSet("hello")) - knownCondMap13.Add("StringEquals", knownCondKeyMap13) - - knownCondMap14 := make(ConditionMap) - knownCondKeyMap14 := make(ConditionKeyMap) - knownCondKeyMap14.Add("s3:prefix", set.CreateStringSet("hello")) - knownCondMap14.Add("StringEquals", knownCondKeyMap14) - - knownCondMap2 := make(ConditionMap) - knownCondKeyMap2 := make(ConditionKeyMap) - knownCondKeyMap2.Add("s3:prefix", set.CreateStringSet("hello", "world")) - knownCondMap2.Add("StringEquals", knownCondKeyMap2) - - testCases := []struct { - statements []Statement - bucketName string - prefix string - expectedResult string - }{ - // All empty statements, bucket name and prefix. - {[]Statement{}, "", "", `[]`}, - // Non-empty statements, empty bucket name and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Non-empty statements, non-empty bucket name and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Non-empty statements, empty bucket name and non-empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "", "hello", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Empty statements, non-empty bucket name and empty prefix. - {[]Statement{}, "mybucket", "", `[]`}, - // Empty statements, non-empty bucket name non-empty prefix. - {[]Statement{}, "mybucket", "hello", `[]`}, - // Empty statements, empty bucket name and non-empty prefix. - {[]Statement{}, "", "hello", `[]`}, - // Statement with unknown Actions with empty prefix. - {[]Statement{{ - Actions: set.CreateStringSet("s3:ListBucketVersions", "s3:ListAllMyBuckets"), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[{"Action":["s3:ListAllMyBuckets","s3:ListBucketVersions"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Actions. - {[]Statement{{ - Actions: set.CreateStringSet("s3:ListBucketVersions", "s3:ListAllMyBuckets"), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[{"Action":["s3:ListAllMyBuckets","s3:ListBucketVersions"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Effect with empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Deny", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Deny","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Effect. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Deny", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Effect":"Deny","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Principal.User.AWS with empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("arn:aws:iam::AccountNumberWithoutHyphens:root")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["arn:aws:iam::AccountNumberWithoutHyphens:root"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Principal.User.AWS. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("arn:aws:iam::AccountNumberWithoutHyphens:root")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["arn:aws:iam::AccountNumberWithoutHyphens:root"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Principal.User.CanonicalUser with empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{CanonicalUser: set.CreateStringSet("649262f44b8145cb")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"CanonicalUser":["649262f44b8145cb"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Principal.User.CanonicalUser. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{CanonicalUser: set.CreateStringSet("649262f44b8145cb")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"CanonicalUser":["649262f44b8145cb"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Conditions with empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Conditions. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statement with unknown Resource and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::testbucket"],"Sid":""}]`}, - // Statement with unknown Resource. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::testbucket"],"Sid":""}]`}, - // Statement with known Actions with empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[]`}, - // Statement with known Actions. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[]`}, - // Statement with known multiple Actions with empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions).Union(commonBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", `[]`}, - // Statement with known multiple Actions. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions).Union(commonBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", `[]`}, - // RemoveBucketActions with readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with writeOnlyInUse. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, writeOnlyInUse. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with readOnlyInUse and writeOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readWriteObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, readOnlyInUse and writeOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readWriteObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with known Conditions, readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, known Conditions, readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, known Conditions contains other object prefix, readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap2, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["world"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with unknown Conditions, readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, unknown Conditions, readOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with known Conditions, writeOnlyInUse. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap11, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, known Conditions, writeOnlyInUse. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap11, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with unknown Conditions, writeOnlyInUse. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap11, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, unknown Conditions, writeOnlyInUse. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap11, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with known Conditions, readOnlyInUse and writeOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap12, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, known Conditions, readOnlyInUse and writeOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap12, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with unknown Conditions, readOnlyInUse and writeOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap12, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // RemoveBucketActions with prefix, unknown Conditions, readOnlyInUse and writeOnlyInUse. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap12, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/world"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/world"],"Sid":""}]`}, - // readOnlyObjectActions - RemoveObjectActions with known condition. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // readOnlyObjectActions - RemoveObjectActions with prefix, known condition. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "hello", `[]`}, - // readOnlyObjectActions - RemoveObjectActions with unknown condition. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // readOnlyObjectActions - RemoveObjectActions with prefix, unknown condition. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // writeOnlyObjectActions - RemoveObjectActions with known condition. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap13, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // writeOnlyObjectActions - RemoveObjectActions with prefix, known condition. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap13, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // writeOnlyObjectActions - RemoveObjectActions with unknown condition. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // writeOnlyObjectActions - RemoveObjectActions with prefix, unknown condition. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // readWriteObjectActions - RemoveObjectActions with known condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap14, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // readWriteObjectActions - RemoveObjectActions with prefix, known condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: knownCondMap13, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "hello", `[]`}, - // readWriteObjectActions - RemoveObjectActions with unknown condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // readWriteObjectActions - RemoveObjectActions with prefix, unknown condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, { - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }}, "mybucket", "hello", `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringNotEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - } - - for _, testCase := range testCases { - statements := removeStatements(testCase.statements, testCase.bucketName, testCase.prefix) - if data, err := json.Marshal(statements); err != nil { - t.Fatalf("unable encoding to json, %s", err) - } else if string(data) != testCase.expectedResult { - t.Fatalf("%+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } -} - -// appendStatement() is called and the result is validated. -func TestAppendStatement(t *testing.T) { - condMap := make(ConditionMap) - condKeyMap := make(ConditionKeyMap) - condKeyMap.Add("s3:prefix", set.CreateStringSet("hello")) - condMap.Add("StringEquals", condKeyMap) - - condMap1 := make(ConditionMap) - condKeyMap1 := make(ConditionKeyMap) - condKeyMap1.Add("s3:prefix", set.CreateStringSet("world")) - condMap1.Add("StringEquals", condKeyMap1) - - unknownCondMap1 := make(ConditionMap) - unknownCondKeyMap1 := make(ConditionKeyMap) - unknownCondKeyMap1.Add("s3:prefix", set.CreateStringSet("world")) - unknownCondMap1.Add("StringNotEquals", unknownCondKeyMap1) - - testCases := []struct { - statements []Statement - statement Statement - expectedResult string - }{ - // Empty statements and empty new statement. - {[]Statement{}, Statement{}, `[]`}, - // Non-empty statements and empty new statement. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{}, `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Empty statements and non-empty new statement. - {[]Statement{}, Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Append existing statement. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Append same statement with different resource. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }, `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket","arn:aws:s3:::testbucket"],"Sid":""}]`}, - // Append same statement with different actions. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Elements of new statement contains elements in statements. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket", "arn:aws:s3:::testbucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket","arn:aws:s3:::testbucket"],"Sid":""}]`}, - // Elements of new statement with conditions contains elements in statements. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket", "arn:aws:s3:::testbucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket","arn:aws:s3:::testbucket"],"Sid":""}]`}, - // Statements with condition and new statement with condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket", "arn:aws:s3:::testbucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket","arn:aws:s3:::testbucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["world"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statements with condition and same resources, and new statement with condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello","world"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statements with unknown condition and same resources, and new statement with known condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: unknownCondMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap1, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["world"]},"StringNotEquals":{"s3:prefix":["world"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statements without condition and new statement with condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket", "arn:aws:s3:::testbucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket","arn:aws:s3:::testbucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statements with condition and new statement without condition. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: condMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket", "arn:aws:s3:::testbucket"), - }}, Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, `[{"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket","arn:aws:s3:::testbucket"],"Sid":""},{"Action":["s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // Statements and new statement are different. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, Statement{ - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - } - - for _, testCase := range testCases { - statements := appendStatement(testCase.statements, testCase.statement) - if data, err := json.Marshal(statements); err != nil { - t.Fatalf("unable encoding to json, %s", err) - } else if string(data) != testCase.expectedResult { - t.Fatalf("%+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } -} - -// getBucketPolicy() is called and the result is validated. -func TestGetBucketPolicy(t *testing.T) { - helloCondMap := make(ConditionMap) - helloCondKeyMap := make(ConditionKeyMap) - helloCondKeyMap.Add("s3:prefix", set.CreateStringSet("hello")) - helloCondMap.Add("StringEquals", helloCondKeyMap) - - worldCondMap := make(ConditionMap) - worldCondKeyMap := make(ConditionKeyMap) - worldCondKeyMap.Add("s3:prefix", set.CreateStringSet("world")) - worldCondMap.Add("StringEquals", worldCondKeyMap) - - notHelloCondMap := make(ConditionMap) - notHelloCondMap.Add("StringNotEquals", worldCondKeyMap) - - testCases := []struct { - statement Statement - prefix string - expectedResult1 bool - expectedResult2 bool - expectedResult3 bool - }{ - // Statement with invalid Effect. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Deny", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with invalid Effect with prefix. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Deny", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, false}, - // Statement with invalid Principal.AWS. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("arn:aws:iam::AccountNumberWithoutHyphens:root")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with invalid Principal.AWS with prefix. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("arn:aws:iam::AccountNumberWithoutHyphens:root")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, false}, - - // Statement with commonBucketActions. - {Statement{ - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", true, false, false}, - // Statement with commonBucketActions. - {Statement{ - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", true, false, false}, - - // Statement with commonBucketActions and condition. - {Statement{ - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with commonBucketActions and condition. - {Statement{ - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, false}, - // Statement with writeOnlyBucketActions. - {Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, true}, - // Statement with writeOnlyBucketActions. - {Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, true}, - // Statement with writeOnlyBucketActions and condition - {Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with writeOnlyBucketActions and condition. - {Statement{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, false}, - // Statement with readOnlyBucketActions. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, true, false}, - // Statement with readOnlyBucketActions. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, true, false}, - // Statement with readOnlyBucketActions with empty condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with readOnlyBucketActions with empty condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, false}, - // Statement with readOnlyBucketActions with matching condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with readOnlyBucketActions with matching condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, true, false}, - - // Statement with readOnlyBucketActions with different condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: worldCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with readOnlyBucketActions with different condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: worldCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, false, false}, - - // Statement with readOnlyBucketActions with StringNotEquals condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: notHelloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "", false, false, false}, - // Statement with readOnlyBucketActions with StringNotEquals condition. - {Statement{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: notHelloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, "hello", false, true, false}, - } - - for _, testCase := range testCases { - commonFound, readOnly, writeOnly := getBucketPolicy(testCase.statement, testCase.prefix) - if !(testCase.expectedResult1 == commonFound && testCase.expectedResult2 == readOnly && testCase.expectedResult3 == writeOnly) { - t.Fatalf("%+v: expected: [%t,%t,%t], got: [%t,%t,%t]", testCase, - testCase.expectedResult1, testCase.expectedResult2, testCase.expectedResult3, - commonFound, readOnly, writeOnly) - } - } -} - -// getObjectPolicy() is called and the result is validated. -func TestGetObjectPolicy(t *testing.T) { - testCases := []struct { - statement Statement - expectedResult1 bool - expectedResult2 bool - }{ - // Statement with invalid Effect. - {Statement{ - Actions: readOnlyObjectActions, - Effect: "Deny", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, false, false}, - // Statement with invalid Principal.AWS. - {Statement{ - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("arn:aws:iam::AccountNumberWithoutHyphens:root")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, false, false}, - // Statement with condition. - {Statement{ - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: make(ConditionMap), - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, false, false}, - // Statement with readOnlyObjectActions. - {Statement{ - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, true, false}, - // Statement with writeOnlyObjectActions. - {Statement{ - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, false, true}, - // Statement with readOnlyObjectActions and writeOnlyObjectActions. - {Statement{ - Actions: readOnlyObjectActions.Union(writeOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/hello*"), - }, true, true}, - } - - for _, testCase := range testCases { - readOnly, writeOnly := getObjectPolicy(testCase.statement) - if !(testCase.expectedResult1 == readOnly && testCase.expectedResult2 == writeOnly) { - t.Fatalf("%+v: expected: [%t,%t], got: [%t,%t]", testCase, - testCase.expectedResult1, testCase.expectedResult2, - readOnly, writeOnly) - } - } -} - -// GetPolicyRules is called and the result is validated -func TestListBucketPolicies(t *testing.T) { - - // Condition for read objects - downloadCondMap := make(ConditionMap) - downloadCondKeyMap := make(ConditionKeyMap) - downloadCondKeyMap.Add("s3:prefix", set.CreateStringSet("download")) - downloadCondMap.Add("StringEquals", downloadCondKeyMap) - - // Condition for readwrite objects - downloadUploadCondMap := make(ConditionMap) - downloadUploadCondKeyMap := make(ConditionKeyMap) - downloadUploadCondKeyMap.Add("s3:prefix", set.CreateStringSet("both")) - downloadUploadCondMap.Add("StringEquals", downloadUploadCondKeyMap) - - testCases := []struct { - statements []Statement - bucketName string - prefix string - expectedResult map[string]BucketPolicy - }{ - // Empty statements, bucket name and prefix. - {[]Statement{}, "", "", map[string]BucketPolicy{}}, - // Non-empty statements, empty bucket name and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "", "", map[string]BucketPolicy{}}, - // Empty statements, non-empty bucket name and empty prefix. - {[]Statement{}, "mybucket", "", map[string]BucketPolicy{}}, - // Readonly object statement - {[]Statement{ - { - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, - { - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: downloadCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, - { - Actions: readOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/download*"), - }}, "mybucket", "", map[string]BucketPolicy{"mybucket/download*": BucketPolicyReadOnly}}, - // Write Only - {[]Statement{ - { - Actions: commonBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, - { - Actions: writeOnlyObjectActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/upload*"), - }}, "mybucket", "", map[string]BucketPolicy{"mybucket/upload*": BucketPolicyWriteOnly}}, - // Readwrite - {[]Statement{ - { - Actions: commonBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, - { - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: downloadUploadCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }, - { - Actions: writeOnlyObjectActions.Union(readOnlyObjectActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket/both*"), - }}, "mybucket", "", map[string]BucketPolicy{"mybucket/both*": BucketPolicyReadWrite}}, - } - - for _, testCase := range testCases { - policyRules := GetPolicies(testCase.statements, testCase.bucketName) - if !reflect.DeepEqual(testCase.expectedResult, policyRules) { - t.Fatalf("%+v:\n expected: %+v, got: %+v", testCase, testCase.expectedResult, policyRules) - } - } -} - -// GetPolicy() is called and the result is validated. -func TestGetPolicy(t *testing.T) { - helloCondMap := make(ConditionMap) - helloCondKeyMap := make(ConditionKeyMap) - helloCondKeyMap.Add("s3:prefix", set.CreateStringSet("hello")) - helloCondMap.Add("StringEquals", helloCondKeyMap) - - testCases := []struct { - statements []Statement - bucketName string - prefix string - expectedResult BucketPolicy - }{ - // Empty statements, bucket name and prefix. - {[]Statement{}, "", "", BucketPolicyNone}, - // Non-empty statements, empty bucket name and empty prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "", "", BucketPolicyNone}, - // Empty statements, non-empty bucket name and empty prefix. - {[]Statement{}, "mybucket", "", BucketPolicyNone}, - // not-matching Statements. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, "mybucket", "", BucketPolicyNone}, - // not-matching Statements with prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - // Statements with only commonBucketActions. - {[]Statement{{ - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", BucketPolicyNone}, - // Statements with only commonBucketActions with prefix. - {[]Statement{{ - Actions: commonBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - // Statements with only readOnlyBucketActions. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", BucketPolicyNone}, - // Statements with only readOnlyBucketActions with prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - // Statements with only readOnlyBucketActions with conditions. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", BucketPolicyNone}, - // Statements with only readOnlyBucketActions with prefix with conditons. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - // Statements with only writeOnlyBucketActions. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", BucketPolicyNone}, - // Statements with only writeOnlyBucketActions with prefix. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - // Statements with only readOnlyBucketActions + writeOnlyBucketActions. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", BucketPolicyNone}, - // Statements with only readOnlyBucketActions + writeOnlyBucketActions with prefix. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - // Statements with only readOnlyBucketActions + writeOnlyBucketActions and conditions. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "", BucketPolicyNone}, - // Statements with only readOnlyBucketActions + writeOnlyBucketActions and conditions with prefix. - {[]Statement{{ - Actions: readOnlyBucketActions.Union(writeOnlyBucketActions), - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, "mybucket", "hello", BucketPolicyNone}, - } - - for _, testCase := range testCases { - policy := GetPolicy(testCase.statements, testCase.bucketName, testCase.prefix) - if testCase.expectedResult != policy { - t.Fatalf("%+v: expected: %s, got: %s", testCase, testCase.expectedResult, policy) - } - } -} - -// SetPolicy() is called and the result is validated. -func TestSetPolicy(t *testing.T) { - helloCondMap := make(ConditionMap) - helloCondKeyMap := make(ConditionKeyMap) - helloCondKeyMap.Add("s3:prefix", set.CreateStringSet("hello")) - helloCondMap.Add("StringEquals", helloCondKeyMap) - - testCases := []struct { - statements []Statement - policy BucketPolicy - bucketName string - prefix string - expectedResult string - }{ - // BucketPolicyNone - empty statements, bucket name and prefix. - {[]Statement{}, BucketPolicyNone, "", "", `[]`}, - // BucketPolicyNone - non-empty statements, bucket name and prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyNone, "", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""}]`}, - // BucketPolicyNone - empty statements, non-empty bucket name and prefix. - {[]Statement{}, BucketPolicyNone, "mybucket", "", `[]`}, - // BucketPolicyNone - empty statements, bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyNone, "", "hello", `[]`}, - // BucketPolicyReadOnly - empty statements, bucket name and prefix. - {[]Statement{}, BucketPolicyReadOnly, "", "", `[]`}, - // BucketPolicyReadOnly - non-empty statements, bucket name and prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, BucketPolicyReadOnly, "", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::testbucket"],"Sid":""}]`}, - // BucketPolicyReadOnly - empty statements, non-empty bucket name and prefix. - {[]Statement{}, BucketPolicyReadOnly, "mybucket", "", `[{"Action":["s3:GetBucketLocation","s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // BucketPolicyReadOnly - empty statements, bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyReadOnly, "", "hello", `[]`}, - // BucketPolicyReadOnly - empty statements, non-empty bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyReadOnly, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // BucketPolicyWriteOnly - empty statements, bucket name and prefix. - {[]Statement{}, BucketPolicyReadOnly, "", "", `[]`}, - // BucketPolicyWriteOnly - non-empty statements, bucket name and prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, BucketPolicyWriteOnly, "", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::testbucket"],"Sid":""}]`}, - // BucketPolicyWriteOnly - empty statements, non-empty bucket name and prefix. - {[]Statement{}, BucketPolicyWriteOnly, "mybucket", "", `[{"Action":["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // BucketPolicyWriteOnly - empty statements, bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyWriteOnly, "", "hello", `[]`}, - // BucketPolicyWriteOnly - empty statements, non-empty bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyWriteOnly, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // BucketPolicyReadWrite - empty statements, bucket name and prefix. - {[]Statement{}, BucketPolicyReadWrite, "", "", `[]`}, - // BucketPolicyReadWrite - non-empty statements, bucket name and prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::testbucket"), - }}, BucketPolicyReadWrite, "", "", `[{"Action":["s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::testbucket"],"Sid":""}]`}, - // BucketPolicyReadWrite - empty statements, non-empty bucket name and prefix. - {[]Statement{}, BucketPolicyReadWrite, "mybucket", "", `[{"Action":["s3:GetBucketLocation","s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // BucketPolicyReadWrite - empty statements, bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyReadWrite, "", "hello", `[]`}, - // BucketPolicyReadWrite - empty statements, non-empty bucket name and non-empty prefix. - {[]Statement{}, BucketPolicyReadWrite, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // Set readonly. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyReadOnly, "mybucket", "", `[{"Action":["s3:GetBucketLocation","s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // Set readonly with prefix. - {[]Statement{{ - Actions: writeOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyReadOnly, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - // Set writeonly. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyWriteOnly, "mybucket", "", `[{"Action":["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // Set writeonly with prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyWriteOnly, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - - // Set readwrite. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyReadWrite, "mybucket", "", `[{"Action":["s3:GetBucketLocation","s3:ListBucket","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/*"],"Sid":""}]`}, - // Set readwrite with prefix. - {[]Statement{{ - Actions: readOnlyBucketActions, - Effect: "Allow", - Principal: User{AWS: set.CreateStringSet("*")}, - Conditions: helloCondMap, - Resources: set.CreateStringSet("arn:aws:s3:::mybucket"), - }}, BucketPolicyReadWrite, "mybucket", "hello", `[{"Action":["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:ListBucket"],"Condition":{"StringEquals":{"s3:prefix":["hello"]}},"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket"],"Sid":""},{"Action":["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::mybucket/hello*"],"Sid":""}]`}, - } - - for _, testCase := range testCases { - statements := SetPolicy(testCase.statements, testCase.policy, testCase.bucketName, testCase.prefix) - if data, err := json.Marshal(statements); err != nil { - t.Fatalf("unable encoding to json, %s", err) - } else if string(data) != testCase.expectedResult { - t.Fatalf("%+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data)) - } - } -} - -// Validates bucket policy string. -func TestIsValidBucketPolicy(t *testing.T) { - testCases := []struct { - inputPolicy BucketPolicy - expectedResult bool - }{ - // valid inputs. - {BucketPolicy("none"), true}, - {BucketPolicy("readonly"), true}, - {BucketPolicy("readwrite"), true}, - {BucketPolicy("writeonly"), true}, - // invalid input. - {BucketPolicy("readwriteonly"), false}, - {BucketPolicy("writeread"), false}, - } - - for i, testCase := range testCases { - actualResult := testCase.inputPolicy.IsValidBucketPolicy() - if testCase.expectedResult != actualResult { - t.Errorf("Test %d: Expected IsValidBucket policy to be '%v' for policy \"%s\", but instead found it to be '%v'", i+1, testCase.expectedResult, testCase.inputPolicy, actualResult) - } - } -} - -// Tests validate Bucket policy resource matcher. -func TestBucketPolicyResourceMatch(t *testing.T) { - - // generates\ statement with given resource.. - generateStatement := func(resource string) Statement { - statement := Statement{} - statement.Resources = set.CreateStringSet(resource) - return statement - } - - // generates resource prefix. - generateResource := func(bucketName, objectName string) string { - return awsResourcePrefix + bucketName + "/" + objectName - } - - testCases := []struct { - resourceToMatch string - statement Statement - expectedResourceMatch bool - }{ - // Test case 1-4. - // Policy with resource ending with bucket/* allows access to all objects inside the given bucket. - {generateResource("minio-bucket", ""), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/*")), true}, - {generateResource("minio-bucket", ""), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/*")), true}, - {generateResource("minio-bucket", ""), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/*")), true}, - {generateResource("minio-bucket", ""), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/*")), true}, - // Test case - 5. - // Policy with resource ending with bucket/oo* should not allow access to bucket/output.txt. - {generateResource("minio-bucket", "output.txt"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/oo*")), false}, - // Test case - 6. - // Policy with resource ending with bucket/oo* should allow access to bucket/ootput.txt. - {generateResource("minio-bucket", "ootput.txt"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/oo*")), true}, - // Test case - 7. - // Policy with resource ending with bucket/oo* allows access to all subfolders starting with "oo" inside given bucket. - {generateResource("minio-bucket", "oop-bucket/my-file"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/oo*")), true}, - // Test case - 8. - {generateResource("minio-bucket", "Asia/India/1.pjg"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/Asia/Japan/*")), false}, - // Test case - 9. - {generateResource("minio-bucket", "Asia/India/1.pjg"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, "minio-bucket"+"/Asia/Japan/*")), false}, - // Test case - 10. - // Proves that the name space is flat. - {generateResource("minio-bucket", "Africa/Bihar/India/design_info.doc/Bihar"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, - "minio-bucket"+"/*/India/*/Bihar")), true}, - // Test case - 11. - // Proves that the name space is flat. - {generateResource("minio-bucket", "Asia/China/India/States/Bihar/output.txt"), generateStatement(fmt.Sprintf("%s%s", awsResourcePrefix, - "minio-bucket"+"/*/India/*/Bihar/*")), true}, - } - for i, testCase := range testCases { - resources := testCase.statement.Resources.FuncMatch(resourceMatch, testCase.resourceToMatch) - actualResourceMatch := resources.Equals(testCase.statement.Resources) - if testCase.expectedResourceMatch != actualResourceMatch { - t.Errorf("Test %d: Expected Resource match to be `%v`, but instead found it to be `%v`", i+1, testCase.expectedResourceMatch, actualResourceMatch) - } - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go deleted file mode 100644 index 297ab97be..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3signer - -import ( - "bytes" - "io/ioutil" - "testing" - "time" -) - -func TestGetSeedSignature(t *testing.T) { - accessKeyID := "AKIAIOSFODNN7EXAMPLE" - secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" - dataLen := 66560 - data := bytes.Repeat([]byte("a"), dataLen) - body := ioutil.NopCloser(bytes.NewReader(data)) - - req := NewRequest("PUT", "/examplebucket/chunkObject.txt", body) - req.Header.Set("x-amz-storage-class", "REDUCED_REDUNDANCY") - req.Host = "s3.amazonaws.com" - - reqTime, err := time.Parse("20060102T150405Z", "20130524T000000Z") - if err != nil { - t.Fatalf("Failed to parse time - %v", err) - } - - req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", "us-east-1", int64(dataLen), reqTime) - actualSeedSignature := req.Body.(*StreamingReader).seedSignature - - expectedSeedSignature := "38cab3af09aa15ddf29e26e36236f60fb6bfb6243a20797ae9a8183674526079" - if actualSeedSignature != expectedSeedSignature { - t.Errorf("Expected %s but received %s", expectedSeedSignature, actualSeedSignature) - } -} - -func TestChunkSignature(t *testing.T) { - chunkData := bytes.Repeat([]byte("a"), 65536) - reqTime, _ := time.Parse(iso8601DateFormat, "20130524T000000Z") - previousSignature := "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9" - location := "us-east-1" - secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" - expectedSignature := "ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648" - actualSignature := buildChunkSignature(chunkData, reqTime, location, previousSignature, secretAccessKeyID) - if actualSignature != expectedSignature { - t.Errorf("Expected %s but received %s", expectedSignature, actualSignature) - } -} - -func TestSetStreamingAuthorization(t *testing.T) { - location := "us-east-1" - secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" - accessKeyID := "AKIAIOSFODNN7EXAMPLE" - - req := NewRequest("PUT", "/examplebucket/chunkObject.txt", nil) - req.Header.Set("x-amz-storage-class", "REDUCED_REDUNDANCY") - req.Host = "" - req.URL.Host = "s3.amazonaws.com" - - dataLen := int64(65 * 1024) - reqTime, _ := time.Parse(iso8601DateFormat, "20130524T000000Z") - req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime) - - expectedAuthorization := "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=38cab3af09aa15ddf29e26e36236f60fb6bfb6243a20797ae9a8183674526079" - - actualAuthorization := req.Header.Get("Authorization") - if actualAuthorization != expectedAuthorization { - t.Errorf("Expected %s but received %s", expectedAuthorization, actualAuthorization) - } -} - -func TestStreamingReader(t *testing.T) { - reqTime, _ := time.Parse("20060102T150405Z", "20130524T000000Z") - location := "us-east-1" - secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" - accessKeyID := "AKIAIOSFODNN7EXAMPLE" - dataLen := int64(65 * 1024) - - req := NewRequest("PUT", "/examplebucket/chunkObject.txt", nil) - req.Header.Set("x-amz-storage-class", "REDUCED_REDUNDANCY") - req.ContentLength = 65 * 1024 - req.Host = "" - req.URL.Host = "s3.amazonaws.com" - - baseReader := ioutil.NopCloser(bytes.NewReader(bytes.Repeat([]byte("a"), 65*1024))) - req.Body = baseReader - req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime) - - b, err := ioutil.ReadAll(req.Body) - if err != nil { - t.Errorf("Expected no error but received %v %d", err, len(b)) - } - req.Body.Close() -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v2_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v2_test.go deleted file mode 100644 index 042b6e65c..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v2_test.go +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3signer - -import ( - "sort" - "testing" -) - -// Tests for 'func TestResourceListSorting(t *testing.T)'. -func TestResourceListSorting(t *testing.T) { - sortedResourceList := make([]string, len(resourceList)) - copy(sortedResourceList, resourceList) - sort.Strings(sortedResourceList) - for i := 0; i < len(resourceList); i++ { - if resourceList[i] != sortedResourceList[i] { - t.Errorf("Expected resourceList[%d] = \"%s\", resourceList is not correctly sorted.", i, sortedResourceList[i]) - break - } - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4_test.go deleted file mode 100644 index a109a4f2a..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4_test.go +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3signer - -import ( - "io" - "net/http" - "strings" - "testing" -) - -func TestRequestHost(t *testing.T) { - req, _ := buildRequest("dynamodb", "us-east-1", "{}") - req.URL.RawQuery = "Foo=z&Foo=o&Foo=m&Foo=a" - req.Host = "myhost" - canonicalHeaders := getCanonicalHeaders(*req, v4IgnoredHeaders) - - if !strings.Contains(canonicalHeaders, "host:"+req.Host) { - t.Errorf("canonical host header invalid") - } -} - -func buildRequest(serviceName, region, body string) (*http.Request, io.ReadSeeker) { - endpoint := "https://" + serviceName + "." + region + ".amazonaws.com" - reader := strings.NewReader(body) - req, _ := http.NewRequest("POST", endpoint, reader) - req.URL.Opaque = "//example.org/bucket/key-._~,!@#$%^&*()" - req.Header.Add("X-Amz-Target", "prefix.Operation") - req.Header.Add("Content-Type", "application/x-amz-json-1.0") - req.Header.Add("Content-Length", string(len(body))) - req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)") - req.Header.Add("X-Amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)") - req.Header.Add("X-amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)") - return req, reader -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go deleted file mode 100644 index d53483e4e..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3signer - -import ( - "net/http" - "strings" - "testing" -) - -// Tests signature calculation. -func TestSignatureCalculation(t *testing.T) { - req, err := http.NewRequest("GET", "https://s3.amazonaws.com", nil) - if err != nil { - t.Fatal("Error:", err) - } - req = SignV4(*req, "", "", "", "us-east-1") - if req.Header.Get("Authorization") != "" { - t.Fatal("Error: anonymous credentials should not have Authorization header.") - } - - req = PreSignV4(*req, "", "", "", "us-east-1", 0) - if strings.Contains(req.URL.RawQuery, "X-Amz-Signature") { - t.Fatal("Error: anonymous credentials should not have Signature query resource.") - } - - req = SignV2(*req, "", "") - if req.Header.Get("Authorization") != "" { - t.Fatal("Error: anonymous credentials should not have Authorization header.") - } - - req = PreSignV2(*req, "", "", 0) - if strings.Contains(req.URL.RawQuery, "Signature") { - t.Fatal("Error: anonymous credentials should not have Signature query resource.") - } - - req = SignV4(*req, "ACCESS-KEY", "SECRET-KEY", "", "us-east-1") - if req.Header.Get("Authorization") == "" { - t.Fatal("Error: normal credentials should have Authorization header.") - } - - req = PreSignV4(*req, "ACCESS-KEY", "SECRET-KEY", "", "us-east-1", 0) - if !strings.Contains(req.URL.RawQuery, "X-Amz-Signature") { - t.Fatal("Error: normal credentials should have Signature query resource.") - } - - req = SignV2(*req, "ACCESS-KEY", "SECRET-KEY") - if req.Header.Get("Authorization") == "" { - t.Fatal("Error: normal credentials should have Authorization header.") - } - - req = PreSignV2(*req, "ACCESS-KEY", "SECRET-KEY", 0) - if !strings.Contains(req.URL.RawQuery, "Signature") { - t.Fatal("Error: normal credentials should not have Signature query resource.") - } -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/test-utils_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/test-utils_test.go deleted file mode 100644 index cf96d66c8..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3signer/test-utils_test.go +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3signer - -import ( - "bufio" - "bytes" - "crypto/tls" - "io" - "io/ioutil" - "net/http" - "strings" -) - -// N B minio-go should compile on go1.5.3 onwards and httptest package is -// available only from go.1.7.x. The following function is taken from -// Go httptest package to be able to build on older versions of Go. - -// NewRequest returns a new incoming server Request, suitable -// for passing to an http.Handler for testing. -// -// The target is the RFC 7230 "request-target": it may be either a -// path or an absolute URL. If target is an absolute URL, the host name -// from the URL is used. Otherwise, "example.com" is used. -// -// The TLS field is set to a non-nil dummy value if target has scheme -// "https". -// -// The Request.Proto is always HTTP/1.1. -// -// An empty method means "GET". -// -// The provided body may be nil. If the body is of type *bytes.Reader, -// *strings.Reader, or *bytes.Buffer, the Request.ContentLength is -// set. -// -// NewRequest panics on error for ease of use in testing, where a -// panic is acceptable. -func NewRequest(method, target string, body io.Reader) *http.Request { - if method == "" { - method = "GET" - } - req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(method + " " + target + " HTTP/1.0\r\n\r\n"))) - if err != nil { - panic("invalid NewRequest arguments; " + err.Error()) - } - - // HTTP/1.0 was used above to avoid needing a Host field. Change it to 1.1 here. - req.Proto = "HTTP/1.1" - req.ProtoMinor = 1 - req.Close = false - - if body != nil { - switch v := body.(type) { - case *bytes.Buffer: - req.ContentLength = int64(v.Len()) - case *bytes.Reader: - req.ContentLength = int64(v.Len()) - case *strings.Reader: - req.ContentLength = int64(v.Len()) - default: - req.ContentLength = -1 - } - if rc, ok := body.(io.ReadCloser); ok { - req.Body = rc - } else { - req.Body = ioutil.NopCloser(body) - } - } - - // 192.0.2.0/24 is "TEST-NET" in RFC 5737 for use solely in - // documentation and example source code and should not be - // used publicly. - req.RemoteAddr = "192.0.2.1:1234" - - if req.Host == "" { - req.Host = "example.com" - } - - if strings.HasPrefix(target, "https://") { - req.TLS = &tls.ConnectionState{ - Version: tls.VersionTLS12, - HandshakeComplete: true, - ServerName: req.Host, - } - } - - return req -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/utils_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/utils_test.go deleted file mode 100644 index 407eddab3..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3signer/utils_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3signer - -import ( - "fmt" - "net/http" - "net/url" - "testing" -) - -// Tests url encoding. -func TestEncodeURL2Path(t *testing.T) { - type urlStrings struct { - bucketName string - objName string - encodedObjName string - } - - bucketName := "bucketName" - want := []urlStrings{ - { - bucketName: "bucketName", - objName: "本語", - encodedObjName: "%E6%9C%AC%E8%AA%9E", - }, - { - bucketName: "bucketName", - objName: "本語.1", - encodedObjName: "%E6%9C%AC%E8%AA%9E.1", - }, - { - objName: ">123>3123123", - bucketName: "bucketName", - encodedObjName: "%3E123%3E3123123", - }, - { - bucketName: "bucketName", - objName: "test 1 2.txt", - encodedObjName: "test%201%202.txt", - }, - { - bucketName: "test.bucketName", - objName: "test++ 1.txt", - encodedObjName: "test%2B%2B%201.txt", - }, - } - - for _, o := range want { - u, err := url.Parse(fmt.Sprintf("https://%s.s3.amazonaws.com/%s", bucketName, o.objName)) - if err != nil { - t.Fatal("Error:", err) - } - urlPath := "/" + bucketName + "/" + o.encodedObjName - if urlPath != encodeURL2Path(&http.Request{URL: u}) { - t.Fatal("Error") - } - } - -} diff --git a/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go b/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go deleted file mode 100644 index 55eaaeacf..000000000 --- a/vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package s3utils - -import ( - "errors" - "net/url" - "testing" -) - -// Tests get region from host URL. -func TestGetRegionFromURL(t *testing.T) { - testCases := []struct { - u url.URL - expectedRegion string - }{ - { - u: url.URL{Host: "storage.googleapis.com"}, - expectedRegion: "", - }, - { - u: url.URL{Host: "s3.cn-north-1.amazonaws.com.cn"}, - expectedRegion: "cn-north-1", - }, - { - u: url.URL{Host: "s3.cn-northwest-1.amazonaws.com.cn"}, - expectedRegion: "cn-northwest-1", - }, - { - u: url.URL{Host: "s3-fips-us-gov-west-1.amazonaws.com"}, - expectedRegion: "us-gov-west-1", - }, - { - u: url.URL{Host: "s3-us-gov-west-1.amazonaws.com"}, - expectedRegion: "us-gov-west-1", - }, - { - u: url.URL{Host: "192.168.1.1"}, - expectedRegion: "", - }, - { - u: url.URL{Host: "s3-eu-west-1.amazonaws.com"}, - expectedRegion: "eu-west-1", - }, - { - u: url.URL{Host: "s3.eu-west-1.amazonaws.com"}, - expectedRegion: "eu-west-1", - }, - { - u: url.URL{Host: "s3.dualstack.eu-west-1.amazonaws.com"}, - expectedRegion: "eu-west-1", - }, - { - u: url.URL{Host: "s3.amazonaws.com"}, - expectedRegion: "", - }, - { - u: url.URL{Host: "s3-external-1.amazonaws.com"}, - expectedRegion: "", - }, - } - - for i, testCase := range testCases { - region := GetRegionFromURL(testCase.u) - if testCase.expectedRegion != region { - t.Errorf("Test %d: Expected region %s, got %s", i+1, testCase.expectedRegion, region) - } - } -} - -// Tests for 'isValidDomain(host string) bool'. -func TestIsValidDomain(t *testing.T) { - testCases := []struct { - // Input. - host string - // Expected result. - result bool - }{ - {"s3.amazonaws.com", true}, - {"s3.cn-north-1.amazonaws.com.cn", true}, - {"s3.cn-northwest-1.amazonaws.com.cn", true}, - {"s3.amazonaws.com_", false}, - {"%$$$", false}, - {"s3.amz.test.com", true}, - {"s3.%%", false}, - {"localhost", true}, - {"-localhost", false}, - {"", false}, - {"\n \t", false}, - {" ", false}, - } - - for i, testCase := range testCases { - result := IsValidDomain(testCase.host) - if testCase.result != result { - t.Errorf("Test %d: Expected isValidDomain test to be '%v', but found '%v' instead", i+1, testCase.result, result) - } - } -} - -// Tests validate IP address validator. -func TestIsValidIP(t *testing.T) { - testCases := []struct { - // Input. - ip string - // Expected result. - result bool - }{ - {"192.168.1.1", true}, - {"192.168.1", false}, - {"192.168.1.1.1", false}, - {"-192.168.1.1", false}, - {"260.192.1.1", false}, - } - - for i, testCase := range testCases { - result := IsValidIP(testCase.ip) - if testCase.result != result { - t.Errorf("Test %d: Expected isValidIP to be '%v' for input \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.ip, result) - } - } - -} - -// Tests validate virtual host validator. -func TestIsVirtualHostSupported(t *testing.T) { - testCases := []struct { - url string - bucket string - // Expeceted result. - result bool - }{ - {"https://s3.amazonaws.com", "my-bucket", true}, - {"https://s3.cn-north-1.amazonaws.com.cn", "my-bucket", true}, - {"https://s3.amazonaws.com", "my-bucket.", false}, - {"https://amazons3.amazonaws.com", "my-bucket.", false}, - {"https://storage.googleapis.com/", "my-bucket", true}, - {"https://mystorage.googleapis.com/", "my-bucket", false}, - } - - for i, testCase := range testCases { - u, err := url.Parse(testCase.url) - if err != nil { - t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err) - } - result := IsVirtualHostSupported(*u, testCase.bucket) - if testCase.result != result { - t.Errorf("Test %d: Expected isVirtualHostSupported to be '%v' for input url \"%s\" and bucket \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.url, testCase.bucket, result) - } - } -} - -// Tests validate Amazon endpoint validator. -func TestIsAmazonEndpoint(t *testing.T) { - testCases := []struct { - url string - // Expected result. - result bool - }{ - {"https://192.168.1.1", false}, - {"192.168.1.1", false}, - {"http://storage.googleapis.com", false}, - {"https://storage.googleapis.com", false}, - {"storage.googleapis.com", false}, - {"s3.amazonaws.com", false}, - {"https://amazons3.amazonaws.com", false}, - {"-192.168.1.1", false}, - {"260.192.1.1", false}, - {"https://s3-.amazonaws.com", false}, - {"https://s3..amazonaws.com", false}, - {"https://s3.dualstack.us-west-1.amazonaws.com.cn", false}, - {"https://s3..us-west-1.amazonaws.com.cn", false}, - // valid inputs. - {"https://s3.amazonaws.com", true}, - {"https://s3-external-1.amazonaws.com", true}, - {"https://s3.cn-north-1.amazonaws.com.cn", true}, - {"https://s3-us-west-1.amazonaws.com", true}, - {"https://s3.us-west-1.amazonaws.com", true}, - {"https://s3.dualstack.us-west-1.amazonaws.com", true}, - } - - for i, testCase := range testCases { - u, err := url.Parse(testCase.url) - if err != nil { - t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err) - } - result := IsAmazonEndpoint(*u) - if testCase.result != result { - t.Errorf("Test %d: Expected isAmazonEndpoint to be '%v' for input \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.url, result) - } - } - -} - -// Tests validate Google Cloud end point validator. -func TestIsGoogleEndpoint(t *testing.T) { - testCases := []struct { - url string - // Expected result. - result bool - }{ - {"192.168.1.1", false}, - {"https://192.168.1.1", false}, - {"s3.amazonaws.com", false}, - {"http://s3.amazonaws.com", false}, - {"https://s3.amazonaws.com", false}, - {"https://s3.cn-north-1.amazonaws.com.cn", false}, - {"-192.168.1.1", false}, - {"260.192.1.1", false}, - // valid inputs. - {"http://storage.googleapis.com", true}, - {"https://storage.googleapis.com", true}, - } - - for i, testCase := range testCases { - u, err := url.Parse(testCase.url) - if err != nil { - t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err) - } - result := IsGoogleEndpoint(*u) - if testCase.result != result { - t.Errorf("Test %d: Expected isGoogleEndpoint to be '%v' for input \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.url, result) - } - } - -} - -func TestPercentEncodeSlash(t *testing.T) { - testCases := []struct { - input string - output string - }{ - {"test123", "test123"}, - {"abc,+_1", "abc,+_1"}, - {"%40prefix=test%40123", "%40prefix=test%40123"}, - {"key1=val1/val2", "key1=val1%2Fval2"}, - {"%40prefix=test%40123/", "%40prefix=test%40123%2F"}, - } - - for i, testCase := range testCases { - receivedOutput := percentEncodeSlash(testCase.input) - if testCase.output != receivedOutput { - t.Errorf( - "Test %d: Input: \"%s\" --> Expected percentEncodeSlash to return \"%s\", but it returned \"%s\" instead!", - i+1, testCase.input, testCase.output, - receivedOutput, - ) - - } - } -} - -// Tests validate the query encoder. -func TestQueryEncode(t *testing.T) { - testCases := []struct { - queryKey string - valueToEncode []string - // Expected result. - result string - }{ - {"prefix", []string{"test@123", "test@456"}, "prefix=test%40123&prefix=test%40456"}, - {"@prefix", []string{"test@123"}, "%40prefix=test%40123"}, - {"@prefix", []string{"a/b/c/"}, "%40prefix=a%2Fb%2Fc%2F"}, - {"prefix", []string{"test#123"}, "prefix=test%23123"}, - {"prefix#", []string{"test#123"}, "prefix%23=test%23123"}, - {"prefix", []string{"test123"}, "prefix=test123"}, - {"prefix", []string{"test本語123", "test123"}, "prefix=test%E6%9C%AC%E8%AA%9E123&prefix=test123"}, - } - - for i, testCase := range testCases { - urlValues := make(url.Values) - for _, valueToEncode := range testCase.valueToEncode { - urlValues.Add(testCase.queryKey, valueToEncode) - } - result := QueryEncode(urlValues) - if testCase.result != result { - t.Errorf("Test %d: Expected queryEncode result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result) - } - } -} - -// Tests validate the URL path encoder. -func TestEncodePath(t *testing.T) { - testCases := []struct { - // Input. - inputStr string - // Expected result. - result string - }{ - {"thisisthe%url", "thisisthe%25url"}, - {"本語", "%E6%9C%AC%E8%AA%9E"}, - {"本語.1", "%E6%9C%AC%E8%AA%9E.1"}, - {">123", "%3E123"}, - {"myurl#link", "myurl%23link"}, - {"space in url", "space%20in%20url"}, - {"url+path", "url%2Bpath"}, - } - - for i, testCase := range testCases { - result := EncodePath(testCase.inputStr) - if testCase.result != result { - t.Errorf("Test %d: Expected queryEncode result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result) - } - } -} - -// Tests validate the bucket name validator. -func TestIsValidBucketName(t *testing.T) { - testCases := []struct { - // Input. - bucketName string - // Expected result. - err error - // Flag to indicate whether test should Pass. - shouldPass bool - }{ - {".mybucket", errors.New("Bucket name contains invalid characters"), false}, - {"$mybucket", errors.New("Bucket name contains invalid characters"), false}, - {"mybucket-", errors.New("Bucket name contains invalid characters"), false}, - {"my", errors.New("Bucket name cannot be smaller than 3 characters"), false}, - {"", errors.New("Bucket name cannot be empty"), false}, - {"my..bucket", errors.New("Bucket name contains invalid characters"), false}, - {"192.168.1.168", errors.New("Bucket name cannot be an ip address"), false}, - {":bucketname", errors.New("Bucket name contains invalid characters"), false}, - {"_bucketName", errors.New("Bucket name contains invalid characters"), false}, - {"my.bucket.com", nil, true}, - {"my-bucket", nil, true}, - {"123my-bucket", nil, true}, - {"Mybucket", nil, true}, - {"My_bucket", nil, true}, - {"My:bucket", nil, true}, - } - - for i, testCase := range testCases { - err := CheckValidBucketName(testCase.bucketName) - if err != nil && testCase.shouldPass { - t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error()) - } - if err == nil && !testCase.shouldPass { - t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error()) - } - // Failed as expected, but does it fail for the expected reason. - if err != nil && !testCase.shouldPass { - if err.Error() != testCase.err.Error() { - t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error()) - } - } - - } - -} - -// Tests validate the bucket name validator stricter. -func TestIsValidBucketNameStrict(t *testing.T) { - testCases := []struct { - // Input. - bucketName string - // Expected result. - err error - // Flag to indicate whether test should Pass. - shouldPass bool - }{ - {".mybucket", errors.New("Bucket name contains invalid characters"), false}, - {"$mybucket", errors.New("Bucket name contains invalid characters"), false}, - {"mybucket-", errors.New("Bucket name contains invalid characters"), false}, - {"my", errors.New("Bucket name cannot be smaller than 3 characters"), false}, - {"", errors.New("Bucket name cannot be empty"), false}, - {"my..bucket", errors.New("Bucket name contains invalid characters"), false}, - {"192.168.1.168", errors.New("Bucket name cannot be an ip address"), false}, - {"Mybucket", errors.New("Bucket name contains invalid characters"), false}, - {"my.bucket.com", nil, true}, - {"my-bucket", nil, true}, - {"123my-bucket", nil, true}, - } - - for i, testCase := range testCases { - err := CheckValidBucketNameStrict(testCase.bucketName) - if err != nil && testCase.shouldPass { - t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error()) - } - if err == nil && !testCase.shouldPass { - t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error()) - } - // Failed as expected, but does it fail for the expected reason. - if err != nil && !testCase.shouldPass { - if err.Error() != testCase.err.Error() { - t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error()) - } - } - - } - -} diff --git a/vendor/github.com/minio/minio-go/pkg/set/stringset_test.go b/vendor/github.com/minio/minio-go/pkg/set/stringset_test.go deleted file mode 100644 index d7e6aa799..000000000 --- a/vendor/github.com/minio/minio-go/pkg/set/stringset_test.go +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2015-2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package set - -import ( - "fmt" - "strings" - "testing" -) - -// NewStringSet() is called and the result is validated. -func TestNewStringSet(t *testing.T) { - if ss := NewStringSet(); !ss.IsEmpty() { - t.Fatalf("expected: true, got: false") - } -} - -// CreateStringSet() is called and the result is validated. -func TestCreateStringSet(t *testing.T) { - ss := CreateStringSet("foo") - if str := ss.String(); str != `[foo]` { - t.Fatalf("expected: %s, got: %s", `["foo"]`, str) - } -} - -// CopyStringSet() is called and the result is validated. -func TestCopyStringSet(t *testing.T) { - ss := CreateStringSet("foo") - sscopy := CopyStringSet(ss) - if !ss.Equals(sscopy) { - t.Fatalf("expected: %s, got: %s", ss, sscopy) - } -} - -// StringSet.Add() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetAdd(t *testing.T) { - testCases := []struct { - value string - expectedResult string - }{ - // Test first addition. - {"foo", `[foo]`}, - // Test duplicate addition. - {"foo", `[foo]`}, - // Test new addition. - {"bar", `[bar foo]`}, - } - - ss := NewStringSet() - for _, testCase := range testCases { - ss.Add(testCase.value) - if str := ss.String(); str != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str) - } - } -} - -// StringSet.Remove() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetRemove(t *testing.T) { - ss := CreateStringSet("foo", "bar") - testCases := []struct { - value string - expectedResult string - }{ - // Test removing non-existen item. - {"baz", `[bar foo]`}, - // Test remove existing item. - {"foo", `[bar]`}, - // Test remove existing item again. - {"foo", `[bar]`}, - // Test remove to make set to empty. - {"bar", `[]`}, - } - - for _, testCase := range testCases { - ss.Remove(testCase.value) - if str := ss.String(); str != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str) - } - } -} - -// StringSet.Contains() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetContains(t *testing.T) { - ss := CreateStringSet("foo") - testCases := []struct { - value string - expectedResult bool - }{ - // Test to check non-existent item. - {"bar", false}, - // Test to check existent item. - {"foo", true}, - // Test to verify case sensitivity. - {"Foo", false}, - } - - for _, testCase := range testCases { - if result := ss.Contains(testCase.value); result != testCase.expectedResult { - t.Fatalf("expected: %t, got: %t", testCase.expectedResult, result) - } - } -} - -// StringSet.FuncMatch() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetFuncMatch(t *testing.T) { - ss := CreateStringSet("foo", "bar") - testCases := []struct { - matchFn func(string, string) bool - value string - expectedResult string - }{ - // Test to check match function doing case insensive compare. - {func(setValue string, compareValue string) bool { - return strings.ToUpper(setValue) == strings.ToUpper(compareValue) - }, "Bar", `[bar]`}, - // Test to check match function doing prefix check. - {func(setValue string, compareValue string) bool { - return strings.HasPrefix(compareValue, setValue) - }, "foobar", `[foo]`}, - } - - for _, testCase := range testCases { - s := ss.FuncMatch(testCase.matchFn, testCase.value) - if result := s.String(); result != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result) - } - } -} - -// StringSet.ApplyFunc() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetApplyFunc(t *testing.T) { - ss := CreateStringSet("foo", "bar") - testCases := []struct { - applyFn func(string) string - expectedResult string - }{ - // Test to apply function prepending a known string. - {func(setValue string) string { return "mybucket/" + setValue }, `[mybucket/bar mybucket/foo]`}, - // Test to apply function modifying values. - {func(setValue string) string { return setValue[1:] }, `[ar oo]`}, - } - - for _, testCase := range testCases { - s := ss.ApplyFunc(testCase.applyFn) - if result := s.String(); result != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result) - } - } -} - -// StringSet.Equals() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetEquals(t *testing.T) { - testCases := []struct { - set1 StringSet - set2 StringSet - expectedResult bool - }{ - // Test equal set - {CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), true}, - // Test second set with more items - {CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar", "baz"), false}, - // Test second set with less items - {CreateStringSet("foo", "bar"), CreateStringSet("bar"), false}, - } - - for _, testCase := range testCases { - if result := testCase.set1.Equals(testCase.set2); result != testCase.expectedResult { - t.Fatalf("expected: %t, got: %t", testCase.expectedResult, result) - } - } -} - -// StringSet.Intersection() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetIntersection(t *testing.T) { - testCases := []struct { - set1 StringSet - set2 StringSet - expectedResult StringSet - }{ - // Test intersecting all values. - {CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar")}, - // Test intersecting all values in second set. - {CreateStringSet("foo", "bar", "baz"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar")}, - // Test intersecting different values in second set. - {CreateStringSet("foo", "baz"), CreateStringSet("baz", "bar"), CreateStringSet("baz")}, - // Test intersecting none. - {CreateStringSet("foo", "baz"), CreateStringSet("poo", "bar"), NewStringSet()}, - } - - for _, testCase := range testCases { - if result := testCase.set1.Intersection(testCase.set2); !result.Equals(testCase.expectedResult) { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result) - } - } -} - -// StringSet.Difference() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetDifference(t *testing.T) { - testCases := []struct { - set1 StringSet - set2 StringSet - expectedResult StringSet - }{ - // Test differing none. - {CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), NewStringSet()}, - // Test differing in first set. - {CreateStringSet("foo", "bar", "baz"), CreateStringSet("foo", "bar"), CreateStringSet("baz")}, - // Test differing values in both set. - {CreateStringSet("foo", "baz"), CreateStringSet("baz", "bar"), CreateStringSet("foo")}, - // Test differing all values. - {CreateStringSet("foo", "baz"), CreateStringSet("poo", "bar"), CreateStringSet("foo", "baz")}, - } - - for _, testCase := range testCases { - if result := testCase.set1.Difference(testCase.set2); !result.Equals(testCase.expectedResult) { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result) - } - } -} - -// StringSet.Union() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetUnion(t *testing.T) { - testCases := []struct { - set1 StringSet - set2 StringSet - expectedResult StringSet - }{ - // Test union same values. - {CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar")}, - // Test union same values in second set. - {CreateStringSet("foo", "bar", "baz"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar", "baz")}, - // Test union different values in both set. - {CreateStringSet("foo", "baz"), CreateStringSet("baz", "bar"), CreateStringSet("foo", "baz", "bar")}, - // Test union all different values. - {CreateStringSet("foo", "baz"), CreateStringSet("poo", "bar"), CreateStringSet("foo", "baz", "poo", "bar")}, - } - - for _, testCase := range testCases { - if result := testCase.set1.Union(testCase.set2); !result.Equals(testCase.expectedResult) { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result) - } - } -} - -// StringSet.MarshalJSON() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetMarshalJSON(t *testing.T) { - testCases := []struct { - set StringSet - expectedResult string - }{ - // Test set with values. - {CreateStringSet("foo", "bar"), `["bar","foo"]`}, - // Test empty set. - {NewStringSet(), "[]"}, - } - - for _, testCase := range testCases { - if result, _ := testCase.set.MarshalJSON(); string(result) != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, string(result)) - } - } -} - -// StringSet.UnmarshalJSON() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetUnmarshalJSON(t *testing.T) { - testCases := []struct { - data []byte - expectedResult string - }{ - // Test to convert JSON array to set. - {[]byte(`["bar","foo"]`), `[bar foo]`}, - // Test to convert JSON string to set. - {[]byte(`"bar"`), `[bar]`}, - // Test to convert JSON empty array to set. - {[]byte(`[]`), `[]`}, - // Test to convert JSON empty string to set. - {[]byte(`""`), `[]`}, - } - - for _, testCase := range testCases { - var set StringSet - set.UnmarshalJSON(testCase.data) - if result := set.String(); result != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result) - } - } -} - -// StringSet.String() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetString(t *testing.T) { - testCases := []struct { - set StringSet - expectedResult string - }{ - // Test empty set. - {NewStringSet(), `[]`}, - // Test set with empty value. - {CreateStringSet(""), `[]`}, - // Test set with value. - {CreateStringSet("foo"), `[foo]`}, - } - - for _, testCase := range testCases { - if str := testCase.set.String(); str != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str) - } - } -} - -// StringSet.ToSlice() is called with series of cases for valid and erroneous inputs and the result is validated. -func TestStringSetToSlice(t *testing.T) { - testCases := []struct { - set StringSet - expectedResult string - }{ - // Test empty set. - {NewStringSet(), `[]`}, - // Test set with empty value. - {CreateStringSet(""), `[]`}, - // Test set with value. - {CreateStringSet("foo"), `[foo]`}, - // Test set with value. - {CreateStringSet("foo", "bar"), `[bar foo]`}, - } - - for _, testCase := range testCases { - sslice := testCase.set.ToSlice() - if str := fmt.Sprintf("%s", sslice); str != testCase.expectedResult { - t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str) - } - } -} |