diff --git a/api/handler/cors_test.go b/api/handler/cors_test.go new file mode 100644 index 0000000..bbd0edf --- /dev/null +++ b/api/handler/cors_test.go @@ -0,0 +1,41 @@ +package handler + +import ( + "context" + "net/http" + "strings" + "testing" + + "github.com/TrueCloudLab/frostfs-s3-gw/api" +) + +func TestCORSOriginWildcard(t *testing.T) { + body := ` + + + GET + * + + +` + hc := prepareHandlerContext(t) + + bktName := "bucket-for-cors" + box, _ := createAccessBox(t) + w, r := prepareTestRequest(hc, bktName, "", nil) + ctx := context.WithValue(r.Context(), api.BoxData, box) + r = r.WithContext(ctx) + r.Header.Add(api.AmzACL, "public-read") + hc.Handler().CreateBucketHandler(w, r) + assertStatus(t, w, http.StatusOK) + + w, r = prepareTestPayloadRequest(hc, bktName, "", strings.NewReader(body)) + ctx = context.WithValue(r.Context(), api.BoxData, box) + r = r.WithContext(ctx) + hc.Handler().PutBucketCorsHandler(w, r) + assertStatus(t, w, http.StatusOK) + + w, r = prepareTestPayloadRequest(hc, bktName, "", nil) + hc.Handler().GetBucketCorsHandler(w, r) + assertStatus(t, w, http.StatusOK) +} diff --git a/api/layer/cors.go b/api/layer/cors.go index baaac62..bef3393 100644 --- a/api/layer/cors.go +++ b/api/layer/cors.go @@ -39,7 +39,7 @@ func (n *layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error { prm := PrmObjectCreate{ Container: p.BktInfo.CID, Creator: p.BktInfo.Owner, - Payload: p.Reader, + Payload: &buf, Filepath: p.BktInfo.CORSObjectName(), CreationTime: TimeNow(ctx), CopiesNumber: p.CopiesNumber, diff --git a/api/layer/neofs_mock.go b/api/layer/neofs_mock.go index af6a259..112caf8 100644 --- a/api/layer/neofs_mock.go +++ b/api/layer/neofs_mock.go @@ -144,7 +144,7 @@ func (t *TestFrostFS) ReadObject(ctx context.Context, prm PrmObjectRead) (*Objec if obj, ok := t.objects[sAddr]; ok { owner := getOwner(ctx) - if !obj.OwnerID().Equals(owner) { + if !obj.OwnerID().Equals(owner) && !t.isPublicRead(prm.Container) { return nil, ErrAccessDenied } @@ -282,6 +282,25 @@ func (t *TestFrostFS) ContainerEACL(_ context.Context, cnrID cid.ID) (*eacl.Tabl return table, nil } +func (t *TestFrostFS) isPublicRead(cnrID cid.ID) bool { + table, ok := t.eaclTables[cnrID.EncodeToString()] + if !ok { + return false + } + + for _, rec := range table.Records() { + if rec.Operation() == eacl.OperationGet && len(rec.Filters()) == 0 { + for _, trgt := range rec.Targets() { + if trgt.Role() == eacl.RoleOthers { + return rec.Action() == eacl.ActionAllow + } + } + } + } + + return false +} + func getOwner(ctx context.Context) user.ID { if bd, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && bd != nil && bd.Gate != nil && bd.Gate.BearerToken != nil { return bearer.ResolveIssuer(*bd.Gate.BearerToken) diff --git a/api/layer/tree_mock.go b/api/layer/tree_mock.go index de4c60b..790735f 100644 --- a/api/layer/tree_mock.go +++ b/api/layer/tree_mock.go @@ -109,11 +109,32 @@ func (t *TreeServiceMock) PutNotificationConfigurationNode(ctx context.Context, } func (t *TreeServiceMock) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error) { - panic("implement me") + systemMap, ok := t.system[bktInfo.CID.EncodeToString()] + if !ok { + return oid.ID{}, nil + } + + node, ok := systemMap["cors"] + if !ok { + return oid.ID{}, nil + } + + return node.OID, nil } func (t *TreeServiceMock) PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, objID oid.ID) (oid.ID, error) { - panic("implement me") + systemMap, ok := t.system[bktInfo.CID.EncodeToString()] + if !ok { + systemMap = make(map[string]*data.BaseNodeVersion) + } + + systemMap["cors"] = &data.BaseNodeVersion{ + OID: objID, + } + + t.system[bktInfo.CID.EncodeToString()] = systemMap + + return oid.ID{}, ErrNoNodeToRemove } func (t *TreeServiceMock) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error) {