Skip to content

Commit

Permalink
#523 PID scoped Accounts
Browse files Browse the repository at this point in the history
Enable submitting PID ranges while adding account

Signed-off-by: Abdulbois <abdulbois.tursunov@dsr-corporation.com>
Signed-off-by: Abdulbois <abdulbois123@gmail.com>
  • Loading branch information
Abdulbois committed Dec 27, 2023
1 parent 15cbeb0 commit 70e5464
Show file tree
Hide file tree
Showing 45 changed files with 1,795 additions and 260 deletions.
33 changes: 32 additions & 1 deletion cmd/dcld/cmd/genaccounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/spf13/cast"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types"
dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types"
"github.com/zigbee-alliance/distributed-compliance-ledger/x/dclgenutil"
dclgenutiltypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclgenutil/types"
Expand All @@ -29,6 +30,7 @@ const (
FlagPubKey = "pubkey"
FlagRoles = "roles"
FlagVID = "vid"
FlagPIDs = "pid_ranges"
)

// AddGenesisAccountCmd returns add-genesis-account cobra Command.
Expand Down Expand Up @@ -109,8 +111,36 @@ the address will be looked up in the local Keybase.
}
}

var pidRanges []*types.Int32Range
if pidStrRanges := viper.GetString(FlagPIDs); len(pidStrRanges) > 0 { //nolint:nestif
var lastMax int32
for _, pidStrRange := range strings.Split(pidStrRanges, ",") {
pidRange := strings.Split(pidStrRange, "-")
if len(pidRange) != 2 {
return fmt.Errorf("failed to parse PID Range")
}
min, err := cast.ToInt32E(pidRange[0])
if err != nil {
return err
}
max, err := cast.ToInt32E(pidRange[1])
if err != nil {
return err
}
if min > max || max == 0 || min == 0 {
return fmt.Errorf("invalid PID Range is provided: min=%d, max=%d", min, max)
}
if max <= lastMax || min <= lastMax {
return fmt.Errorf("invalid PID Range is provided: {%d-%d}, ranges are overlapped, range items must be provided in increased order", min, max)
}
pid := types.Int32Range{Min: min, Max: max}
pidRanges = append(pidRanges, &pid)
lastMax = max
}
}

// FIXME issue 99 VendorID
genAccount = dclauthtypes.NewAccount(ba, roles, []*dclauthtypes.Grant{}, []*dclauthtypes.Grant{}, vendorID)
genAccount = dclauthtypes.NewAccount(ba, roles, []*dclauthtypes.Grant{}, []*dclauthtypes.Grant{}, vendorID, pidRanges)

