Skip to content
This repository was archived by the owner on Sep 6, 2022. It is now read-only.

Commit f93cff6

Browse files
fix: aggregate permissions (#142)
* fix: aggregate permissions * examples * Update chaincode/tuple_aggregate.go Co-authored-by: Matthieu Blottière <49146345+mblottiere@users.noreply.github.com> * implement as union * remove print * make linter happy Co-authored-by: Matthieu Blottière <49146345+mblottiere@users.noreply.github.com>
1 parent beacebd commit f93cff6

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

chaincode/permissions.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,39 @@ func mergePermissions(x, y Permission) Permission {
119119
return priv
120120
}
121121

122+
// UnionPermissions returns the union between two sets of permissions
123+
func UnionPermissions(x, y Permissions) Permissions {
124+
perm := Permissions{}
125+
perm.Process = unionPermissions(x.Process, y.Process)
126+
perm.Download = unionPermissions(x.Download, y.Download)
127+
return perm
128+
}
129+
130+
func unionPermissions(x, y Permission) Permission {
131+
res := Permission{
132+
Public: x.Public || y.Public,
133+
}
134+
if !res.Public {
135+
res.AuthorizedIDs = x.getNodesUnion(y)
136+
}
137+
return res
138+
}
139+
140+
func (priv Permission) getNodesUnion(p Permission) []string {
141+
authorizedIds := map[string]bool{}
142+
for _, i := range priv.AuthorizedIDs {
143+
authorizedIds[i] = true
144+
}
145+
for _, i := range p.AuthorizedIDs {
146+
authorizedIds[i] = true
147+
}
148+
res := make([]string, 0, len(authorizedIds))
149+
for k := range authorizedIds {
150+
res = append(res, k)
151+
}
152+
return res
153+
}
154+
122155
func (priv Permission) getNodesIntersection(p Permission) []string {
123156
nodes := []string{}
124157
for _, i := range priv.AuthorizedIDs {

chaincode/tuple_aggregate.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (tuple *Aggregatetuple) SetFromInput(db *LedgerDB, inp inputAggregatetuple)
6464
func (tuple *Aggregatetuple) SetFromParents(db *LedgerDB, inModels []string) error {
6565
var parentStatuses []string
6666
inModelKeys := tuple.InModelKeys
67-
permissions, err := NewPermissions(db, OpenPermissions)
67+
permissions, err := NewPermissions(db, inputPermissions{})
6868
if err != nil {
6969
return errors.BadRequest(err, "could not generate open permissions")
7070
}
@@ -82,7 +82,6 @@ func (tuple *Aggregatetuple) SetFromParents(db *LedgerDB, inModels []string) err
8282
case CompositeTraintupleType:
8383
tuple, err := db.GetCompositeTraintuple(parentTraintupleKey)
8484
if err == nil {
85-
// if the parent is composite, always take the "trunk" out-model
8685
parentPermissions = tuple.OutTrunkModel.Permissions
8786
parentStatuses = append(parentStatuses, tuple.Status)
8887
}
@@ -107,7 +106,7 @@ func (tuple *Aggregatetuple) SetFromParents(db *LedgerDB, inModels []string) err
107106
}
108107

109108
inModelKeys = append(inModelKeys, parentTraintupleKey)
110-
permissions = MergePermissions(permissions, parentPermissions)
109+
permissions = UnionPermissions(permissions, parentPermissions)
111110
}
112111
tuple.Status = determineStatusFromInModels(parentStatuses)
113112
tuple.InModelKeys = inModelKeys

chaincode/tuple_aggregate_test.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ func TestTraintupleAggregate(t *testing.T) {
273273
Status: StatusTodo,
274274
Permissions: outputPermissions{
275275
Process: Permission{
276-
Public: true,
277-
AuthorizedIDs: []string{},
276+
Public: false,
277+
AuthorizedIDs: []string{workerA},
278278
},
279279
},
280280
Metadata: map[string]string{},
@@ -507,8 +507,33 @@ func TestAggregatetuplePermissions(t *testing.T) {
507507
// verify permissions
508508
assert.EqualValues(t, false, aggr.Permissions.Process.Public,
509509
"the aggregate tuple should not be public")
510-
assert.EqualValues(t, []string{workerA, "nodeC"}, aggr.Permissions.Process.AuthorizedIDs,
511-
"the aggregate tuple permissions should be the intersect of the in-model permissions")
510+
assert.True(t, sameStringSlice([]string{workerA, "nodeA", "nodeB", "nodeC", "nodeD"}, aggr.Permissions.Process.AuthorizedIDs),
511+
"the aggregate tuple permissions should be union of the in-model permissions")
512+
}
513+
514+
// return true if slices contain the same elements, regardless of order
515+
// https://stackoverflow.com/a/36000696/1370722
516+
func sameStringSlice(x, y []string) bool {
517+
if len(x) != len(y) {
518+
return false
519+
}
520+
// create a map of string -> int
521+
diff := make(map[string]int, len(x))
522+
for _, _x := range x {
523+
// 0 value for int is 0, so just increment a counter for the string
524+
diff[_x]++
525+
}
526+
for _, _y := range y {
527+
// If the string _y is not in diff bail out early
528+
if _, ok := diff[_y]; !ok {
529+
return false
530+
}
531+
diff[_y]--
532+
if diff[_y] == 0 {
533+
delete(diff, _y)
534+
}
535+
}
536+
return len(diff) == 0
512537
}
513538

514539
func TestAggregatetupleLogSuccessFail(t *testing.T) {

0 commit comments

Comments
 (0)