Skip to content

Commit

Permalink
client/object: Add checks for ROOT and PHY props in SearchV2
Browse files Browse the repository at this point in the history
These filters are key-only, no sense to pass them otherwise.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
  • Loading branch information
cthulhu-rider committed Feb 24, 2025
1 parent 66489a1 commit 2e75853
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
9 changes: 9 additions & 0 deletions client/object_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ func (x *SearchObjectsOptions) SetCount(count uint32) { x.count = count }
// Max number of filters is 8. Max number of attributes is 8. If attributes are
// specified, the 1st filter must be about it. Neither filters nor
// attributes can contain [object.FilterContainerID] or [object.FilterID].
// Filters by [object.FilterRoot] and [object.FilterPhysical] properties must
// have zero value and matcher.
//
// Note that if requested attribute is missing in the matching object,
// corresponding element in its [SearchResultItem.Attributes] is empty.
Expand Down Expand Up @@ -250,6 +252,13 @@ func verifySearchFilter(f object.SearchFilter) error {
return errors.New("missing attribute")
case object.FilterContainerID, object.FilterID:
return fmt.Errorf("prohibited attribute %s", attr)
case object.FilterRoot, object.FilterPhysical:
if m := f.Operation(); m != 0 {
return fmt.Errorf("non-zero matcher %s for attribute %s", m, attr)
}
if val := f.Value(); val != "" {
return fmt.Errorf("value for attribute %s is prohibited", attr)
}
}
return nil
}
Expand Down
19 changes: 19 additions & 0 deletions client/object_search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,25 @@ func TestClient_SearchObjects(t *testing.T) {
_, _, err := okConn.SearchObjects(ctx, anyCID, fs, []string{"attr"}, anyRequestCursor, anyValidSigner, anyValidOpts)
require.EqualError(t, err, "invalid filter #1: missing attribute")
})
t.Run("key-only", func(t *testing.T) {
var fs object.SearchFilters
fs.AddFilter("attr", "val", object.MatchStringEqual)
fs.AddFilter(object.FilterRoot, "", 123)
_, _, err := okConn.SearchObjects(ctx, anyCID, fs, []string{"attr"}, anyRequestCursor, anyValidSigner, anyValidOpts)
require.EqualError(t, err, "invalid filter #1: non-zero matcher 123 for attribute $Object:ROOT")
fs = fs[:1]
fs.AddFilter(object.FilterRoot, "val", 0)
_, _, err = okConn.SearchObjects(ctx, anyCID, fs, []string{"attr"}, anyRequestCursor, anyValidSigner, anyValidOpts)
require.EqualError(t, err, "invalid filter #1: value for attribute $Object:ROOT is prohibited")
fs = fs[:1]
fs.AddFilter(object.FilterPhysical, "", 123)
_, _, err = okConn.SearchObjects(ctx, anyCID, fs, []string{"attr"}, anyRequestCursor, anyValidSigner, anyValidOpts)
require.EqualError(t, err, "invalid filter #1: non-zero matcher 123 for attribute $Object:PHY")
fs = fs[:1]
fs.AddFilter(object.FilterPhysical, "val", 0)
_, _, err = okConn.SearchObjects(ctx, anyCID, fs, []string{"attr"}, anyRequestCursor, anyValidSigner, anyValidOpts)
require.EqualError(t, err, "invalid filter #1: value for attribute $Object:PHY is prohibited")
})
})
t.Run("attributes", func(t *testing.T) {
for _, tc := range []struct {
Expand Down

0 comments on commit 2e75853

Please sign in to comment.