Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions code/go/0chain.net/blobbercore/handler/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -985,17 +985,17 @@ func TestHandlers_Requiring_Signature(t *testing.T) {
AddRow(alloc.Terms[0].ID, alloc.Terms[0].AllocationID),
)

mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "reference_objects"`)).
WithArgs(aa).
WillReturnError(gorm.ErrRecordNotFound)

mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "allocation_connections" WHERE`)).
WithArgs(connectionID, alloc.ID, alloc.OwnerID, allocation.DeletedConnection).
WillReturnRows(
sqlmock.NewRows([]string{}).
AddRow(),
)

mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "reference_objects"`)).
WithArgs(aa).
WillReturnError(gorm.ErrRecordNotFound)

mock.ExpectExec(`INSERT INTO "allocation_connections"`).
WithArgs(aa, aa, aa, aa, aa, aa, aa).
WillReturnResult(sqlmock.NewResult(0, 0))
Expand Down
97 changes: 63 additions & 34 deletions code/go/0chain.net/blobbercore/handler/object_operation_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,18 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
return nil, common.NewError("invalid_parameters", "Invalid allocation id passed."+err.Error())
}

valid, err := verifySignatureFromRequest(allocationTx, r.Header.Get(common.ClientSignatureHeader), allocationObj.OwnerPublicKey)
allocationID := allocationObj.ID
fileOperation := getFileOperation(r)
existingFileRef := getExistingFileRef(fsh, ctx, r, allocationObj, fileOperation)
isCollaborator := existingFileRef != nil && reference.IsACollaborator(ctx, existingFileRef.ID, clientID)
publicKey := allocationObj.OwnerPublicKey

if isCollaborator {
publicKey = ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string)
}

valid, err := verifySignatureFromRequest(allocationTx, r.Header.Get(common.ClientSignatureHeader), publicKey)

if !valid || err != nil {
return nil, common.NewError("invalid_signature", "Invalid signature")
}
Expand All @@ -934,8 +945,6 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
return nil, common.NewError("immutable_allocation", "Cannot write to an immutable allocation")
}

allocationID := allocationObj.ID

if len(clientID) == 0 {
return nil, common.NewError("invalid_operation", "Operation needs to be performed by the owner or the payer of the allocation")
}
Expand All @@ -960,59 +969,47 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
defer mutex.Unlock()

result := &blobberhttp.UploadResult{}
mode := allocation.INSERT_OPERATION
if r.Method == "PUT" {
mode = allocation.UPDATE_OPERATION
} else if r.Method == "DELETE" {
mode = allocation.DELETE_OPERATION
}

if mode == allocation.DELETE_OPERATION {
if fileOperation == allocation.DELETE_OPERATION {
if allocationObj.OwnerID != clientID && allocationObj.RepairerID != clientID {
return nil, common.NewError("invalid_operation", "Operation needs to be performed by the owner or the payer of the allocation")
}
result, err = fsh.DeleteFile(ctx, r, connectionObj)
if err != nil {
return nil, err
}
} else if mode == allocation.INSERT_OPERATION || mode == allocation.UPDATE_OPERATION {
} else if fileOperation == allocation.INSERT_OPERATION || fileOperation == allocation.UPDATE_OPERATION {
formField := getFormFieldName(fileOperation)
var formData allocation.UpdateFileChange
formField := "uploadMeta"
if mode == allocation.UPDATE_OPERATION {
formField = "updateMeta"
}
uploadMetaString := r.FormValue(formField)
err = json.Unmarshal([]byte(uploadMetaString), &formData)
if err != nil {
return nil, common.NewError("invalid_parameters",
"Invalid parameters. Error parsing the meta data for upload."+err.Error())
}
exisitingFileRef := fsh.checkIfFileAlreadyExists(ctx, allocationID, formData.Path)
existingFileRefSize := int64(0)
exisitingFileOnCloud := false
if mode == allocation.INSERT_OPERATION {
existingFileOnCloud := false
if fileOperation == allocation.INSERT_OPERATION {
if allocationObj.OwnerID != clientID && allocationObj.RepairerID != clientID {
return nil, common.NewError("invalid_operation", "Operation needs to be performed by the owner or the payer of the allocation")
}

if exisitingFileRef != nil {
if existingFileRef != nil {
return nil, common.NewError("duplicate_file", "File at path already exists")
}
} else if mode == allocation.UPDATE_OPERATION {
if exisitingFileRef == nil {
} else if fileOperation == allocation.UPDATE_OPERATION {
if existingFileRef == nil {
return nil, common.NewError("invalid_file_update", "File at path does not exist for update")
}

if allocationObj.OwnerID != clientID &&
allocationObj.RepairerID != clientID &&
!reference.IsACollaborator(ctx, exisitingFileRef.ID, clientID) {
if allocationObj.OwnerID != clientID && allocationObj.RepairerID != clientID && !isCollaborator {
return nil, common.NewError("invalid_operation", "Operation needs to be performed by the owner, collaborator or the payer of the allocation")
}
}

if exisitingFileRef != nil {
existingFileRefSize = exisitingFileRef.Size
exisitingFileOnCloud = exisitingFileRef.OnCloud
if existingFileRef != nil {
existingFileRefSize = existingFileRef.Size
existingFileOnCloud = existingFileRef.OnCloud
}

origfile, _, err := r.FormFile("uploadFile")
Expand All @@ -1022,13 +1019,12 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
defer origfile.Close()

thumbfile, thumbHeader, _ := r.FormFile("uploadThumbnailFile")
thumbnailPresent := false
if thumbHeader != nil {
thumbnailPresent = true
thumbnailPresent := thumbHeader != nil
if thumbnailPresent {
defer thumbfile.Close()
}

fileInputData := &filestore.FileInputData{Name: formData.Filename, Path: formData.Path, OnCloud: exisitingFileOnCloud}
fileInputData := &filestore.FileInputData{Name: formData.Filename, Path: formData.Path, OnCloud: existingFileOnCloud}
fileOutputData, err := filestore.GetFileStore().WriteFile(allocationID, fileInputData, origfile, connectionObj.ConnectionID)
if err != nil {
return nil, common.NewError("upload_error", "Failed to upload the file. "+err.Error())
Expand Down Expand Up @@ -1076,12 +1072,12 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo
allocationChange := &allocation.AllocationChange{}
allocationChange.ConnectionID = connectionObj.ConnectionID
allocationChange.Size = allocationSize - existingFileRefSize
allocationChange.Operation = mode
allocationChange.Operation = fileOperation

connectionObj.Size += allocationChange.Size
if mode == allocation.INSERT_OPERATION {
if fileOperation == allocation.INSERT_OPERATION {
connectionObj.AddChange(allocationChange, &formData.NewFileChange)
} else if mode == allocation.UPDATE_OPERATION {
} else if fileOperation == allocation.UPDATE_OPERATION {
connectionObj.AddChange(allocationChange, &formData)
}
}
Expand All @@ -1093,3 +1089,36 @@ func (fsh *StorageHandler) WriteFile(ctx context.Context, r *http.Request) (*blo

return result, nil
}

func getFormFieldName(mode string) string {
formField := "uploadMeta"
if mode == allocation.UPDATE_OPERATION {
formField = "updateMeta"
}

return formField
}

func getFileOperation(r *http.Request) string {
mode := allocation.INSERT_OPERATION
if r.Method == "PUT" {
mode = allocation.UPDATE_OPERATION
} else if r.Method == "DELETE" {
mode = allocation.DELETE_OPERATION
}

return mode
}

func getExistingFileRef(fsh *StorageHandler, ctx context.Context, r *http.Request, allocationObj *allocation.Allocation, fileOperation string) *reference.Ref {
if fileOperation == allocation.INSERT_OPERATION || fileOperation == allocation.UPDATE_OPERATION {
var formData allocation.UpdateFileChange
uploadMetaString := r.FormValue(getFormFieldName(fileOperation))
err := json.Unmarshal([]byte(uploadMetaString), &formData)

if err == nil {
return fsh.checkIfFileAlreadyExists(ctx, allocationObj.ID, formData.Path)
}
}
return nil
}