mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-08 13:19:58 -06:00
graph: Add support for "or" filter on /users
This add support for combining filters on the /users with a logical "or" operation. E.g. the filter: "filter=(memberOf/any(m:m/id eq 509a9dcd-bb37-4f4f-a01a-19dca27d9cfa) or memberOf/any(m:m/id eq 262982c1-2362-4afa-bfdf-8cbfef64a06e)" will return all users that are a member of either of the referenced group. Closes: #5667
This commit is contained in:
committed by
Ralf Haferkamp
parent
e63e466188
commit
db752dc5ac
@@ -50,6 +50,12 @@ func (g Graph) applyFilterLogical(ctx context.Context, req *godata.GoDataRequest
|
||||
return users, invalidFilterError()
|
||||
}
|
||||
return g.applyFilterLogicalAnd(ctx, req, root.Children[0], root.Children[1])
|
||||
case "or":
|
||||
// 'or' needs 2 operands
|
||||
if len(root.Children) != 2 {
|
||||
return users, invalidFilterError()
|
||||
}
|
||||
return g.applyFilterLogicalOr(ctx, req, root.Children[0], root.Children[1])
|
||||
}
|
||||
logger.Debug().Str("Token", root.Token.Value).Msg("unsupported logical filter")
|
||||
return users, unsupportedFilterError()
|
||||
@@ -109,6 +115,32 @@ func (g Graph) applyFilterLogicalAnd(ctx context.Context, req *godata.GoDataRequ
|
||||
return filteredUsers, nil
|
||||
}
|
||||
|
||||
func (g Graph) applyFilterLogicalOr(ctx context.Context, req *godata.GoDataRequest, operand1 *godata.ParseNode, operand2 *godata.ParseNode) (users []*libregraph.User, err error) {
|
||||
// logger := g.logger.SubloggerWithRequestID(ctx)
|
||||
var res1, res2 []*libregraph.User
|
||||
|
||||
res1, err = g.applyUserFilter(ctx, req, operand1)
|
||||
if err != nil {
|
||||
return []*libregraph.User{}, err
|
||||
}
|
||||
|
||||
res2, err = g.applyUserFilter(ctx, req, operand2)
|
||||
if err != nil {
|
||||
return []*libregraph.User{}, err
|
||||
}
|
||||
|
||||
// We now have two slices with results of the subfilters. Now turn one of them
|
||||
// into a map for efficiently getting the union of both slices
|
||||
userSet := userSliceToMap(res1)
|
||||
filteredUsers := make([]*libregraph.User, 0, len(res1)+len(res2))
|
||||
filteredUsers = append(filteredUsers, res1...)
|
||||
for _, user := range res2 {
|
||||
if _, found := userSet[user.GetId()]; !found {
|
||||
filteredUsers = append(filteredUsers, user)
|
||||
}
|
||||
}
|
||||
return filteredUsers, nil
|
||||
}
|
||||
func (g Graph) applyFilterLambda(ctx context.Context, req *godata.GoDataRequest, nodes []*godata.ParseNode) (users []*libregraph.User, err error) {
|
||||
logger := g.logger.SubloggerWithRequestID(ctx)
|
||||
if len(nodes) != 2 {
|
||||
|
||||
@@ -378,9 +378,12 @@ var _ = Describe("Users", func() {
|
||||
Entry("with memberOf lambda filter with UUID", "memberOf/any(n:n/id eq 25cb7bc0-3168-4a0c-adbe-396f478ad494)", http.StatusOK),
|
||||
Entry("with memberOf lambda filter with UUID string", "memberOf/any(n:n/id eq '25cb7bc0-3168-4a0c-adbe-396f478ad494')", http.StatusOK),
|
||||
Entry("with appRoleAssignments lambda filter with appRoleId", "appRoleAssignments/any(n:n/appRoleId eq 'some-appRole-ID')", http.StatusOK),
|
||||
Entry("with two memberOf lambda filters",
|
||||
Entry("with two memberOf lambda filters combined with and",
|
||||
"memberOf/any(n:n/id eq 25cb7bc0-3168-4a0c-adbe-396f478ad494) and memberOf/any(n:n/id eq 2713f1d5-6822-42bd-ad56-9f6c55a3a8fa)",
|
||||
http.StatusOK),
|
||||
Entry("with two memberOf lambda filters combined with or",
|
||||
"memberOf/any(n:n/id eq 25cb7bc0-3168-4a0c-adbe-396f478ad494) or memberOf/any(n:n/id eq 2713f1d5-6822-42bd-ad56-9f6c55a3a8fa)",
|
||||
http.StatusOK),
|
||||
Entry("with supported appRoleAssignments lambda filter property",
|
||||
"appRoleAssignments/any(n:n/appRoleId eq 'some-appRoleAssignment-ID') and memberOf/any(n:n/id eq 2713f1d5-6822-42bd-ad56-9f6c55a3a8fa)",
|
||||
http.StatusOK),
|
||||
|
||||
Reference in New Issue
Block a user