Skip to content

Commit

Permalink
keys are sanitised directly by orion, no need for extra sanitization (#…
Browse files Browse the repository at this point in the history
…431)

Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro authored Nov 16, 2022
1 parent 35c062a commit 6446a4c
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 51 deletions.
8 changes: 4 additions & 4 deletions integration/orion/cars/views/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (f *BuyerFlow) Call(context view.Context) (interface{}, error) {
func buyerValidateTransaction(loadedTx *otx.LoadedTransaction, buyerID, dmvID string) error {
newCarRec := &states.CarRecord{}
var newCarACL *types.AccessControl
writes := loadedTx.Writes()
writes, _ := loadedTx.Writes()
for _, dw := range writes {
switch {
case strings.HasPrefix(dw.Key, states.CarRecordKeyPrefix):
Expand Down Expand Up @@ -202,7 +202,7 @@ func (f *DMVFlow) Call(context view.Context) (interface{}, error) {
tx.SetNamespace("cars") // Sets the namespace where the state should be stored

if err = dmvValidateTransaction(tx, loadedTx, me); err != nil {
return nil, errors.Wrap(err, "error during buyer validate transaction")
return nil, errors.Wrap(err, "error during dmv validate transaction")
}

if err = loadedTx.Commit(); err != nil {
Expand All @@ -216,7 +216,7 @@ func (f *DMVFlow) Call(context view.Context) (interface{}, error) {

func dmvValidateTransaction(tx *otx.Transaction, loadedTx *otx.LoadedTransaction, dmvID string) error {
carRec := &states.CarRecord{}
reads := loadedTx.Reads()
reads, _ := loadedTx.Reads()
for _, dr := range reads {
recordBytes, err := tx.Get(dr.Key)
if err != nil {
Expand All @@ -234,7 +234,7 @@ func dmvValidateTransaction(tx *otx.Transaction, loadedTx *otx.LoadedTransaction

newCarRec := &states.CarRecord{}
var newCarACL *types.AccessControl
writes := loadedTx.Writes()
writes, _ := loadedTx.Writes()
for _, dw := range writes {
switch {
case strings.HasPrefix(dw.Key, states.CarRecordKeyPrefix):
Expand Down
61 changes: 38 additions & 23 deletions platform/orion/core/generic/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package generic

import (
"encoding/base64"
"net/url"
"encoding/hex"
"strings"
"time"

Expand All @@ -29,7 +28,7 @@ type DataTx struct {
}

func (d *DataTx) Put(db string, key string, bytes []byte, a driver.AccessControl) error {
key = sanitizeKey(key)
key = toOrionKey(key)
var ac *types.AccessControl
if a != nil {
var ok bool
Expand All @@ -45,7 +44,7 @@ func (d *DataTx) Put(db string, key string, bytes []byte, a driver.AccessControl
}

func (d *DataTx) Get(db string, key string) ([]byte, error) {
key = sanitizeKey(key)
key = toOrionKey(key)
r, _, err := d.dataTx.Get(db, key)
if err != nil {
return nil, errors.Wrapf(err, "failed getting data")
Expand All @@ -59,7 +58,7 @@ func (d *DataTx) Commit(sync bool) (string, error) {
}

func (d *DataTx) Delete(db string, key string) error {
key = sanitizeKey(key)
key = toOrionKey(key)
return d.dataTx.Delete(db, key)
}

Expand Down Expand Up @@ -97,36 +96,44 @@ func (l *LoadedDataTx) CoSignAndClose() ([]byte, error) {
return proto.Marshal(env)
}

func (l *LoadedDataTx) Reads() map[string][]*driver.DataRead {
func (l *LoadedDataTx) Reads() (map[string][]*driver.DataRead, error) {
res := map[string][]*driver.DataRead{}
source := l.loadedDataTx.Reads()
for s, reads := range source {
newReads := make([]*driver.DataRead, len(reads))
for i, read := range reads {
k, err := fromOrionKey(read.Key)
if err != nil {
return nil, errors.WithMessagef(err, "failed to decode read key [%s]", read.Key)
}
newReads[i] = &driver.DataRead{
Key: read.Key,
Key: k,
}
}
res[s] = newReads
}
return res
return res, nil
}

func (l *LoadedDataTx) Writes() map[string][]*driver.DataWrite {
func (l *LoadedDataTx) Writes() (map[string][]*driver.DataWrite, error) {
res := map[string][]*driver.DataWrite{}
source := l.loadedDataTx.Writes()
for s, writes := range source {
newWrites := make([]*driver.DataWrite, len(writes))
for i, write := range writes {
k, err := fromOrionKey(write.Key)
if err != nil {
return nil, errors.WithMessagef(err, "failed to decode write key [%s]", write.Key)
}
newWrites[i] = &driver.DataWrite{
Key: write.Key,
Key: k,
Value: write.Value,
Acl: write.Acl,
}
}
res[s] = newWrites
}
return res
return res, nil
}

func (l *LoadedDataTx) MustSignUsers() []string {
Expand Down Expand Up @@ -252,30 +259,38 @@ func (s *SessionManager) NewSession(id string) (driver.Session, error) {
return &Session{s: session}, err
}

// sanitizeKey makes sure that each component in the key can be correctly be url escaped
func sanitizeKey(key string) string {
escaped := false
// toOrionKey makes sure that each component in the key can be correctly be url escaped
func toOrionKey(key string) string {
key = strings.ReplaceAll(key, string(rune(0)), "~")
components := strings.Split(key, "~")
for i, c := range components {
cc := url.PathEscape(c)
if c != cc {
components[i] = base64.StdEncoding.EncodeToString([]byte(c))
escaped = true
b := strings.Builder{}
for i := 0; i < len(components); i++ {
b.WriteString(hex.EncodeToString([]byte(components[i])))
if i < len(components)-1 {
b.WriteRune('~')
}
}
if !escaped {
return key
if strings.HasSuffix(key, "~") {
b.WriteRune('~')
}
return b.String()
}

func fromOrionKey(key string) (string, error) {
components := strings.Split(key, "~")
b := strings.Builder{}
for i := 0; i < len(components); i++ {
b.WriteString(components[i])
decoded, err := hex.DecodeString(components[i])
if err != nil {
return "", errors.Wrapf(err, "failed to decode [%s]", key)
}
b.WriteString(string(decoded))
if i < len(components)-1 {
b.WriteRune('~')
}
}
if strings.HasSuffix(key, "~") {
b.WriteRune('~')
}
return b.String()
return b.String(), nil
}
4 changes: 2 additions & 2 deletions platform/orion/driver/sm.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ type LoadedDataTx interface {
ID() string
Commit() error
CoSignAndClose() ([]byte, error)
Reads() map[string][]*DataRead
Writes() map[string][]*DataWrite
Reads() (map[string][]*DataRead, error)
Writes() (map[string][]*DataWrite, error)
MustSignUsers() []string
SignedUsers() []string
}
Expand Down
15 changes: 1 addition & 14 deletions platform/orion/services/db/orion.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ SPDX-License-Identifier: Apache-2.0
package db

import (
"encoding/base64"
"strings"
"sync"

"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto"
Expand Down Expand Up @@ -284,18 +282,7 @@ func (db *Orion) Discard() error {
}

func dbKey(namespace, key string) string {
k := orionKey(namespace + keys.NamespaceSeparator + key)
components := strings.Split(k, "~")
var b strings.Builder
for _, component := range components {
b.WriteString(base64.StdEncoding.EncodeToString([]byte(component)))
b.WriteString("~")
}
return b.String()
}

func orionKey(key string) string {
return strings.ReplaceAll(key, string(rune(0)), "~")
return namespace + keys.NamespaceSeparator + key
}

func (db *Orion) versionedValue(txn *orion.Transaction, dbKey string) (*dbproto.VersionedValue, error) {
Expand Down
20 changes: 14 additions & 6 deletions platform/orion/services/otx/loaded.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,28 @@ func (lt *LoadedTransaction) CoSignAndClose() ([]byte, error) {
return t.CoSignAndClose()
}

func (lt *LoadedTransaction) Reads() []*orion.DataRead {
func (lt *LoadedTransaction) Reads() ([]*orion.DataRead, error) {
t, err := lt.getLoadedDataTx()
if err != nil {
return nil
return nil, err
}
reads, err := t.Reads()
if err != nil {
return nil, err
}
return t.Reads()[lt.Namespace]
return reads[lt.Namespace], nil
}

func (lt *LoadedTransaction) Writes() []*orion.DataWrite {
func (lt *LoadedTransaction) Writes() ([]*orion.DataWrite, error) {
t, err := lt.getLoadedDataTx()
if err != nil {
return nil
return nil, err
}
writes, err := t.Writes()
if err != nil {
return nil, err
}
return t.Writes()[lt.Namespace]
return writes[lt.Namespace], nil
}

func (lt *LoadedTransaction) MustSignUsers() []string {
Expand Down
4 changes: 2 additions & 2 deletions platform/orion/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ func (t *LoadedTransaction) CoSignAndClose() ([]byte, error) {
return t.loadedDataTx.CoSignAndClose()
}

func (t *LoadedTransaction) Reads() map[string][]*DataRead {
func (t *LoadedTransaction) Reads() (map[string][]*driver.DataRead, error) {
return t.loadedDataTx.Reads()
}

func (t *LoadedTransaction) Writes() map[string][]*DataWrite {
func (t *LoadedTransaction) Writes() (map[string][]*driver.DataWrite, error) {
return t.loadedDataTx.Writes()
}

Expand Down

0 comments on commit 6446a4c

Please sign in to comment.