Skip to content

Commit 1b76450

Browse files
committed
Add validation library
1 parent 552f505 commit 1b76450

File tree

12 files changed

+286
-151
lines changed

12 files changed

+286
-151
lines changed

.dockerignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.idea
2+
.vscode
23
build
34
localnet

go.mod

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ go 1.13
55
require (
66
github.com/cosmos/cosmos-sdk v0.37.4
77
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8
8+
github.com/go-playground/locales v0.14.0
9+
github.com/go-playground/universal-translator v0.18.0
10+
github.com/go-playground/validator/v10 v10.9.0
811
github.com/gorilla/mux v1.7.3
912
github.com/pkg/errors v0.8.1
1013
github.com/spf13/cobra v0.0.5
1114
github.com/spf13/pflag v1.0.3
1215
github.com/spf13/viper v1.6.1
13-
github.com/stretchr/testify v1.4.0
16+
github.com/stretchr/testify v1.7.0
1417
github.com/tendermint/go-amino v0.15.1
1518
github.com/tendermint/tendermint v0.32.8
1619
github.com/tendermint/tm-db v0.2.0

go.sum

+42-19
Large diffs are not rendered by default.

integration_tests/cli/vendorinfo-demo.sh

+66-3
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,73 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16+
set -euo pipefail
17+
source integration_tests/cli/common.sh
18+
19+
# Preparation of Actors
20+
vid=$RANDOM
21+
vid2=$RANDOM
22+
vendor_account=vendor_account_$vid
23+
second_vendor_account=vendor_account_$vid2
24+
echo "Create First Vendor Account - $vendor_account"
25+
create_new_vendor_account $vendor_account $vid
26+
echo "Create Second Vendor Account - $second_vendor_account"
27+
create_new_vendor_account $second_vendor_account $vid2
28+
29+
test_divider
30+
1631
# Create a vendor info record
32+
echo "Create VendorInfo Record for VID: $vid"
33+
companyLegalName="XYZ IOT Devices Inc"
34+
vendorName="XYZ Devices"
35+
result=$(echo "test1234" | dclcli tx vendorinfo add-vendor --vid=$vid --companyLegalName="$companyLegalName" --vendorName="$vendorName" --from=$vendor_account --yes)
36+
check_response "$result" "\"success\": true"
37+
echo "$result"
38+
39+
test_divider
40+
41+
# Query vendor info record
42+
echo "Verify if VendorInfo Record for VID: $vid is present or not"
43+
result=$(dclcli query vendorinfo vendor --vid=$vid)
44+
check_response "$result" "\"vendorId\": $vid"
45+
check_response "$result" "\"companyLegalName\": \"$companyLegalName\""
46+
check_response "$result" "\"vendorName\": \"$vendorName\""
47+
echo "$result"
48+
49+
test_divider
50+
51+
# Update vendor info record
52+
echo "Update vendor info record for VID: $vid"
53+
companyLegalName="ABC Subsidiary Corporation"
54+
vendorLandingPageUrl="https://www.w3.org/"
55+
result=$(echo "test1234" | dclcli tx vendorinfo update-vendor --vid=$vid --companyLegalName="$companyLegalName" --vendorLandingPageUrl=$vendorLandingPageUrl --vendorName="$vendorName" --from=$vendor_account --yes)
56+
check_response "$result" "\"success\": true"
57+
echo "$result"
58+
59+
test_divider
60+
61+
# Query updated vendor info record
62+
echo "Verify if VendorInfo Record for VID: $vid is updated or not"
63+
result=$(dclcli query vendorinfo vendor --vid=$vid)
64+
check_response "$result" "\"vendorId\": $vid"
65+
check_response "$result" "\"companyLegalName\": \"$companyLegalName\""
66+
check_response "$result" "\"vendorName\": \"$vendorName\""
67+
check_response "$result" "\"vendorLandingPageUrl\": \"$vendorLandingPageUrl\""
68+
echo "$result"
69+
70+
test_divider
71+
72+
# Create a vendor info record from a vendor account belonging to another vendor_account
73+
vid1=$RANDOM
74+
result=$(echo "test1234" | dclcli tx vendorinfo add-vendor --vid=$vid1 --companyLegalName="$companyLegalName" --vendorName="$vendorName" --from=$vendor_account --yes 2>&1) || true
75+
echo "$result"
76+
check_response_and_report "$result" "transaction should be signed by an vendor account associated with the vendorId $vid1"
1777

18-
# Update a vendor infor records
78+
test_divider
1979

20-
# Creata a vendor info record from a vendor account belonging to another vendor_account
80+
# Update a vendor info record from a vendor account belonging to another vendor_account
81+
result=$(echo "test1234" | dclcli tx vendorinfo update-vendor --vid=$vid --companyLegalName="$companyLegalName" --vendorName="$vendorName" --from=$second_vendor_account --yes 2>&1) || true
82+
echo "$result"
83+
check_response_and_report "$result" "transaction should be signed by an vendor account associated with the vendorId $vid"
2184

22-
# Update a vendor info record from a vendor account belonging to another vendor_account
85+
test_divider

integration_tests/constants/constants.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ var (
5151
SoftwareVersionValid = true
5252
OtaURL = "http://ota.firmware.com"
5353
OtaFileSize uint64 = 12345678
54-
OtaChecksum = "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" //nolint:lll
54+
OtaChecksum = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" //nolint:lll
5555
OtaChecksumType uint16 = 1
5656
OtaBlob = "OTABlob Text"
5757
CommissioningCustomFlow uint8 = 1

utils/validator/errors.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2020 DSR Corporation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package validator
16+
17+
import (
18+
sdk "github.com/cosmos/cosmos-sdk/types"
19+
)
20+
21+
const (
22+
Codespace sdk.CodespaceType = "Validation"
23+
CodeRequiredFieldMissing sdk.CodeType = 900
24+
CodeFieldMaxLengthExceeded sdk.CodeType = 901
25+
CodeFieldNotValid sdk.CodeType = 902
26+
)

utils/validator/validator.go

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright 2020 DSR Corporation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package validator
16+
17+
import (
18+
"fmt"
19+
20+
sdk "github.com/cosmos/cosmos-sdk/types"
21+
"github.com/go-playground/locales/en"
22+
ut "github.com/go-playground/universal-translator"
23+
"github.com/go-playground/validator/v10"
24+
en_translations "github.com/go-playground/validator/v10/translations/en"
25+
)
26+
27+
var (
28+
uni *ut.UniversalTranslator
29+
vl *validator.Validate
30+
)
31+
32+
func validate(s interface{}, performAddValidation bool) sdk.Error {
33+
34+
en := en.New()
35+
uni = ut.New(en, en)
36+
37+
trans, _ := uni.GetTranslator("en")
38+
39+
vl = validator.New()
40+
41+
vl.RegisterValidation("requiredForAdd", onlyRequiredForAdd)
42+
en_translations.RegisterDefaultTranslations(vl, trans)
43+
44+
_ = vl.RegisterTranslation("required", trans, func(ut ut.Translator) error {
45+
return ut.Add("required", "{0} is a required field", true) // see universal-translator for details
46+
}, func(ut ut.Translator, fe validator.FieldError) string {
47+
t, _ := ut.T("required", fe.Field())
48+
return t
49+
})
50+
51+
_ = vl.RegisterTranslation("requiredForAdd", trans, func(ut ut.Translator) error {
52+
return ut.Add("requiredForAdd", "{0} is a required field", true)
53+
}, func(ut ut.Translator, fe validator.FieldError) string {
54+
t, _ := ut.T("requiredForAdd", fe.Field())
55+
return t
56+
})
57+
58+
_ = vl.RegisterTranslation("max", trans, func(ut ut.Translator) error {
59+
return ut.Add("max", "maximum length for {0} allowed is {1}", true)
60+
}, func(ut ut.Translator, fe validator.FieldError) string {
61+
t, _ := ut.T("max", fe.Field(), fe.Param())
62+
return t
63+
})
64+
65+
_ = vl.RegisterTranslation("url", trans, func(ut ut.Translator) error {
66+
return ut.Add("url", "Field {0} : {1} is not a valid url", true)
67+
}, func(ut ut.Translator, fe validator.FieldError) string {
68+
t, _ := ut.T("url", fe.Field(), fmt.Sprintf("%v", fe.Value()))
69+
return t
70+
})
71+
72+
errs := vl.Struct(s)
73+
74+
if errs != nil {
75+
for _, e := range errs.(validator.ValidationErrors) {
76+
if e.Tag() == "max" {
77+
return sdk.NewError(Codespace, CodeFieldMaxLengthExceeded, e.Translate(trans))
78+
}
79+
if e.Tag() == "required" {
80+
return sdk.NewError(Codespace, CodeRequiredFieldMissing, e.Translate(trans))
81+
}
82+
if e.Tag() == "requiredForAdd" && performAddValidation {
83+
return sdk.NewError(Codespace, CodeRequiredFieldMissing, e.Translate(trans))
84+
}
85+
if e.Tag() == "url" {
86+
return sdk.NewError(Codespace, CodeFieldNotValid, e.Translate(trans))
87+
}
88+
89+
}
90+
}
91+
92+
return nil
93+
}
94+
95+
func ValidateUpdate(s interface{}) sdk.Error {
96+
return validate(s, false)
97+
}
98+
99+
func ValidateAdd(s interface{}) sdk.Error {
100+
return validate(s, true)
101+
102+
}
103+
104+
func onlyRequiredForAdd(fl validator.FieldLevel) bool {
105+
if fl.Field().String() == "" {
106+
return false
107+
} else {
108+
return true
109+
}
110+
}

x/modelversion/client/cli/tx.go

+5
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ func GetCmdUpdateModelVersion(cdc *codec.Codec) *cobra.Command {
225225

226226
softwareVersionValid := viper.GetBool(FlagSoftwareVersionValid)
227227

228+
firmwareDigests := viper.GetString(FlagFirmwareDigests)
229+
228230
otaURL := viper.GetString(FlagOtaURL)
229231
if len(otaURL) > 256 {
230232
types.ErrOtaURLInvalid(otaURL)
@@ -256,6 +258,7 @@ func GetCmdUpdateModelVersion(cdc *codec.Codec) *cobra.Command {
256258
PID: pid,
257259
SoftwareVersion: softwareVersion,
258260
SoftwareVersionValid: softwareVersionValid,
261+
FirmwareDigests: firmwareDigests,
259262
OtaURL: otaURL,
260263
MinApplicableSoftwareVersion: minApplicableSoftwareVersion,
261264
MaxApplicableSoftwareVersion: maxApplicableSofwareVersion,
@@ -278,6 +281,8 @@ func GetCmdUpdateModelVersion(cdc *codec.Codec) *cobra.Command {
278281
"Software Version of model (uint32)")
279282
cmd.Flags().String(FlagSoftwareVersionValid, "",
280283
"boolean flag to revoke the software version model")
284+
cmd.Flags().String(FlagFirmwareDigests, "",
285+
`FirmwareDigests field included in the Device Attestation response when this Software Image boots on the device`)
281286
cmd.Flags().String(FlagOtaURL, "", "URL where to obtain the OTA image")
282287
cmd.Flags().String(FlagMinApplicableSoftwareVersion, "",
283288
`MinApplicableSoftwareVersion should specify the lowest SoftwareVersion for which this image can be applied`)

x/modelversion/internal/types/msgs.go

+8-45
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ package types
1616

1717
import (
1818
sdk "github.com/cosmos/cosmos-sdk/types"
19+
"github.com/zigbee-alliance/distributed-compliance-ledger/utils/validator"
1920
)
2021

2122
const RouterKey = ModuleName
2223

2324
type MsgAddModelVersion struct {
2425
ModelVersion
25-
Signer sdk.AccAddress `json:"signer"`
26+
Signer sdk.AccAddress `json:"signer" validate:"required"`
2627
}
2728

2829
func NewMsgAddModelVersion(
@@ -44,37 +45,10 @@ func (m MsgAddModelVersion) Type() string {
4445
}
4546

4647
func (m MsgAddModelVersion) ValidateBasic() sdk.Error {
47-
if m.Signer.Empty() {
48-
return sdk.ErrInvalidAddress("Invalid Signer: it cannot be empty")
49-
}
50-
51-
if m.VID == 0 {
52-
return sdk.ErrUnknownRequest("Invalid VID: it must be non-zero 16-bit unsigned integer")
53-
}
54-
55-
if m.PID == 0 {
56-
return sdk.ErrUnknownRequest("Invalid PID: it must be non-zero 16-bit unsigned integer")
57-
}
58-
59-
if m.SoftwareVersion == 0 {
60-
return sdk.ErrUnknownRequest("Invalid SoftwareVersion: it must be non-zero 32-bit unsigned integer")
61-
}
62-
63-
if len(m.SoftwareVersionString) == 0 {
64-
return sdk.ErrUnknownRequest("Invalid SoftwareVersionString: it cannot be empty")
65-
}
66-
67-
if m.CDVersionNumber == 0 {
68-
return sdk.ErrUnknownRequest("Invalid CDVersionNumber: it must be non-zero 16-bit unsigned integer")
69-
}
70-
71-
if m.OtaURL != "" || m.OtaFileSize != 0 || m.OtaChecksum != "" || m.OtaChecksumType != 0 {
72-
if m.OtaURL == "" || m.OtaFileSize == 0 || m.OtaChecksum == "" || m.OtaChecksumType == 0 {
73-
return sdk.ErrUnknownRequest("Invalid MsgAddModelVersion: the fields OtaURL, OtaFileSize, OtaChecksum and " +
74-
"OtaChecksumType must be either specified together, or not specified together")
75-
}
48+
err := validator.ValidateAdd(m)
49+
if err != nil {
50+
return err
7651
}
77-
7852
return nil
7953
}
8054

@@ -110,20 +84,9 @@ func (m MsgUpdateModelVersion) Type() string {
11084
}
11185

11286
func (m MsgUpdateModelVersion) ValidateBasic() sdk.Error {
113-
if m.Signer.Empty() {
114-
return sdk.ErrInvalidAddress("Invalid Signer: it cannot be empty")
115-
}
116-
117-
if m.VID == 0 {
118-
return sdk.ErrUnknownRequest("Invalid VID: it must be non-zero 16-bit unsigned integer")
119-
}
120-
121-
if m.PID == 0 {
122-
return sdk.ErrUnknownRequest("Invalid PID: it must be non-zero 16-bit unsigned integer")
123-
}
124-
125-
if m.SoftwareVersion == 0 {
126-
return sdk.ErrUnknownRequest("Invalid SoftwareVersion: it must be non-zero 32-bit unsigned integer")
87+
err := validator.ValidateUpdate(m)
88+
if err != nil {
89+
return err
12790
}
12891

12992
return nil

x/modelversion/internal/types/types.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ import (
2020

2121
//nolint:maligned
2222
type ModelVersion struct {
23-
VID uint16 `json:"vid"`
24-
PID uint16 `json:"pid"`
25-
SoftwareVersion uint32 `json:"softwareVersion"`
26-
SoftwareVersionString string `json:"softwareVersionString,omitempty"`
27-
CDVersionNumber uint16 `json:"CDVersionNumber,omitempty"`
28-
FirmwareDigests string `json:"firmwareDigests,omitempty"`
23+
VID uint16 `json:"vid" validate:"required"`
24+
PID uint16 `json:"pid" validate:"required"`
25+
SoftwareVersion uint32 `json:"softwareVersion" validate:"required"`
26+
SoftwareVersionString string `json:"softwareVersionString,omitempty" validate:"requiredForAdd,max=64"`
27+
CDVersionNumber uint16 `json:"CDVersionNumber,omitempty" validate:"requiredForAdd"`
28+
FirmwareDigests string `json:"firmwareDigests,omitempty" validate:"max=512"`
2929
SoftwareVersionValid bool `json:"softwareVersionValid"`
30-
OtaURL string `json:"otaURL,omitempty"`
31-
OtaFileSize uint64 `json:"otaFileSize,omitempty"`
32-
OtaChecksum string `json:"otaChecksum,omitempty"`
33-
OtaChecksumType uint16 `json:"otaChecksumType,omitempty"`
34-
MinApplicableSoftwareVersion uint32 `json:"minApplicableSoftwareVersion,omitempty"`
35-
MaxApplicableSoftwareVersion uint32 `json:"maxApplicableSoftwareVersion,omitempty"`
36-
ReleaseNotesURL string `json:"releaseNotesURL,omitempty"`
30+
OtaURL string `json:"otaURL,omitempty" validate:"omitempty,url,max=256"`
31+
OtaFileSize uint64 `json:"otaFileSize,omitempty" validate:"required_with_all=OtaURL"`
32+
OtaChecksum string `json:"otaChecksum,omitempty" validate:"required_with_all=OtaURL,max=64"`
33+
OtaChecksumType uint16 `json:"otaChecksumType,omitempty" validate:"required_with_all=OtaURL"`
34+
MinApplicableSoftwareVersion uint32 `json:"minApplicableSoftwareVersion,omitempty" validate:"requiredForAdd"`
35+
MaxApplicableSoftwareVersion uint32 `json:"maxApplicableSoftwareVersion,omitempty" validate:"requiredForAdd"`
36+
ReleaseNotesURL string `json:"releaseNotesURL,omitempty" validate:"max=256"`
3737
}
3838

3939
func (d ModelVersion) String() string {

0 commit comments

Comments
 (0)