Skip to content

Commit

Permalink
Merge pull request #19 from ucan-wg/v1-fix-policy-examples-test
Browse files Browse the repository at this point in the history
fix: TestPolicyExamples/Any case
  • Loading branch information
fabiobozzo authored Sep 16, 2024
2 parents 700f130 + ad03154 commit 06e0674
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 18 deletions.
35 changes: 27 additions & 8 deletions capability/policy/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,22 @@ func matchStatement(statement Statement, node ipld.Node) bool {
switch statement.Kind() {
case KindEqual:
if s, ok := statement.(equality); ok {
one, _, err := selector.Select(s.selector, node)
if err != nil || one == nil {
one, many, err := selector.Select(s.selector, node)
if err != nil {
return false
}
return datamodel.DeepEqual(s.value, one)
if one != nil {
return datamodel.DeepEqual(s.value, one)
}
if many != nil {
for _, n := range many {
if eq := datamodel.DeepEqual(s.value, n); eq {
return true
}
}
}

return false
}
case KindGreaterThan:
if s, ok := statement.(equality); ok {
Expand Down Expand Up @@ -119,17 +130,25 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindAny:
if s, ok := statement.(quantifier); ok {
// FIXME: line below return a single node, not many
_, many, err := selector.Select(s.selector, node)
if err != nil || many == nil {
one, many, err := selector.Select(s.selector, node)
if err != nil {
return false
}
for _, n := range many {
ok := matchStatement(s.statement, n)
if one != nil {
ok := matchStatement(s.statement, one)
if ok {
return true
}
}
if many != nil {
for _, n := range many {
ok := matchStatement(s.statement, n)
if ok {
return true
}
}
}

return false
}
}
Expand Down
52 changes: 42 additions & 10 deletions capability/policy/selector/selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,26 +199,58 @@ func resolve(sel Selector, subject ipld.Node, at []string) (ipld.Node, []ipld.No

case seg.Field() != "":
at = append(at, seg.Field())
if cur == nil || cur.Kind() != datamodel.Kind_Map {
if cur == nil {
if seg.Optional() {
cur = nil
} else {
return nil, nil, newResolutionError(fmt.Sprintf("can not access field: %s on kind: %s", seg.Field(), kindString(cur)), at)
}
} else {
n, err := cur.LookupByString(seg.Field())
if err != nil {
if isMissing(err) {
if seg.Optional() {
cur = nil
switch cur.Kind() {
case datamodel.Kind_Map:
n, err := cur.LookupByString(seg.Field())
if err != nil {
if isMissing(err) {
if seg.Optional() {
cur = nil
} else {
return nil, nil, newResolutionError(fmt.Sprintf("object has no field named: %s", seg.Field()), at)
}
} else {
return nil, nil, newResolutionError(fmt.Sprintf("object has no field named: %s", seg.Field()), at)
return nil, nil, err
}
} else {
return nil, nil, err
cur = n
}
case datamodel.Kind_List:
var many []ipld.Node
it := cur.ListIterator()
for !it.Done() {
_, v, err := it.Next()
if err != nil {
return nil, nil, err
}
if v.Kind() == datamodel.Kind_Map {
n, err := v.LookupByString(seg.Field())
if err == nil {
many = append(many, n)
}
}
}
if len(many) > 0 {
cur = nil
return nil, many, nil
} else if seg.Optional() {
cur = nil
} else {
return nil, nil, newResolutionError(fmt.Sprintf("no elements in list have field named: %s", seg.Field()), at)
}
default:
if seg.Optional() {
cur = nil
} else {
return nil, nil, newResolutionError(fmt.Sprintf("can not access field: %s on kind: %s", seg.Field(), kindString(cur)), at)
}
} else {
cur = n
}
}

Expand Down

0 comments on commit 06e0674

Please sign in to comment.