You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1466 lines
47 KiB

package s3acl
import (
"bytes"
"encoding/json"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3account"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
"io"
"net/http"
"testing"
)
var (
accountManager = &s3account.AccountManager{
IdNameMapping: map[string]string{
s3account.AccountAdmin.Id: s3account.AccountAdmin.Name,
s3account.AccountAnonymous.Id: s3account.AccountAnonymous.Name,
"accountA": "accountA",
"accountB": "accountB",
},
EmailIdMapping: map[string]string{
s3account.AccountAdmin.EmailAddress: s3account.AccountAdmin.Id,
s3account.AccountAnonymous.EmailAddress: s3account.AccountAnonymous.Id,
"accountA@example.com": "accountA",
"accountBexample.com": "accountB",
},
}
)
func TestGetAccountId(t *testing.T) {
req := &http.Request{
Header: make(map[string][]string),
}
//case1
//accountId: "admin"
req.Header.Set(s3_constants.AmzAccountId, s3account.AccountAdmin.Id)
if GetAccountId(req) != s3account.AccountAdmin.Id {
t.Fatal("expect accountId: admin")
}
//case2
//accountId: "anoymous"
req.Header.Set(s3_constants.AmzAccountId, s3account.AccountAnonymous.Id)
if GetAccountId(req) != s3account.AccountAnonymous.Id {
t.Fatal("expect accountId: anonymous")
}
//case3
//accountId is nil => "anonymous"
req.Header.Del(s3_constants.AmzAccountId)
if GetAccountId(req) != s3account.AccountAnonymous.Id {
t.Fatal("expect accountId: anonymous")
}
}
func grantsEquals(a, b []*s3.Grant) bool {
if len(a) != len(b) {
return false
}
for i, grant := range a {
if !GrantEquals(grant, b[i]) {
return false
}
}
return true
}
func TestDetermineReqGrants(t *testing.T) {
{
//case1: request account is anonymous
accountId := s3account.AccountAnonymous.Id
reqPermission := s3_constants.PermissionRead
resultGrants := DetermineRequiredGrants(accountId, reqPermission)
expectGrants := []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
Permission: &reqPermission,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountId,
},
Permission: &reqPermission,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountId,
},
Permission: &s3_constants.PermissionFullControl,
},
}
if !grantsEquals(resultGrants, expectGrants) {
t.Fatalf("grants not expect")
}
}
{
//case2: request account is not anonymous (Iam authed)
accountId := "accountX"
reqPermission := s3_constants.PermissionRead
resultGrants := DetermineRequiredGrants(accountId, reqPermission)
expectGrants := []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
Permission: &reqPermission,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountId,
},
Permission: &reqPermission,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAuthenticatedUsers,
},
Permission: &reqPermission,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAuthenticatedUsers,
},
Permission: &s3_constants.PermissionFullControl,
},
}
if !grantsEquals(resultGrants, expectGrants) {
t.Fatalf("grants not expect")
}
}
}
func TestAssembleEntryWithAcp(t *testing.T) {
defaultOwner := "admin"
//case1
//assemble with non-empty grants
expectOwner := "accountS"
expectGrants := []*s3.Grant{
{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
URI: &s3_constants.GranteeGroupAllUsers,
},
},
}
entry := &filer_pb.Entry{}
AssembleEntryWithAcp(entry, expectOwner, expectGrants)
resultOwner := GetAcpOwner(entry.Extended, defaultOwner)
if resultOwner != expectOwner {
t.Fatalf("owner not expect")
}
resultGrants := GetAcpGrants(nil, entry.Extended)
if !grantsEquals(resultGrants, expectGrants) {
t.Fatal("grants not expect")
}
//case2
//assemble with empty grants (override)
AssembleEntryWithAcp(entry, "", nil)
resultOwner = GetAcpOwner(entry.Extended, defaultOwner)
if resultOwner != defaultOwner {
t.Fatalf("owner not expect")
}
resultGrants = GetAcpGrants(nil, entry.Extended)
if len(resultGrants) != 0 {
t.Fatal("grants not expect")
}
}
func TestGrantEquals(t *testing.T) {
testCases := map[bool]bool{
GrantEquals(nil, nil): true,
GrantEquals(&s3.Grant{}, nil): false,
GrantEquals(&s3.Grant{}, &s3.Grant{}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
}, &s3.Grant{}): false,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{},
}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{},
}): false,
//type not present, compare other fields of grant is meaningless
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
ID: &s3account.AccountAdmin.Id,
EmailAddress: &s3account.AccountAdmin.EmailAddress,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
ID: &s3account.AccountAdmin.Id,
},
}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
},
}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionWrite,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
}): false,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
},
}): true,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
URI: &s3_constants.GranteeGroupAllUsers,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
},
}): false,
GrantEquals(&s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
URI: &s3_constants.GranteeGroupAllUsers,
},
}, &s3.Grant{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
}): true,
}
for tc, expect := range testCases {
if tc != expect {
t.Fatal("TestGrantEquals not expect!")
}
}
}
func TestSetAcpOwnerHeader(t *testing.T) {
ownerId := "accountZ"
req := &http.Request{
Header: make(map[string][]string),
}
SetAcpOwnerHeader(req, ownerId)
if req.Header.Get(s3_constants.ExtAmzOwnerKey) != ownerId {
t.Fatalf("owner unexpect")
}
}
func TestSetAcpGrantsHeader(t *testing.T) {
req := &http.Request{
Header: make(map[string][]string),
}
grants := []*s3.Grant{
{
Permission: &s3_constants.PermissionRead,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
ID: &s3account.AccountAdmin.Id,
URI: &s3_constants.GranteeGroupAllUsers,
},
},
}
SetAcpGrantsHeader(req, grants)
grantsJson, _ := json.Marshal(grants)
if req.Header.Get(s3_constants.ExtAmzAclKey) != string(grantsJson) {
t.Fatalf("owner unexpect")
}
}
func TestGrantWithFullControl(t *testing.T) {
accountId := "Accountaskdfj"
expect := &s3.Grant{
Permission: &s3_constants.PermissionFullControl,
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountId,
},
}
result := GrantWithFullControl(accountId)
if !GrantEquals(result, expect) {
t.Fatal("GrantWithFullControl not expect")
}
}
func TestExtractObjectAcl(t *testing.T) {
type Case struct {
id string
resultErrCode, expectErrCode s3err.ErrorCode
resultGrants, expectGrants []*s3.Grant
resultOwnerId, expectOwnerId string
}
testCases := make([]*Case, 0)
accountAdminId := "admin"
//Request body to specify AccessControlList
{
//ownership: ObjectWriter
//s3:PutObjectAcl('createObject' is set to false), config acl through request body
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-ObjectWriter, createObject-false, acl-requestBody",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountAdminId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, accountAdminId,
})
}
{
//ownership: BucketOwnerEnforced (extra acl is not allowed)
//s3:PutObjectAcl('createObject' is set to false), config acl through request body
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-false, acl-requestBody",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
{
//ownership: ObjectWriter
//s3:PutObject('createObject' is set to false), request body will be ignored when parse acl
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-ObjectWriter, createObject-true, acl-requestBody",
errCode, s3err.ErrNone,
grants, []*s3.Grant{},
ownerId, "",
})
}
{
//ownership: BucketOwnerEnforced (extra acl is not allowed)
//s3:PutObject('createObject' is set to true), request body will be ignored when parse acl
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-true, acl-requestBody",
errCode, s3err.ErrNone,
grants, []*s3.Grant{},
ownerId, "",
})
}
//CannedAcl Header to specify ACL
//cannedAcl, putObjectACL
{
//ownership: ObjectWriter
//s3:PutObjectACL('createObject' is set to false), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-ObjectWriter, createObject-false, acl-CannedAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutObjectACL('createObject' is set to false), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-false, acl-CannedAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutObjectACL('createObject' is set to false), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-false, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
//cannedACL, putObject
{
//ownership: ObjectWriter
//s3:PutObject('createObject' is set to true), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-ObjectWriter, createObject-true, acl-CannedAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutObject('createObject' is set to true), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-true, acl-CannedAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutObject('createObject' is set to true), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-true, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
//cannedAcl, putObjectACL
{
//ownership: ObjectWriter
//s3:PutObjectACL('createObject' is set to false), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-ObjectWriter, createObject-false, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutObjectACL('createObject' is set to false), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-false, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutObjectACL('createObject' is set to false), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-false, acl-customAcl",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
//customAcl, putObject
{
//ownership: ObjectWriter
//s3:PutObject('createObject' is set to true), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-ObjectWriter, createObject-true, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutObject('createObject' is set to true), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-true, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
ownerId, "",
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutObject('createObject' is set to true), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-true, acl-customAcl",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
{
//parse acp from request header: both canned acl and custom acl not allowed
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
req.Header.Set(s3_constants.AmzCannedAcl, "private")
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "Only one of cannedAcl, customAcl is allowed",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
})
}
{
//Acl can only be specified in one of requestBody, cannedAcl, customAcl, simultaneous use is not allowed
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
req.Header.Set(s3_constants.AmzCannedAcl, "private")
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
_, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "Only one of requestBody, cannedAcl, customAcl is allowed",
resultErrCode: errCode, expectErrCode: s3err.ErrUnexpectedContent,
})
}
for _, tc := range testCases {
if tc.resultErrCode != tc.expectErrCode {
t.Fatalf("case[%s]: errorCode[%v] not expect[%v]", tc.id, s3err.GetAPIError(tc.resultErrCode).Code, s3err.GetAPIError(tc.expectErrCode).Code)
}
if !grantsEquals(tc.resultGrants, tc.expectGrants) {
t.Fatalf("case[%s]: grants not expect", tc.id)
}
}
}
func TestBucketObjectAcl(t *testing.T) {
type Case struct {
id string
resultErrCode, expectErrCode s3err.ErrorCode
resultGrants, expectGrants []*s3.Grant
}
testCases := make([]*Case, 0)
accountAdminId := "admin"
//Request body to specify AccessControlList
{
//ownership: ObjectWriter
//s3:PutBucketAcl('createObject' is set to false), config acl through request body
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
bucketOwnerId := "admin"
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-ObjectWriter, createObject-false, acl-requestBody",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &accountAdminId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeGroup,
URI: &s3_constants.GranteeGroupAllUsers,
},
Permission: &s3_constants.PermissionFullControl,
},
},
})
}
{
//ownership: BucketOwnerEnforced (extra acl is not allowed)
//s3:PutBucketAcl('createObject' is set to false), config acl through request body
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-false, acl-requestBody",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
{
//ownership: ObjectWriter
//s3:PutObject('createObject' is set to false), request body will be ignored when parse acl
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-ObjectWriter, createObject-true, acl-requestBody",
errCode, s3err.ErrNone,
grants, []*s3.Grant{},
})
}
{
//ownership: BucketOwnerEnforced (extra acl is not allowed)
//s3:PutObject('createObject' is set to true), request body will be ignored when parse acl
req := &http.Request{
Header: make(map[string][]string),
}
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-requestBody",
errCode, s3err.ErrNone,
grants, []*s3.Grant{},
})
}
//CannedAcl Header to specify ACL
//cannedAcl, PutBucketAcl
{
//ownership: ObjectWriter
//s3:PutBucketAcl('createObject' is set to false), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-ObjectWriter, createObject-false, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutBucketAcl('createObject' is set to false), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-false, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutBucketAcl('createObject' is set to false), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-false, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
})
}
//cannedACL, createBucket
{
//ownership: ObjectWriter
//s3:PutObject('createObject' is set to true), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutObject('createObject' is set to true), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-true, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutObject('createObject' is set to true), parse cannedACL header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-CannedAcl",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
})
}
//customAcl, PutBucketAcl
{
//ownership: ObjectWriter
//s3:PutBucketAcl('createObject' is set to false), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-ObjectWriter, createObject-false, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutBucketAcl('createObject' is set to false), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-false, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutBucketAcl('createObject' is set to false), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-false, acl-customAcl",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
//customAcl, putObject
{
//ownership: ObjectWriter
//s3:PutObject('createObject' is set to true), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-ObjectWriter, createObject-true, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
})
}
{
//ownership: BucketOwnerPreferred
//s3:PutObject('createObject' is set to true), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
"TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-true, acl-customAcl",
errCode, s3err.ErrNone,
grants, []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
},
})
}
{
//ownership: BucketOwnerEnforced
//s3:PutObject('createObject' is set to true), parse customAcl header
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
testCases = append(testCases, &Case{
id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-customAcl",
resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
})
}
{
//parse acp from request header: both canned acl and custom acl not allowed
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
req.Header.Set(s3_constants.AmzCannedAcl, "private")
bucketOwnerId := "admin"
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "Only one of cannedAcl, customAcl is allowed",
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
})
}
{
//Acl can only be specified in one of requestBody, cannedAcl, customAcl, simultaneous use is not allowed
req := &http.Request{
Header: make(map[string][]string),
}
req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
req.Header.Set(s3_constants.AmzCannedAcl, "private")
req.Body = io.NopCloser(bytes.NewReader([]byte(`
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>admin</ID>
<DisplayName>admin</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>admin</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
`)))
requestAccountId := "accountA"
_, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, false)
testCases = append(testCases, &Case{
id: "Only one of requestBody, cannedAcl, customAcl is allowed",
resultErrCode: errCode, expectErrCode: s3err.ErrUnexpectedContent,
})
}
for _, tc := range testCases {
if tc.resultErrCode != tc.expectErrCode {
t.Fatalf("case[%s]: errorCode[%v] not expect[%v]", tc.id, s3err.GetAPIError(tc.resultErrCode).Code, s3err.GetAPIError(tc.expectErrCode).Code)
}
if !grantsEquals(tc.resultGrants, tc.expectGrants) {
t.Fatalf("case[%s]: grants not expect", tc.id)
}
}
}
func TestMarshalGrantsToJson(t *testing.T) {
//ok
bucketOwnerId := "admin"
requestAccountId := "accountA"
grants := []*s3.Grant{
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &requestAccountId,
},
Permission: &s3_constants.PermissionFullControl,
},
{
Grantee: &s3.Grantee{
Type: &s3_constants.GrantTypeCanonicalUser,
ID: &bucketOwnerId,
},
Permission: &s3_constants.PermissionFullControl,
},
}
result, err := MarshalGrantsToJson(grants)
if err != nil {
t.Error(err)
}
var grants2 []*s3.Grant
err = json.Unmarshal(result, &grants2)
if err != nil {
t.Error(err)
}
print(string(result))
if !grantsEquals(grants, grants2) {
t.Fatal("grants not equal", grants, grants2)
}
//ok
result, err = MarshalGrantsToJson(nil)
if result != nil && err != nil {
t.Fatal("error: result, err = MarshalGrantsToJson(nil)")
}
}