Skip to content

Commit

Permalink
improve public share filter handling
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed Oct 27, 2021
1 parent ab1db2a commit b5a4309
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 23 deletions.
33 changes: 10 additions & 23 deletions pkg/publicshare/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (m *manager) GetPublicShare(ctx context.Context, u *user.User, ref *link.Pu
}

if ref.GetId().GetOpaqueId() == ps.Id.OpaqueId {
if !notExpired(&ps) {
if publicshare.IsExpired(&ps) {
if err := m.revokeExpiredPublicShare(ctx, &ps, u); err != nil {
return nil, err
}
Expand Down Expand Up @@ -383,34 +383,21 @@ func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters []

if len(filters) == 0 {
shares = append(shares, &local.PublicShare)
} else {
for i := range filters {
if filters[i].Type == link.ListPublicSharesRequest_Filter_TYPE_RESOURCE_ID {
if utils.ResourceIDEqual(local.ResourceId, filters[i].GetResourceId()) {
if notExpired(&local.PublicShare) {
shares = append(shares, &local.PublicShare)
} else if err := m.revokeExpiredPublicShare(ctx, &local.PublicShare, u); err != nil {
return nil, err
}
}
continue
}

}
if publicshare.MatchesFilters(&local.PublicShare, filters) {
if !publicshare.IsExpired(&local.PublicShare) {
shares = append(shares, &local.PublicShare)
} else if err := m.revokeExpiredPublicShare(ctx, &local.PublicShare, u); err != nil {
return nil, err
}
}
}

return shares, nil
}

// notExpired tests whether a public share is expired
func notExpired(s *link.PublicShare) bool {
t := time.Unix(int64(s.Expiration.GetSeconds()), int64(s.Expiration.GetNanos()))
if (s.Expiration != nil && t.After(time.Now())) || s.Expiration == nil {
return true
}
return false
}

func (m *manager) cleanupExpiredShares() {
m.mutex.Lock()
defer m.mutex.Unlock()
Expand All @@ -423,7 +410,7 @@ func (m *manager) cleanupExpiredShares() {
var ps link.PublicShare
_ = utils.UnmarshalJSONToProtoV1([]byte(d.(string)), &ps)

if !notExpired(&ps) {
if publicshare.IsExpired(&ps) {
_ = m.revokeExpiredPublicShare(context.Background(), &ps, nil)
}
}
Expand Down Expand Up @@ -525,7 +512,7 @@ func (m *manager) GetPublicShareByToken(ctx context.Context, token string, auth
}

if local.Token == token {
if !notExpired(&local) {
if publicshare.IsExpired(&local) {
// TODO user is not needed at all in this API.
if err := m.revokeExpiredPublicShare(ctx, &local, nil); err != nil {
return nil, err
Expand Down
50 changes: 50 additions & 0 deletions pkg/publicshare/publicshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/pkg/utils"
)

// Manager manipulates public shares.
Expand Down Expand Up @@ -93,3 +94,52 @@ func ResourceIDFilter(id *provider.ResourceId) *link.ListPublicSharesRequest_Fil
},
}
}

// MatchesFilter tests if the share passes the filter.
func MatchesFilter(share *link.PublicShare, filter *link.ListPublicSharesRequest_Filter) bool {
switch filter.Type {
case link.ListPublicSharesRequest_Filter_TYPE_RESOURCE_ID:
return utils.ResourceIDEqual(share.ResourceId, filter.GetResourceId())
default:
return false
}
}

// MatchesAnyFilter checks if the share passes at least one of the given filters.
func MatchesAnyFilter(share *link.PublicShare, filters []*link.ListPublicSharesRequest_Filter) bool {
for _, f := range filters {
if MatchesFilter(share, f) {
return true
}
}
return false
}

// MatchesFilters checks if the share passes the given filters.
// 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 MatchesFilters(share *link.PublicShare, filters []*link.ListPublicSharesRequest_Filter) bool {
grouped := GroupFiltersByType(filters)
for _, f := range grouped {
if !MatchesAnyFilter(share, f) {
return false
}
}
return true
}

// GroupFiltersByType groups the given filters and returns a map using the filter type as the key.
func GroupFiltersByType(filters []*link.ListPublicSharesRequest_Filter) map[link.ListPublicSharesRequest_Filter_Type][]*link.ListPublicSharesRequest_Filter {
grouped := make(map[link.ListPublicSharesRequest_Filter_Type][]*link.ListPublicSharesRequest_Filter)
for _, f := range filters {
grouped[f.Type] = append(grouped[f.Type], f)
}
return grouped
}

// IsExpired tests whether a public share is expired
func IsExpired(s *link.PublicShare) bool {
expiration := time.Unix(int64(s.Expiration.GetSeconds()), int64(s.Expiration.GetNanos()))
return s.Expiration != nil && expiration.Before(time.Now())
}

0 comments on commit b5a4309

Please sign in to comment.