Skip to content

Commit

Permalink
implement share filters for space id and state (#3312)
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas authored Oct 11, 2022
1 parent 67cd2fb commit 79b4014
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 23 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/share-filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Implemented new share filters

Added share filters for space ID and share state.

https://github.com/cs3org/reva/pull/3312
https://github.com/owncloud/ocis/issues/3843
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/cheggaaa/pb v1.0.29
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e
github.com/cs3org/go-cs3apis v0.0.0-20220929083235-bb0b1a236d6c
github.com/cs3org/go-cs3apis v0.0.0-20221005085457-19ea8088a512
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8
github.com/dgraph-io/ristretto v0.1.0
github.com/emvi/iso-639-1 v1.0.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJff
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
github.com/cs3org/go-cs3apis v0.0.0-20220929083235-bb0b1a236d6c h1:b+YTmOGlf43mnF8MzO0fsy8/Ho8JLu44Iq5Y0fKLJMM=
github.com/cs3org/go-cs3apis v0.0.0-20220929083235-bb0b1a236d6c/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/go-cs3apis v0.0.0-20221005085457-19ea8088a512 h1:xTvaIsLu1ezoWOJKnV0ehgiowkOiEhMaylaI1lD/Axw=
github.com/cs3org/go-cs3apis v0.0.0-20221005085457-19ea8088a512/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
2 changes: 1 addition & 1 deletion internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag
log.Debug().Msg("purging storage space")
// List all shares in this storage space
lsRes, err := s.ListShares(ctx, &collaborationv1beta1.ListSharesRequest{
Filters: []*collaborationv1beta1.Filter{share.SpaceIDFilter(id.SpaceId)}, // FIXME rename the filter? @c0rby
Filters: []*collaborationv1beta1.Filter{share.SpaceIDFilter(id.SpaceId)},
})
switch {
case err != nil:
Expand Down
2 changes: 1 addition & 1 deletion pkg/share/manager/jsoncs3/jsoncs3.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
}

if share.IsGrantedToUser(s, user) {
if share.MatchesFilters(s, filters) {
if share.MatchesFiltersWithState(s, state.State, filters) {
rs := &collaboration.ReceivedShare{
Share: s,
State: state.State,
Expand Down
55 changes: 41 additions & 14 deletions pkg/share/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ import (
)

const (
// SpaceIDFilterType defines a new filter type for space id.
// TODO: Remove once this filter type is in the CS3 API.
SpaceIDFilterType collaboration.Filter_Type = 7
// NoState can be used to signal the filter matching functions to ignore the share state.
NoState collaboration.ShareState = -1
)

//go:generate make --no-print-directory -C ../.. mockery NAME=Manager
Expand Down Expand Up @@ -121,11 +120,19 @@ func ResourceIDFilter(id *provider.ResourceId) *collaboration.Filter {
// SpaceIDFilter is an abstraction for creating filter by space id.
func SpaceIDFilter(id string) *collaboration.Filter {
return &collaboration.Filter{
Type: SpaceIDFilterType,
Term: &collaboration.Filter_ResourceId{
ResourceId: &provider.ResourceId{
SpaceId: id,
},
Type: collaboration.Filter_TYPE_SPACE_ID,
Term: &collaboration.Filter_SpaceId{
SpaceId: id,
},
}
}

// StateFilter is an abstraction for creating filter by share state.
func StateFilter(state collaboration.ShareState) *collaboration.Filter {
return &collaboration.Filter{
Type: collaboration.Filter_TYPE_STATE,
Term: &collaboration.Filter_State{
State: state,
},
}
}
Expand All @@ -152,7 +159,7 @@ func IsGrantedToUser(share *collaboration.Share, user *userv1beta1.User) bool {
}

// MatchesFilter tests if the share passes the filter.
func MatchesFilter(share *collaboration.Share, filter *collaboration.Filter) bool {
func MatchesFilter(share *collaboration.Share, state collaboration.ShareState, filter *collaboration.Filter) bool {
switch filter.Type {
case collaboration.Filter_TYPE_RESOURCE_ID:
return utils.ResourceIDEqual(share.ResourceId, filter.GetResourceId())
Expand All @@ -162,17 +169,19 @@ func MatchesFilter(share *collaboration.Share, filter *collaboration.Filter) boo
// This filter type is used to filter out "denial shares". These are currently implemented by having the permission "0".
// I.e. if the permission is 0 we don't want to show it.
return int(conversions.RoleFromResourcePermissions(share.Permissions.Permissions).OCSPermissions()) != 0
case SpaceIDFilterType:
return share.ResourceId.SpaceId == filter.GetResourceId().GetSpaceId()
case collaboration.Filter_TYPE_SPACE_ID:
return share.ResourceId.SpaceId == filter.GetSpaceId()
case collaboration.Filter_TYPE_STATE:
return state == filter.GetState()
default:
return false
}
}

// MatchesAnyFilter checks if the share passes at least one of the given filters.
func MatchesAnyFilter(share *collaboration.Share, filters []*collaboration.Filter) bool {
func MatchesAnyFilter(share *collaboration.Share, state collaboration.ShareState, filters []*collaboration.Filter) bool {
for _, f := range filters {
if MatchesFilter(share, f) {
if MatchesFilter(share, state, f) {
return true
}
}
Expand All @@ -189,7 +198,25 @@ func MatchesFilters(share *collaboration.Share, filters []*collaboration.Filter)
}
grouped := GroupFiltersByType(filters)
for _, f := range grouped {
if !MatchesAnyFilter(share, f) {
if !MatchesAnyFilter(share, NoState, f) {
return false
}
}
return true
}

// MatchesFiltersWithState checks if the share passes the given filters.
// This can check filter by share state
// Filters of the same type form a disjuntion, a logical OR. Filters of separate type form a conjunction, a logical AND.
// Here is an example:
// (resource_id=1 OR resource_id=2) AND (grantee_type=USER OR grantee_type=GROUP)
func MatchesFiltersWithState(share *collaboration.Share, state collaboration.ShareState, filters []*collaboration.Filter) bool {
if len(filters) == 0 {
return true
}
grouped := GroupFiltersByType(filters)
for _, f := range grouped {
if !MatchesAnyFilter(share, state, f) {
return false
}
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/share/share_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,16 @@ func TestMatchesFilter(t *testing.T) {
Permissions: &collaboration.SharePermissions{Permissions: &provider.ResourcePermissions{}},
}

if !MatchesFilter(share, ResourceIDFilter(id)) {
if !MatchesFilter(share, NoState, ResourceIDFilter(id)) {
t.Errorf("Expected share to pass the id filter. Share: %v", share)
}
if MatchesFilter(share, GroupGranteeFilter()) {
if MatchesFilter(share, NoState, GroupGranteeFilter()) {
t.Errorf("Expected share to not pass the grantee type filter. Share: %v", share)
}
if MatchesFilter(share, &collaboration.Filter{Type: collaboration.Filter_TYPE_EXCLUDE_DENIALS}) {
if MatchesFilter(share, NoState, &collaboration.Filter{Type: collaboration.Filter_TYPE_EXCLUDE_DENIALS}) {
t.Errorf("Expected share to not pass the exclude denials filter. Share: %v", share)
}
if MatchesFilter(share, &collaboration.Filter{Type: collaboration.Filter_TYPE_INVALID}) {
if MatchesFilter(share, NoState, &collaboration.Filter{Type: collaboration.Filter_TYPE_INVALID}) {
t.Errorf("Expected share to not pass an invalid filter. Share: %v", share)
}
}
Expand All @@ -153,12 +153,12 @@ func TestMatchesAnyFilter(t *testing.T) {
}

f1 := []*collaboration.Filter{UserGranteeFilter(), GroupGranteeFilter()}
if !MatchesAnyFilter(share, f1) {
if !MatchesAnyFilter(share, NoState, f1) {
t.Errorf("Expected share to match any of the given filters. Share: %v, Filters: %v", share, f1)
}

f2 := []*collaboration.Filter{ResourceIDFilter(&provider.ResourceId{StorageId: "something", OpaqueId: "different"}), GroupGranteeFilter()}
if MatchesAnyFilter(share, f2) {
if MatchesAnyFilter(share, NoState, f2) {
t.Errorf("Expected share to not match any of the given filters. Share: %v, Filters: %v", share, f2)
}
}
Expand Down

0 comments on commit 79b4014

Please sign in to comment.