graph: Initial support for $filter in /users (#5533)

This adds some initial support for using $filter (as defined in the
odata spec) on the /users endpoint. Currently the following filters are
supported:

A single filter on `id` property of the `memberOf` relation of users.
To list all users that are members of a specific group:

```
curl 'https://localhost:9200/graph/v1.0/users?$filter=memberOf/any(m:m/id eq '262982c1-2362-4afa-bfdf-8cbfef64a06e')
```

A logical AND filteri on the `id` property of the `memberOf` relation of users.

`$filter=memberOf/any(m:m/id eq 262982c1-2362-4afa-bfdf-8cbfef64a06e) and memberOf/any(m:m/id eq 6040aa17-9c64-4fef-9bd0-77234d71bad0)`

This will cause at least two queries on the identity backend. The `and`
operation is performed locally.

Closes: #5487
This commit is contained in:
Ralf Haferkamp
2023-02-14 10:32:32 +01:00
committed by GitHub
parent 93c2844585
commit b7ec7c92c4
8 changed files with 241 additions and 14 deletions
+15 -1
View File
@@ -6,6 +6,7 @@ import (
"net/url"
"strings"
"github.com/CiscoM31/godata"
"github.com/go-ldap/ldap/v3"
"github.com/gofrs/uuid"
ldapdn "github.com/libregraph/idm/pkg/ldapdn"
@@ -134,9 +135,15 @@ func (i *LDAP) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregr
}
// GetGroupMembers implements the Backend Interface for the LDAP Backend
func (i *LDAP) GetGroupMembers(ctx context.Context, groupID string) ([]*libregraph.User, error) {
func (i *LDAP) GetGroupMembers(ctx context.Context, groupID string, req *godata.GoDataRequest) ([]*libregraph.User, error) {
logger := i.logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "ldap").Msg("GetGroupMembers")
exp, err := GetExpandValues(req.Query)
if err != nil {
return nil, err
}
e, err := i.getLDAPGroupByNameOrID(groupID, true)
if err != nil {
return nil, err
@@ -149,6 +156,13 @@ func (i *LDAP) GetGroupMembers(ctx context.Context, groupID string) ([]*libregra
}
for _, member := range memberEntries {
if u := i.createUserModelFromLDAP(member); u != nil {
if slices.Contains(exp, "memberOf") {
userGroups, err := i.getGroupsForUser(member.DN)
if err != nil {
return nil, err
}
u.MemberOf = i.groupsFromLDAPEntries(userGroups)
}
result = append(result, u)
}
}