From e881f2df462d8ad01fa6f885e0ec8ae34406e73f Mon Sep 17 00:00:00 2001 From: Andrenerd Date: Mon, 3 May 2021 06:03:37 +0200 Subject: [PATCH 1/2] add validation for uploadMeta and updateMeta request data --- .../blobbercore/allocation/newfilechange.go | 19 +++++++++----- .../allocation/updatefilechange.go | 10 ++++--- code/go/0chain.net/blobbercore/util/json.go | 26 +++++++++++++++++++ 3 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 code/go/0chain.net/blobbercore/util/json.go diff --git a/code/go/0chain.net/blobbercore/allocation/newfilechange.go b/code/go/0chain.net/blobbercore/allocation/newfilechange.go index bc8bbd76b..9ea04fe6e 100644 --- a/code/go/0chain.net/blobbercore/allocation/newfilechange.go +++ b/code/go/0chain.net/blobbercore/allocation/newfilechange.go @@ -5,26 +5,28 @@ import ( "encoding/json" "path/filepath" "strings" + "reflect" "0chain.net/blobbercore/filestore" "0chain.net/blobbercore/reference" "0chain.net/blobbercore/stats" + "0chain.net/blobbercore/util" "0chain.net/core/common" ) type NewFileChange struct { - ConnectionID string `json:"connection_id"` + ConnectionID string `json:"connection_id" validation:"required"` AllocationID string `json:"allocation_id"` - Filename string `json:"filename"` + Filename string `json:"filename" validation:"required"` ThumbnailFilename string `json:"thumbnail_filename"` - Path string `json:"filepath"` + Path string `json:"filepath" validation:"required"` Size int64 `json:"size"` Hash string `json:"content_hash,omitempty"` ThumbnailSize int64 `json:"thumbnail_size"` ThumbnailHash string `json:"thumbnail_content_hash,omitempty"` MerkleRoot string `json:"merkle_root,omitempty"` - ActualHash string `json:"actual_hash,omitempty"` - ActualSize int64 `json:"actual_size,omitempty"` + ActualHash string `json:"actual_hash,omitempty" validation:"required"` + ActualSize int64 `json:"actual_size,omitempty" validation:"required"` ActualThumbnailSize int64 `json:"actual_thumb_size"` ActualThumbnailHash string `json:"actual_thumb_hash"` MimeType string `json:"mimetype,omitempty"` @@ -120,8 +122,11 @@ func (nf *NewFileChange) Marshal() (string, error) { } func (nf *NewFileChange) Unmarshal(input string) error { - err := json.Unmarshal([]byte(input), nf) - return err + if err := json.Unmarshal([]byte(input), nf); err != nil { + return err + } + + return util.UnmarshalValidation(reflect.ValueOf(nf).Elem()) } func (nf *NewFileChange) DeleteTempFile() error { diff --git a/code/go/0chain.net/blobbercore/allocation/updatefilechange.go b/code/go/0chain.net/blobbercore/allocation/updatefilechange.go index c70238472..f80c835ea 100644 --- a/code/go/0chain.net/blobbercore/allocation/updatefilechange.go +++ b/code/go/0chain.net/blobbercore/allocation/updatefilechange.go @@ -4,11 +4,12 @@ import ( "context" "encoding/json" "path/filepath" + "reflect" "0chain.net/blobbercore/filestore" "0chain.net/blobbercore/stats" - "0chain.net/blobbercore/reference" + "0chain.net/blobbercore/util" "0chain.net/core/common" . "0chain.net/core/logging" @@ -94,8 +95,11 @@ func (nf *UpdateFileChange) Marshal() (string, error) { } func (nf *UpdateFileChange) Unmarshal(input string) error { - err := json.Unmarshal([]byte(input), nf) - return err + if err := json.Unmarshal([]byte(input), nf); err != nil { + return err + } + + return util.UnmarshalValidation(reflect.ValueOf(nf).Elem()) } func (nf *UpdateFileChange) DeleteTempFile() error { diff --git a/code/go/0chain.net/blobbercore/util/json.go b/code/go/0chain.net/blobbercore/util/json.go new file mode 100644 index 000000000..0850b6965 --- /dev/null +++ b/code/go/0chain.net/blobbercore/util/json.go @@ -0,0 +1,26 @@ +package util + +import ( + "fmt" + "strings" + "reflect" + "errors" +) + +// Validate unmarshalled data with tag-based rules +// Example: +// struct { +// Name string `json:"name" validation:"required"` +// } +func UnmarshalValidation(fields reflect.Value) error { + for i := 0; i < fields.NumField(); i++ { + validation := fields.Type().Field(i).Tag.Get("validation") + if strings.Contains(validation, "required") && fields.Field(i).IsZero() { + // todo: better try this first: + // jsonFieldName := fields.Type().Field(i).Tag.Get("json") + return errors.New(fmt.Sprintf("The '%s' field is required", fields.Type().Field(i).Name)) + } + } + + return nil +} From 69651799eb905d79f6512cf1c21ec2e88e190f10 Mon Sep 17 00:00:00 2001 From: Andrenerd Date: Tue, 4 May 2021 03:52:19 +0200 Subject: [PATCH 2/2] add tests, polish code --- code/go/0chain.net/blobbercore/allocation/newfilechange.go | 3 +-- code/go/0chain.net/blobbercore/allocation/updatefilechange.go | 3 +-- code/go/0chain.net/blobbercore/util/json.go | 4 +++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/go/0chain.net/blobbercore/allocation/newfilechange.go b/code/go/0chain.net/blobbercore/allocation/newfilechange.go index 9ea04fe6e..280e2cd6d 100644 --- a/code/go/0chain.net/blobbercore/allocation/newfilechange.go +++ b/code/go/0chain.net/blobbercore/allocation/newfilechange.go @@ -5,7 +5,6 @@ import ( "encoding/json" "path/filepath" "strings" - "reflect" "0chain.net/blobbercore/filestore" "0chain.net/blobbercore/reference" @@ -126,7 +125,7 @@ func (nf *NewFileChange) Unmarshal(input string) error { return err } - return util.UnmarshalValidation(reflect.ValueOf(nf).Elem()) + return util.UnmarshalValidation(nf) } func (nf *NewFileChange) DeleteTempFile() error { diff --git a/code/go/0chain.net/blobbercore/allocation/updatefilechange.go b/code/go/0chain.net/blobbercore/allocation/updatefilechange.go index f80c835ea..835cd36ce 100644 --- a/code/go/0chain.net/blobbercore/allocation/updatefilechange.go +++ b/code/go/0chain.net/blobbercore/allocation/updatefilechange.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "path/filepath" - "reflect" "0chain.net/blobbercore/filestore" "0chain.net/blobbercore/stats" @@ -99,7 +98,7 @@ func (nf *UpdateFileChange) Unmarshal(input string) error { return err } - return util.UnmarshalValidation(reflect.ValueOf(nf).Elem()) + return util.UnmarshalValidation(nf) } func (nf *UpdateFileChange) DeleteTempFile() error { diff --git a/code/go/0chain.net/blobbercore/util/json.go b/code/go/0chain.net/blobbercore/util/json.go index 0850b6965..753023c2c 100644 --- a/code/go/0chain.net/blobbercore/util/json.go +++ b/code/go/0chain.net/blobbercore/util/json.go @@ -12,7 +12,9 @@ import ( // struct { // Name string `json:"name" validation:"required"` // } -func UnmarshalValidation(fields reflect.Value) error { +func UnmarshalValidation(v interface{}) error { + fields := reflect.ValueOf(v).Elem() + for i := 0; i < fields.NumField(); i++ { validation := fields.Type().Field(i).Tag.Get("validation") if strings.Contains(validation, "required") && fields.Field(i).IsZero() {