if err := genAccount.Validate(); err != nil {
return fmt.Errorf("failed to validate new genesis account: %w", err)
Expand Down Expand Up @@ -154,6 +184,7 @@ the address will be looked up in the local Keybase.
cmd.Flags().String(FlagRoles, "",
fmt.Sprintf("The list of roles (split by comma) to assign to account (supported roles: %v)", dclauthtypes.Roles))
cmd.Flags().String(FlagVID, "", "Vendor ID associated with this account. Required only for Vendor Roles")
cmd.Flags().String(FlagPIDs, "", "The list of Product ID ranges (split by \"-\") associated with this account (for example: 1-101,101-6554)")

cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
Expand Down
6 changes: 5 additions & 1 deletion docs/how-to.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Once approved the account can be used to send transactions. See [use_case_txn_au
### 1. Create an Account proposal for the user

```bash
dcld tx auth propose-add-account --address=<bench32 encoded string> --pubkey=<protobuf JSON encoded> --roles=<role1,role2,...> --vid=<uint16> --from=<account>
dcld tx auth propose-add-account --address=<bench32 encoded string> --pubkey=<protobuf JSON encoded> --roles=<role1,role2,...> --vid=<uint16> --pid_ranges=<uint16-range,uint16-range,...> --from=<account>
```

### 2. Approve proposed Account
Expand Down Expand Up @@ -211,6 +211,7 @@ Minimal command:
```bash
dcld tx model add-model --vid=<uint16> --pid=<uint16> --deviceTypeID=<uint16> --productName=<string> --from=<account>
```
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range

Full command:

Expand All @@ -229,6 +230,7 @@ Minimal command:
dcld tx model add-model-version --vid=<uint16> --pid=<uint16> --softwareVersion=<uint32> --softwareVersionString=<string> --cdVersionNumber=<uint32>
--minApplicableSoftwareVersion=<uint32> --maxApplicableSoftwareVersion=<uint32> --from=<account>
```
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range

Full command:

Expand All @@ -250,12 +252,14 @@ dcld tx vendorinfo update-vendor --vid=<uint16> ... --from=<account>
```bash
dcld tx model update-model --vid=<uint16> --pid=<uint16> ... --from=<account>
```
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range

### 7. Edit Model Version

```bash
dcld tx model update-model-version --vid=<uint16> --pid=<uint16> --softwareVersion=<uint32> ... --from=<account>
```
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range

### 8. Add PKI Revocation Distribution Point

Expand Down
3 changes: 2 additions & 1 deletion docs/transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1383,14 +1383,15 @@ will be in a pending state until sufficient number of approvals is received.
- address: `string` - account address; Bech32 encoded
- pub_key: `string` - account's Protobuf JSON encoded public key
- vid: `optional(uint16)` - vendor ID (only needed for vendor role)
- pid_ranges: `optional(array<uint16 range>)` - the list if product-id ranges(range item separated with "-"), comma-separated, in increasing order, associated with this account: `1-100,101-200...`
- roles: `array<string>` - the list of roles, comma-separated, assigning to the account. Supported roles: `Vendor`, `TestHouse`, `CertificationCenter`, `Trustee`, `NodeAdmin`, `VendorAdmin`.
- info: `optional(string)` - information/notes for the proposal
- time: `optional(int64)` - proposal time (number of nanoseconds elapsed since January 1, 1970 UTC). CLI uses the current time for that field.
- In State: `dclauth/PendingAccount/value/<address>`
- Who can send:
- Trustee
- CLI command:
- `dcld tx auth propose-add-account --address=<bench32 encoded string> --pubkey=<protobuf JSON encoded> --roles=<role1,role2,...> --vid=<uint16> --from=<account>`
- `dcld tx auth propose-add-account --address=<bench32 encoded string> --pubkey=<protobuf JSON encoded> --roles=<role1,role2,...> --vid=<uint16> --pid_ranges=<uint16-range,uint16-range,...> --from=<account>`

### APPROVE_ADD_ACCOUNT

Expand Down
100 changes: 100 additions & 0 deletions integration_tests/cli/auth-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,106 @@ check_response "$result" "\[\]"

test_divider

# Check creating Vendor Account with valid pid ranges: success-case
pid_ranges="1-100,101-200"

test_divider
echo "Check creating Vendor Account with valid pid ranges: success-case"
random_string user
echo "$user generates keys"
cmd="(echo $passphrase; echo $passphrase) | dcld keys add $user"
result="$(bash -c "$cmd")"

test_divider

echo "Get key info for $user"
result=$(echo $passphrase | dcld keys show $user)
check_response "$result" "\"name\": \"$user\""

test_divider

user_address=$(echo $passphrase | dcld keys show $user -a)
user_pubkey=$(echo $passphrase | dcld keys show $user -p)

test_divider

echo "Jack proposes account for $user"
result=$(echo $passphrase | dcld tx auth propose-add-account --info="Jack is proposing this account" --address="$user_address" --pubkey="$user_pubkey" --roles="Vendor" --vid=$vid --pid_ranges=$pid_ranges --from jack --yes)
check_response "$result" "\"code\": 0"

test_divider

echo "Get all active accounts. $user account in the list because has enough approvals"
result=$(dcld query auth all-accounts)
check_response "$result" "\"address\": \"$user_address\""

test_divider

echo "Get an account for $user"
result=$(dcld query auth account --address=$user_address)
check_response "$result" "\"address\": \"$user_address\""
check_response_and_report "$result" $jack_address "json"
check_response_and_report "$result" '"info": "Jack is proposing this account"' "json"

test_divider

echo "Get an proposed account for $user is not found"
result=$(dcld query auth proposed-account --address=$user_address)
check_response "$result" "Not Found"

test_divider

echo "Get all proposed accounts. $user account is not in the list"
result=$(dcld query auth all-proposed-accounts)
check_response "$result" "\[\]"

test_divider

# Check creating Vendor Account with invalid pid ranges: negative-case
invalid_pid_ranges="100-101,1-200"

test_divider
echo "Check creating Vendor Account with invalid pid ranges: negative-case"
random_string user
echo "$user generates keys"
cmd="(echo $passphrase; echo $passphrase) | dcld keys add $user"
result="$(bash -c "$cmd")"

test_divider

echo "Get key info for $user"
result=$(echo $passphrase | dcld keys show $user)
check_response "$result" "\"name\": \"$user\""

test_divider

user_address=$(echo $passphrase | dcld keys show $user -a)
user_pubkey=$(echo $passphrase | dcld keys show $user -p)

test_divider

echo "Jack proposes account for $user"
result=$(echo $passphrase | dcld tx auth propose-add-account --info="Jack is proposing this account" --address="$user_address" --pubkey="$user_pubkey" --roles="Vendor" --vid=$vid --pid_ranges=$invalid_pid_ranges --from jack --yes 2>&1) || true
check_response "$result" "invalid PID Range is provided" raw

echo "Get an proposed account for $user is not found"
result=$(dcld query auth proposed-account --address=$user_address)
check_response "$result" "Not Found"

test_divider

echo "Get all proposed accounts. $user account is not in the list"
result=$(dcld query auth all-proposed-accounts)
check_response "$result" "\[\]"

test_divider

echo "Get all active accounts. $user account is not in the list because has not enough approvals received"
result=$(dcld query auth all-accounts)
response_does_not_contain "$result" "\"address\": \"$user_address\""

test_divider

random_string new_trustee1
echo "$new_trustee1 generates keys"
cmd="(echo $passphrase; echo $passphrase) | dcld keys add $new_trustee1"
Expand Down
11 changes: 9 additions & 2 deletions integration_tests/cli/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,15 @@ create_new_vendor_account(){
_address=$(echo $passphrase | dcld keys show $_name -a)
_pubkey=$(echo $passphrase | dcld keys show $_name -p)

echo "Jack proposes account for \"$_name\" with Vendor role"
_result=$(echo $passphrase | dcld tx auth propose-add-account --address="$_address" --pubkey="$_pubkey" --roles=Vendor --vid=$_vid --from jack --yes)
local _result=""
if [ $# -eq 3 ]; then
local _pid_ranges="$3"
echo "Jack proposes account for \"$_name\" with Vendor role and with [$_pid_ranges] associated Product IDs"
_result=$(echo $passphrase | dcld tx auth propose-add-account --address="$_address" --pubkey="$_pubkey" --roles=Vendor --vid=$_vid --pid_ranges=$_pid_ranges --from jack --yes)
else
echo "Jack proposes account for \"$_name\" with Vendor role"
_result=$(echo $passphrase | dcld tx auth propose-add-account --address="$_address" --pubkey="$_pubkey" --roles=Vendor --vid=$_vid --from jack --yes)
fi
check_response "$_result" "\"code\": 0"

}
Expand Down
48 changes: 48 additions & 0 deletions integration_tests/cli/model-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ create_new_vendor_account $vendor_account $vid

test_divider

((vid_with_pids=vid + 1))
pid_ranges="$pid-$pid"
vendor_account_with_pids=vendor_account_$vid_with_pids
echo "Create Vendor account - $vid_with_pids with ProductIDs - $pid_ranges"
create_new_vendor_account $vendor_account_with_pids $vid_with_pids $pid_ranges

test_divider

# Body

echo "Query non existent model"
Expand Down Expand Up @@ -57,6 +65,14 @@ echo "$result"

test_divider

productLabel="Device #1"
echo "Add Model with VID: $vid_with_pids PID: $pid"
result=$(echo "test1234" | dcld tx model add-model --vid=$vid_with_pids --pid=$pid --deviceTypeID=1 --productName=TestProduct --productLabel="$productLabel" --partNumber=1 --commissioningCustomFlow=0 --from=$vendor_account_with_pids --yes)
check_response "$result" "\"code\": 0"
echo "$result"

test_divider

echo "Get Model with VID: $vid PID: $pid"
result=$(dcld query model get-model --vid=$vid --pid=$pid)
check_response "$result" "\"vid\": $vid"
Expand All @@ -75,6 +91,13 @@ echo "$result"

test_divider

echo "Create Model Versions with VID: $vid_with_pids PID: $pid SoftwareVersion: $sv"
result=$(echo "test1234" | dcld tx model add-model-version --vid=$vid_with_pids --pid=$pid --softwareVersion=$sv --minApplicableSoftwareVersion=1 --maxApplicableSoftwareVersion=15 --softwareVersionString=$sv --cdVersionNumber=$cd_version_num --from=$vendor_account_with_pids --yes)
check_response "$result" "\"code\": 0"
echo "$result"

test_divider

echo "Get all models"
result=$(dcld query model all-models)
check_response "$result" "\"vid\": $vid"
Expand All @@ -98,6 +121,13 @@ echo "$result"

test_divider

echo "Update Model with VID: ${vid_with_pids} PID: ${pid} with new description"
result=$(echo "test1234" | dcld tx model update-model --vid=$vid_with_pids --pid=$pid --from $vendor_account_with_pids --yes --productLabel "$description")
check_response "$result" "\"code\": 0"
echo "$result"

test_divider

echo "Get Model with VID: ${vid} PID: ${pid}"
result=$(dcld query model get-model --vid=$vid --pid=$pid)
check_response "$result" "\"vid\": $vid"
Expand Down Expand Up @@ -130,14 +160,32 @@ echo "$result"

test_divider

echo "Delete Model with VID: ${vid_with_pids} PID: ${pid}"
result=$(dcld tx model delete-model --vid=$vid_with_pids --pid=$pid --from=$vendor_account_with_pids --yes)
echo "$result"

test_divider

echo "Query non existent model"
result=$(dcld query model get-model --vid=$vid --pid=$pid)
check_response "$result" "Not Found"
echo "$result"

test_divider

echo "Query non existent model"
result=$(dcld query model get-model --vid=$vid_with_pids --pid=$pid)
check_response "$result" "Not Found"
echo "$result"

test_divider

echo "Query model versions for deleted model"
result=$(dcld query model model-version --vid=$vid --pid=$pid --softwareVersion=$sv)
check_response "$result" "Not Found"
echo "$result"

echo "Query model versions for deleted model"
result=$(dcld query model model-version --vid=$vid_with_pids --pid=$pid --softwareVersion=$sv)
check_response "$result" "Not Found"
echo "$result"
11 changes: 11 additions & 0 deletions integration_tests/cli/model-negative-cases.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ test_divider
echo "Create CertificationCenter account"
create_new_account zb_account "CertificationCenter"

((vid_with_pids=vid + 1))
pid_ranges="1-100"
vendor_account_with_pids=vendor_account_$vid_with_pids
echo "Create Vendor account - $vid_with_pids with ProductIDs - $pid_ranges"
create_new_vendor_account $vendor_account_with_pids $vid_with_pids $pid_ranges

# Body

# Ledger side errors
Expand All @@ -42,6 +48,11 @@ result=$(echo "test1234" | dcld tx model add-model --vid=$vid --pid=$pid --devic
check_response_and_report "$result" "\"code\": 4"
echo "$result"

echo "Add Model with VID: $vid_with_pids PID: 101 :Vendor with non-associated PID"
result=$(echo "test1234" | dcld tx model add-model --vid=$vid_with_pids --pid=101 --deviceTypeID=1 --productName=TestProduct --productLabel=TestingProductLabel --partNumber=1 --commissioningCustomFlow=0 --from=$vendor_account_with_pids --yes)
check_response_and_report "$result" "\"code\": 4"
echo "$result"

test_divider

vid1=$RANDOM
Expand Down
23 changes: 14 additions & 9 deletions integration_tests/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types"
)

func strToPubKey(pkStr string, cdc codec.Codec) cryptotypes.PubKey {
Expand Down Expand Up @@ -130,15 +131,19 @@ var (
UpgradePlanInfo = "Some upgrade info"

//
Address1, _ = sdk.AccAddressFromBech32("cosmos1s5xf3aanx7w84hgplk9z3l90qfpantg6nsmhpf")
Address2, _ = sdk.AccAddressFromBech32("cosmos1nl4uaesk9gtu7su3n89lne6xpa6lq8gljn79rq")
Address3, _ = sdk.AccAddressFromBech32("cosmos12r9vsus5js32pvnayt33zhcd4y9wcqcly45gr9")
Address4, _ = sdk.AccAddressFromBech32("cosmos1vvwldfef3yuggm7ge9p34d6dvpz5s74nus6n7g")
VendorID1 int32 = 1000
VendorID2 int32 = 2000
VendorID3 int32 = 3000
VendorID4 int32 = 4000
PubKey1 = strToPubKey(
Address1, _ = sdk.AccAddressFromBech32("cosmos1s5xf3aanx7w84hgplk9z3l90qfpantg6nsmhpf")
Address2, _ = sdk.AccAddressFromBech32("cosmos1nl4uaesk9gtu7su3n89lne6xpa6lq8gljn79rq")
Address3, _ = sdk.AccAddressFromBech32("cosmos12r9vsus5js32pvnayt33zhcd4y9wcqcly45gr9")
Address4, _ = sdk.AccAddressFromBech32("cosmos1vvwldfef3yuggm7ge9p34d6dvpz5s74nus6n7g")
VendorID1 int32 = 1000
VendorID2 int32 = 2000
VendorID3 int32 = 3000
VendorID4 int32 = 4000
ProductIDsEmpty []*types.Int32Range
ProductIDsFull = append([]*types.Int32Range{}, &types.Int32Range{Min: 1, Max: 65535})
ProductIDs100 = append([]*types.Int32Range{}, &types.Int32Range{Min: 1, Max: 100})
ProductIDs200 = append([]*types.Int32Range{}, &types.Int32Range{Min: 1, Max: 100}, &types.Int32Range{Min: 101, Max: 200})
PubKey1 = strToPubKey(
`{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Aw1XXHQ8i6JVNKsFQ9eQArJVt2GXEO0EBFsQL6XJ5BxY"}`,
defEncConfig.Marshaler,
)
Expand Down
Loading

0 comments on commit 70e5464

Please sign in to comment.