Skip to content

Commit

Permalink
Fix/delete requests (#672)
Browse files Browse the repository at this point in the history
  • Loading branch information
cnlangzi committed May 14, 2022
1 parent cb46c97 commit 89a6ab5
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 114 deletions.
6 changes: 5 additions & 1 deletion code/go/0chain.net/blobbercore/handler/file_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (

// FileCommand execute command for a file operation
type FileCommand interface {

// GetExistingFileRef get file ref if it exists
GetExistingFileRef() *reference.Ref

// IsValidated validate request, and try build ChangeProcesser instance
IsValidated(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, clientID string) error

Expand All @@ -35,7 +39,7 @@ func createFileCommand(req *http.Request) FileCommand {
case http.MethodPut:
return &UpdateFileCommand{}
case http.MethodDelete:
return &FileCommandDelete{}
return &DeleteFileCommand{}

default:
return &UploadFileCommand{}
Expand Down
20 changes: 12 additions & 8 deletions code/go/0chain.net/blobbercore/handler/file_command_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@ import (
"github.com/0chain/blobber/code/go/0chain.net/core/common"
)

// FileCommandDelete command for deleting file
type FileCommandDelete struct {
// DeleteFileCommand command for deleting file
type DeleteFileCommand struct {
existingFileRef *reference.Ref
changeProcessor *allocation.DeleteFileChange
allocationChange *allocation.AllocationChange
}

func (cmd *DeleteFileCommand) GetExistingFileRef() *reference.Ref {
return cmd.existingFileRef
}

// IsValidated validate request.
func (cmd *FileCommandDelete) IsValidated(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, clientID string) error {
func (cmd *DeleteFileCommand) IsValidated(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, clientID string) error {
if allocationObj.OwnerID != clientID && allocationObj.RepairerID != clientID {
return common.NewError("invalid_operation", "Operation needs to be performed by the owner or the payer of the allocation")
}

path := req.FormValue("path")
if path == "" {
path, ok := GetField(req, "path")
if !ok {
return common.NewError("invalid_parameters", "Invalid path")
}
var err error
Expand All @@ -43,14 +47,14 @@ func (cmd *FileCommandDelete) IsValidated(ctx context.Context, req *http.Request
}

// UpdateChange add DeleteFileChange in db
func (cmd *FileCommandDelete) UpdateChange(ctx context.Context, connectionObj *allocation.AllocationChangeCollector) error {
func (cmd *DeleteFileCommand) UpdateChange(ctx context.Context, connectionObj *allocation.AllocationChangeCollector) error {
connectionObj.AddChange(cmd.allocationChange, cmd.changeProcessor)

return connectionObj.Save(ctx)
}

// ProcessContent flush file to FileStorage
func (cmd *FileCommandDelete) ProcessContent(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, connectionObj *allocation.AllocationChangeCollector) (blobberhttp.UploadResult, error) {
func (cmd *DeleteFileCommand) ProcessContent(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, connectionObj *allocation.AllocationChangeCollector) (blobberhttp.UploadResult, error) {
deleteSize := cmd.existingFileRef.Size

cmd.changeProcessor = &allocation.DeleteFileChange{ConnectionID: connectionObj.ID,
Expand All @@ -74,7 +78,7 @@ func (cmd *FileCommandDelete) ProcessContent(ctx context.Context, req *http.Requ
}

// ProcessThumbnail no thumbnail should be processed for delete. A deffered delete command has been added on ProcessContent
func (cmd *FileCommandDelete) ProcessThumbnail(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, connectionObj *allocation.AllocationChangeCollector) error {
func (cmd *DeleteFileCommand) ProcessThumbnail(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, connectionObj *allocation.AllocationChangeCollector) error {
//DO NOTHING
return nil
}
4 changes: 4 additions & 0 deletions code/go/0chain.net/blobbercore/handler/file_command_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ type UpdateFileCommand struct {
allocationChange *allocation.AllocationChange
}

func (cmd *UpdateFileCommand) GetExistingFileRef() *reference.Ref {
return cmd.existingFileRef
}

// IsValidated validate request.
func (cmd *UpdateFileCommand) IsValidated(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, clientID string) error {
uploadMetaString := req.FormValue(UploadMeta)
Expand Down
4 changes: 4 additions & 0 deletions code/go/0chain.net/blobbercore/handler/file_command_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type UploadFileCommand struct {
fileChanger *allocation.UploadFileChanger
}

func (cmd *UploadFileCommand) GetExistingFileRef() *reference.Ref {
return nil
}

// IsValidated validate request.
func (cmd *UploadFileCommand) IsValidated(ctx context.Context, req *http.Request, allocationObj *allocation.Allocation, clientID string) error {
if allocationObj.OwnerID != clientID && allocationObj.RepairerID != clientID {
Expand Down
12 changes: 11 additions & 1 deletion code/go/0chain.net/blobbercore/handler/grpc_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,17 @@ func (b *blobberGRPCService) Collaborator(ctx context.Context, req *blobbergrpc.
"collab_id": {req.CollabId},
}

resp, err := CollaboratorHandler(ctx, r)
var resp interface{}

switch req.Method {
case http.MethodPost:
resp, err = AddCollaboratorHandler(ctx, r)
case http.MethodGet:
resp, err = GetCollaboratorHandler(ctx, r)
case http.MethodDelete:
resp, err = RemoveCollaboratorHandler(ctx, r)
}

if err != nil {
return nil, err
}
Expand Down
13 changes: 9 additions & 4 deletions code/go/0chain.net/blobbercore/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,14 @@ func SetupHandlers(r *mux.Router) {

r.HandleFunc("/v1/connection/commit/{allocation}", common.ToStatusCode(WithStatusConnection(CommitHandler)))
r.HandleFunc("/v1/file/commitmetatxn/{allocation}", common.ToJSONResponse(WithConnection(CommitMetaTxnHandler)))
r.HandleFunc("/v1/file/collaborator/{allocation}", common.ToJSONResponse(WithConnection(CollaboratorHandler)))

r.HandleFunc("/v1/file/calculatehash/{allocation}", common.ToJSONResponse(WithConnection(CalculateHashHandler)))

// collaborator
r.HandleFunc("/v1/file/collaborator/{allocation}", common.ToJSONResponse(WithConnection(AddCollaboratorHandler))).Methods(http.MethodOptions, http.MethodPost)
r.HandleFunc("/v1/file/collaborator/{allocation}", common.ToJSONResponse(WithConnection(GetCollaboratorHandler))).Methods(http.MethodOptions, http.MethodGet)
r.HandleFunc("/v1/file/collaborator/{allocation}", common.ToJSONResponse(WithConnection(RemoveCollaboratorHandler))).Methods(http.MethodOptions, http.MethodDelete)

//object info related apis
r.HandleFunc("/allocation", common.ToJSONResponse(WithConnection(AllocationHandler)))
r.HandleFunc("/v1/file/meta/{allocation}", common.ToJSONResponse(WithReadOnlyConnection(FileMetaHandler)))
Expand Down Expand Up @@ -290,7 +295,7 @@ func UpdateAttributesHandler(ctx context.Context, r *http.Request) (interface{},
return response, nil
}

func writeResponse (w http.ResponseWriter, resp []byte) {
func writeResponse(w http.ResponseWriter, resp []byte) {
_, err := w.Write(resp)

if err != nil {
Expand Down Expand Up @@ -392,8 +397,8 @@ func RevokeShare(ctx context.Context, r *http.Request) (interface{}, error) {
return nil, common.NewError("invalid_signature", "Invalid signature")
}

path := r.FormValue("path")
refereeClientID := r.FormValue("refereeClientID")
path, _ := GetField(r, "path")
refereeClientID, _ := GetField(r, "refereeClientID")
filePathHash := fileref.GetReferenceLookup(allocationID, path)
//_, err = reference.GetReferenceByLookupHashForAddCollaborator(ctx, allocationID, filePathHash)
_, err = reference.GetLimitedRefFieldsByLookupHash(ctx, allocationID, filePathHash, []string{"id", "type"})
Expand Down
31 changes: 16 additions & 15 deletions code/go/0chain.net/blobbercore/handler/handler_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,16 @@ func CalculateHashHandler(ctx context.Context, r *http.Request) (interface{}, er
return response, nil
}

func CollaboratorHandler(ctx context.Context, r *http.Request) (interface{}, error) {
func AddCollaboratorHandler(ctx context.Context, r *http.Request) (interface{}, error) {
return storageHandler.AddCollaborator(setupHandlerContext(ctx, r), r)
}

ctx = setupHandlerContext(ctx, r)
func GetCollaboratorHandler(ctx context.Context, r *http.Request) (interface{}, error) {
return storageHandler.GetCollaborator(setupHandlerContext(ctx, r), r)
}

response, err := storageHandler.AddCollaborator(ctx, r)
if err != nil {
return nil, err
}
return response, nil
func RemoveCollaboratorHandler(ctx context.Context, r *http.Request) (interface{}, error) {
return storageHandler.RemoveCollaborator(setupHandlerContext(ctx, r), r)
}

func HomepageHandler(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -95,21 +96,21 @@ func HomepageHandler(w http.ResponseWriter, r *http.Request) {
}

type BlobberInfo struct {
ChainId string `json:"chain_id"`
BlobberId string `json:"blobber_id"`
BlobberPublicKey string `json:"public_key"`
BuildTag string `json:"build_tag"`
Stats interface{} `json:"stats"`
ChainId string `json:"chain_id"`
BlobberId string `json:"blobber_id"`
BlobberPublicKey string `json:"public_key"`
BuildTag string `json:"build_tag"`
Stats interface{} `json:"stats"`
}

func GetBlobberInfoJson() BlobberInfo {
mc := chain.GetServerChain()

blobberInfo := BlobberInfo{
ChainId: mc.ID,
BlobberId: node.Self.ID,
ChainId: mc.ID,
BlobberId: node.Self.ID,
BlobberPublicKey: node.Self.PublicKey,
BuildTag: build.BuildTag,
BuildTag: build.BuildTag,
}

return blobberInfo
Expand Down
39 changes: 16 additions & 23 deletions code/go/0chain.net/blobbercore/handler/handler_share_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"mime/multipart"
"net/http"
"net/http/httptest"
"net/url"
"os"
"regexp"
"testing"
Expand Down Expand Up @@ -375,23 +376,21 @@ func TestHandlers_Share(t *testing.T) {
args: args{
w: httptest.NewRecorder(),
r: func() *http.Request {
url, err := router.Get(revokeShare).URL("allocation", alloc.Tx)
u, err := router.Get(revokeShare).URL("allocation", alloc.Tx)
if err != nil {
t.Fatal()
}

body := bytes.NewBuffer(nil)
formWriter := multipart.NewWriter(body)
query := &url.Values{}
shareClientID := "da4b54d934890aa415bb043ce1126f2e30a96faf63a4c65c25bbddcb32824d77"
remotePath := "/file.txt"

require.NoError(t, formWriter.WriteField("refereeClientID", shareClientID))
require.NoError(t, formWriter.WriteField("path", remotePath))
if err := formWriter.Close(); err != nil {
t.Fatal(err)
}
r, err := http.NewRequest(http.MethodDelete, url.String(), body)
r.Header.Add("Content-Type", formWriter.FormDataContentType())
query.Add("refereeClientID", shareClientID)
query.Add("path", remotePath)

u.RawQuery = query.Encode()
r, err := http.NewRequest(http.MethodDelete, u.String(), nil)

if err != nil {
t.Fatal(err)
}
Expand All @@ -402,7 +401,6 @@ func TestHandlers_Share(t *testing.T) {
t.Fatal(err)
}

r.Header.Set("Content-Type", formWriter.FormDataContentType())
r.Header.Set(common.ClientSignatureHeader, sign)
r.Header.Set(common.ClientHeader, alloc.OwnerID)

Expand Down Expand Up @@ -454,34 +452,29 @@ func TestHandlers_Share(t *testing.T) {
args: args{
w: httptest.NewRecorder(),
r: func() *http.Request {
url, err := router.Get(revokeShare).URL("allocation", alloc.Tx)
u, err := router.Get(revokeShare).URL("allocation", alloc.Tx)
if err != nil {
t.Fatal()
}

body := bytes.NewBuffer(nil)
formWriter := multipart.NewWriter(body)
query := &url.Values{}
shareClientID := "da4b54d934890aa415bb043ce1126f2e30a96faf63a4c65c25bbddcb32824d77"
remotePath := "/file.txt"

require.NoError(t, formWriter.WriteField("refereeClientID", shareClientID))
require.NoError(t, formWriter.WriteField("path", remotePath))
if err := formWriter.Close(); err != nil {
t.Fatal(err)
}
r, err := http.NewRequest(http.MethodDelete, url.String(), body)
r.Header.Add("Content-Type", formWriter.FormDataContentType())
query.Add("refereeClientID", shareClientID)
query.Add("path", remotePath)

u.RawQuery = query.Encode()
r, err := http.NewRequest(http.MethodDelete, u.String(), nil)
if err != nil {
t.Fatal(err)
}

hash := encryption.Hash(alloc.Tx)
sign, err := sch.Sign(hash)
if err != nil {
t.Fatal(err)
}

r.Header.Set("Content-Type", formWriter.FormDataContentType())
r.Header.Set(common.ClientSignatureHeader, sign)
r.Header.Set(common.ClientHeader, alloc.OwnerID)

Expand Down
3 changes: 2 additions & 1 deletion code/go/0chain.net/blobbercore/handler/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func setupHandlers() (*mux.Router, map[string]string) {
collName := "Collaborator"
router.HandleFunc(collPath, common.UserRateLimit(
common.ToJSONResponse(
WithReadOnlyConnection(CollaboratorHandler),
WithReadOnlyConnection(GetCollaboratorHandler),
),
),
).Name(collName)
Expand Down Expand Up @@ -1106,6 +1106,7 @@ func TestHandlers_Requiring_Signature(t *testing.T) {
}
tests := append(positiveTests, negativeTests...)
tests = append(tests, uploadNegativeTests...)

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
mock := datastore.MockTheStore(t)
Expand Down
17 changes: 17 additions & 0 deletions code/go/0chain.net/blobbercore/handler/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,20 @@ func TryParseForm(r *http.Request) {
}
}
}

// GetField get field from form or query
func GetField(r *http.Request, key string) (string, bool) {
TryParseForm(r)

v, ok := r.Form[key]
if ok {
return v[0], true
}

v, ok = r.URL.Query()[key]
if ok {
return v[0], true
}

return "", false
}
29 changes: 6 additions & 23 deletions code/go/0chain.net/blobbercore/handler/object_operation_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,8 @@ func (fsh *StorageHandler) CommitWrite(ctx context.Context, r *http.Request) (*b

allocationID := allocationObj.ID

connectionID := r.FormValue("connection_id")
if connectionID == "" {
connectionID, ok := GetField(r, "connection_id")
if !ok {
return nil, common.NewError("invalid_parameters", "Invalid connection id passed")
}

Expand Down Expand Up @@ -413,11 +413,6 @@ func (fsh *StorageHandler) CommitWrite(ctx context.Context, r *http.Request) (*b
return nil, common.NewError("invalid_operation", "Operation needs to be performed by the owner of the allocation")
}

if err = r.ParseMultipartForm(FormFileParseMaxMemory); err != nil {
Logger.Error("Error Parsing the request", zap.Any("error", err))
return nil, common.NewError("request_parse_error", err.Error())
}

if allocationObj.BlobberSizeUsed+connectionObj.Size > allocationObj.BlobberSize {
return nil, common.NewError("max_allocation_size",
"Max size reached for the allocation with this blobber")
Expand Down Expand Up @@ -981,15 +976,8 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
return nil, err
}

var existingFileRef *reference.Ref
switch rCmd := cmd.(type) {
case *UpdateFileCommand:
existingFileRef = rCmd.existingFileRef
case *FileCommandDelete:
existingFileRef = rCmd.existingFileRef
default:
existingFileRef = nil
}
existingFileRef := cmd.GetExistingFileRef()

isCollaborator := existingFileRef != nil && reference.IsACollaborator(ctx, existingFileRef.ID, clientID)
publicKey := allocationObj.OwnerPublicKey

Expand All @@ -1011,13 +999,8 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
return nil, common.NewError("invalid_operation", "Operation needs to be performed by the owner or the payer of the allocation")
}

if err := r.ParseMultipartForm(FormFileParseMaxMemory); err != nil {
Logger.Error("Error Parsing the request", zap.Any("error", err))
return nil, common.NewError("request_parse_error", err.Error())
}

connectionID := r.FormValue("connection_id")
if connectionID == "" {
connectionID, ok := GetField(r, "connection_id")
if !ok {
return nil, common.NewError("invalid_parameters", "Invalid connection id passed")
}

Expand Down

0 comments on commit 89a6ab5

Please sign in to comment.