|
|
@ -1,80 +1,534 @@ |
|
|
|
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" |
|
|
|
) |
|
|
|
|
|
|
|
func TestParseAclHeaders(t *testing.T) { |
|
|
|
accountManager := &s3account.AccountManager{ |
|
|
|
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, 0), |
|
|
|
} |
|
|
|
//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 TestExtractAcl(t *testing.T) { |
|
|
|
type Case struct { |
|
|
|
id int |
|
|
|
resultErrCode, expectErrCode s3err.ErrorCode |
|
|
|
resultGrants, expectGrants []*s3.Grant |
|
|
|
} |
|
|
|
testCases := make([]*Case, 0) |
|
|
|
accountAdminId := "admin" |
|
|
|
|
|
|
|
{ |
|
|
|
//case1 (good case)
|
|
|
|
//parse acp from request body
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
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> |
|
|
|
`))) |
|
|
|
objectWriter := "accountA" |
|
|
|
grants, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, accountAdminId, objectWriter) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
1, |
|
|
|
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, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
//case2 (good case)
|
|
|
|
//parse acp from header (cannedAcl)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
req.Body = nil |
|
|
|
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclPrivate) |
|
|
|
objectWriter := "accountA" |
|
|
|
grants, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, accountAdminId, objectWriter) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
2, |
|
|
|
errCode, s3err.ErrNone, |
|
|
|
grants, []*s3.Grant{ |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeCanonicalUser, |
|
|
|
ID: &objectWriter, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
//case3 (bad case)
|
|
|
|
//parse acp from request body (content is invalid)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
req.Body = io.NopCloser(bytes.NewReader([]byte("zdfsaf"))) |
|
|
|
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclPrivate) |
|
|
|
objectWriter := "accountA" |
|
|
|
_, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, accountAdminId, objectWriter) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
id: 3, |
|
|
|
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
//case4 (bad case)
|
|
|
|
//parse acp from header (cannedAcl is invalid)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
req.Body = nil |
|
|
|
req.Header.Set(s3_constants.AmzCannedAcl, "dfaksjfk") |
|
|
|
objectWriter := "accountA" |
|
|
|
_, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, "", objectWriter) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
id: 4, |
|
|
|
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest, |
|
|
|
}) |
|
|
|
|
|
|
|
{ |
|
|
|
//case5 (bad case)
|
|
|
|
//parse acp from request body: owner is inconsistent
|
|
|
|
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> |
|
|
|
`))) |
|
|
|
objectWriter = "accountA" |
|
|
|
_, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, objectWriter, objectWriter) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
id: 5, |
|
|
|
resultErrCode: errCode, expectErrCode: s3err.ErrAccessDenied, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
//good value
|
|
|
|
grants := make([]*s3.Grant, 0) |
|
|
|
validHeaderValue := `uri="http://acs.amazonaws.com/groups/global/AllUsers", id="anonymous", emailAddress="admin@example.com"` |
|
|
|
errCode := ParseCustomAclHeader(validHeaderValue, s3_constants.PermissionFullControl, &grants) |
|
|
|
if errCode != s3err.ErrNone { |
|
|
|
t.Fatal(errCode) |
|
|
|
for _, tc := range testCases { |
|
|
|
if tc.resultErrCode != tc.expectErrCode { |
|
|
|
t.Fatalf("case[%d]: errorCode not expect", tc.id) |
|
|
|
} |
|
|
|
if !grantsEquals(tc.resultGrants, tc.expectGrants) { |
|
|
|
t.Fatalf("case[%d]: grants not expect", tc.id) |
|
|
|
} |
|
|
|
} |
|
|
|
_, errCode = ValidateAndTransferGrants(accountManager, grants) |
|
|
|
if errCode != s3err.ErrNone { |
|
|
|
t.Fatal(errCode) |
|
|
|
} |
|
|
|
|
|
|
|
func TestParseAndValidateAclHeaders(t *testing.T) { |
|
|
|
type Case struct { |
|
|
|
id int |
|
|
|
resultOwner, expectOwner string |
|
|
|
resultErrCode, expectErrCode s3err.ErrorCode |
|
|
|
resultGrants, expectGrants []*s3.Grant |
|
|
|
} |
|
|
|
testCases := make([]*Case, 0) |
|
|
|
bucketOwner := "admin" |
|
|
|
|
|
|
|
//bad case: acl header format error
|
|
|
|
grants = make([]*s3.Grant, 0) |
|
|
|
formatErrCase := `uri, id="anonymous", emailAddress="admin@example.com"` |
|
|
|
errCode = ParseCustomAclHeader(formatErrCase, s3_constants.PermissionFullControl, &grants) |
|
|
|
if errCode != s3err.ErrInvalidRequest { |
|
|
|
t.Fatal(errCode) |
|
|
|
{ |
|
|
|
//case1 (good case)
|
|
|
|
//parse custom acl
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
objectWriter := "accountA" |
|
|
|
req.Header.Set(s3_constants.AmzAclFullControl, `uri="http://acs.amazonaws.com/groups/global/AllUsers", id="anonymous", emailAddress="admin@example.com"`) |
|
|
|
ownerId, grants, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
1, |
|
|
|
ownerId, objectWriter, |
|
|
|
errCode, s3err.ErrNone, |
|
|
|
grants, []*s3.Grant{ |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeGroup, |
|
|
|
URI: &s3_constants.GranteeGroupAllUsers, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeCanonicalUser, |
|
|
|
ID: &s3account.AccountAnonymous.Id, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeCanonicalUser, |
|
|
|
ID: &s3account.AccountAdmin.Id, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}) |
|
|
|
} |
|
|
|
{ |
|
|
|
//case2 (good case)
|
|
|
|
//parse canned acl (ownership=ObjectWriter)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
objectWriter := "accountA" |
|
|
|
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl) |
|
|
|
ownerId, grants, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
2, |
|
|
|
ownerId, objectWriter, |
|
|
|
errCode, s3err.ErrNone, |
|
|
|
grants, []*s3.Grant{ |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeCanonicalUser, |
|
|
|
ID: &objectWriter, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeCanonicalUser, |
|
|
|
ID: &bucketOwner, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}) |
|
|
|
} |
|
|
|
{ |
|
|
|
//case3 (good case)
|
|
|
|
//parse canned acl (ownership=OwnershipBucketOwnerPreferred)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
objectWriter := "accountA" |
|
|
|
req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl) |
|
|
|
ownerId, grants, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwner, objectWriter, false) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
3, |
|
|
|
ownerId, bucketOwner, |
|
|
|
errCode, s3err.ErrNone, |
|
|
|
grants, []*s3.Grant{ |
|
|
|
{ |
|
|
|
Grantee: &s3.Grantee{ |
|
|
|
Type: &s3_constants.GrantTypeCanonicalUser, |
|
|
|
ID: &bucketOwner, |
|
|
|
}, |
|
|
|
Permission: &s3_constants.PermissionFullControl, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}) |
|
|
|
} |
|
|
|
{ |
|
|
|
//case4 (bad case)
|
|
|
|
//parse custom acl (grantee id not exists)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
objectWriter := "accountA" |
|
|
|
req.Header.Set(s3_constants.AmzAclFullControl, `uri="http://acs.amazonaws.com/groups/global/AllUsers", id="notExistsAccount", emailAddress="admin@example.com"`) |
|
|
|
_, _, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
id: 4, |
|
|
|
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
//case5 (bad case)
|
|
|
|
//parse custom acl (invalid format)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
objectWriter := "accountA" |
|
|
|
req.Header.Set(s3_constants.AmzAclFullControl, `uri="http:sfasf"`) |
|
|
|
_, _, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
id: 5, |
|
|
|
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
//case6 (bad case)
|
|
|
|
//parse canned acl (invalid value)
|
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
objectWriter := "accountA" |
|
|
|
req.Header.Set(s3_constants.AmzCannedAcl, `uri="http:sfasf"`) |
|
|
|
_, _, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false) |
|
|
|
testCases = append(testCases, &Case{ |
|
|
|
id: 5, |
|
|
|
resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
|
if tc.expectErrCode != tc.resultErrCode { |
|
|
|
t.Errorf("case[%d]: errCode unexpect", tc.id) |
|
|
|
} |
|
|
|
if tc.resultOwner != tc.expectOwner { |
|
|
|
t.Errorf("case[%d]: ownerId unexpect", tc.id) |
|
|
|
} |
|
|
|
if !grantsEquals(tc.resultGrants, tc.expectGrants) { |
|
|
|
t.Fatalf("case[%d]: grants not expect", tc.id) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//bad case: email not exists
|
|
|
|
grants = make([]*s3.Grant, 0) |
|
|
|
badCaseOfEmail := `uri="http://acs.amazonaws.com/groups/global/AllUsers", id="anonymous", emailAddress="admin@example1.com"` |
|
|
|
errCode = ParseCustomAclHeader(badCaseOfEmail, s3_constants.PermissionFullControl, &grants) |
|
|
|
if errCode != s3err.ErrNone { |
|
|
|
t.Fatal(errCode) |
|
|
|
func grantsEquals(a, b []*s3.Grant) bool { |
|
|
|
if len(a) != len(b) { |
|
|
|
return false |
|
|
|
} |
|
|
|
_, errCode = ValidateAndTransferGrants(accountManager, grants) |
|
|
|
if errCode != s3err.ErrInvalidRequest { |
|
|
|
t.Fatal(errCode) |
|
|
|
for i, grant := range a { |
|
|
|
if !GrantEquals(grant, b[i]) { |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
return true |
|
|
|
} |
|
|
|
|
|
|
|
//bad case: account id not exists
|
|
|
|
grants = make([]*s3.Grant, 0) |
|
|
|
badCaseOfAccountId := "uri=\"http://acs.amazonaws.com/groups/global/AllUsers\", id=\"xxxxxx\", emailAddress=\"admin@example.com\"" |
|
|
|
errCode = ParseCustomAclHeader(badCaseOfAccountId, s3_constants.PermissionFullControl, &grants) |
|
|
|
if errCode != s3err.ErrNone { |
|
|
|
t.Fatal(errCode) |
|
|
|
func TestDetermineReqGrants(t *testing.T) { |
|
|
|
{ |
|
|
|
//case1: request account is anonymous
|
|
|
|
accountId := s3account.AccountAnonymous.Id |
|
|
|
reqPermission := s3_constants.PermissionRead |
|
|
|
|
|
|
|
resultGrants := DetermineReqGrants(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") |
|
|
|
} |
|
|
|
} |
|
|
|
_, errCode = ValidateAndTransferGrants(accountManager, grants) |
|
|
|
if errCode != s3err.ErrInvalidRequest { |
|
|
|
t.Fatal(errCode) |
|
|
|
{ |
|
|
|
//case2: request account is not anonymous (Iam authed)
|
|
|
|
accountId := "accountX" |
|
|
|
reqPermission := s3_constants.PermissionRead |
|
|
|
|
|
|
|
resultGrants := DetermineReqGrants(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
|
|
|
|
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") |
|
|
|
} |
|
|
|
|
|
|
|
//bad case: group url not valid
|
|
|
|
grants = make([]*s3.Grant, 0) |
|
|
|
badCaseOfURL := "uri=\"http://acs.amazonaws.com/groups/global/AllUsers111xxxx\", id=\"anonymous\", emailAddress=\"admin@example.com\"" |
|
|
|
errCode = ParseCustomAclHeader(badCaseOfURL, s3_constants.PermissionFullControl, &grants) |
|
|
|
if errCode != s3err.ErrNone { |
|
|
|
t.Fatal(errCode) |
|
|
|
resultGrants := GetAcpGrants(entry.Extended) |
|
|
|
if !grantsEquals(resultGrants, expectGrants) { |
|
|
|
t.Fatal("grants not expect") |
|
|
|
} |
|
|
|
} |
|
|
|
_, errCode = ValidateAndTransferGrants(accountManager, grants) |
|
|
|
if errCode != s3err.ErrInvalidRequest { |
|
|
|
t.Fatal(errCode) |
|
|
|
{ |
|
|
|
//case2
|
|
|
|
entry := &filer_pb.Entry{} |
|
|
|
AssembleEntryWithAcp(entry, "", nil) |
|
|
|
|
|
|
|
resultOwner := GetAcpOwner(entry.Extended, defaultOwner) |
|
|
|
if resultOwner != defaultOwner { |
|
|
|
t.Fatalf("owner not expect") |
|
|
|
} |
|
|
|
|
|
|
|
resultGrants := GetAcpGrants(entry.Extended) |
|
|
|
if len(resultGrants) != 0 { |
|
|
|
t.Fatal("grants not expect") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
func TestGrantEquals(t *testing.T) { |
|
|
@ -218,3 +672,37 @@ func TestGrantEquals(t *testing.T) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func TestSetAcpOwnerHeader(t *testing.T) { |
|
|
|
ownerId := "accountZ" |
|
|
|
req := &http.Request{ |
|
|
|
Header: make(map[string][]string, 0), |
|
|
|
} |
|
|
|
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, 0), |
|
|
|
} |
|
|
|
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") |
|
|
|
} |
|
|
|
} |