mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-23 05:59:28 -06:00
graph: Pass parsed odata request to the identity backend
In preparation for some more advanced queries pass the parse odata request
tVo the identity backend methods instead of the raw url.Values{}. This also
add some helpers for validating $expand and $search queries to reject
some unsupported queries.
Also remove support for `$select=memberOf` and `$select=drive|drives` queries
and stick to the technically correct `$expand=...`.
This commit is contained in:
committed by
Ralf Haferkamp
parent
25d2a2bc71
commit
26f7523ff8
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/CiscoM31/godata"
|
||||
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
|
||||
@@ -25,8 +26,8 @@ type Backend interface {
|
||||
DeleteUser(ctx context.Context, nameOrID string) error
|
||||
// UpdateUser applies changes to given user, identified by username or id
|
||||
UpdateUser(ctx context.Context, nameOrID string, user libregraph.User) (*libregraph.User, error)
|
||||
GetUser(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.User, error)
|
||||
GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error)
|
||||
GetUser(ctx context.Context, nameOrID string, oreq *godata.GoDataRequest) (*libregraph.User, error)
|
||||
GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.User, error)
|
||||
|
||||
// CreateGroup creates the supplied group in the identity backend.
|
||||
CreateGroup(ctx context.Context, group libregraph.Group) (*libregraph.Group, error)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/CiscoM31/godata"
|
||||
cs3group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
cs3user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
@@ -39,7 +40,8 @@ func (i *CS3) UpdateUser(ctx context.Context, nameOrID string, user libregraph.U
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (i *CS3) GetUser(ctx context.Context, userID string, queryParam url.Values) (*libregraph.User, error) {
|
||||
// GetUser implements the Backend Interface.
|
||||
func (i *CS3) GetUser(ctx context.Context, userID string, _ *godata.GoDataRequest) (*libregraph.User, error) {
|
||||
logger := i.Logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "cs3").Msg("GetUser")
|
||||
client, err := pool.GetGatewayServiceClient(i.Config.Address, i.Config.GetRevaOptions()...)
|
||||
@@ -67,7 +69,8 @@ func (i *CS3) GetUser(ctx context.Context, userID string, queryParam url.Values)
|
||||
return CreateUserModelFromCS3(res.User), nil
|
||||
}
|
||||
|
||||
func (i *CS3) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
|
||||
// GetUsers implements the Backend Interface.
|
||||
func (i *CS3) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.User, error) {
|
||||
logger := i.Logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "cs3").Msg("GetUsers")
|
||||
client, err := pool.GetGatewayServiceClient(i.Config.Address, i.Config.GetRevaOptions()...)
|
||||
@@ -76,9 +79,9 @@ func (i *CS3) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregrap
|
||||
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
||||
}
|
||||
|
||||
search := queryParam.Get("search")
|
||||
if search == "" {
|
||||
search = queryParam.Get("$search")
|
||||
search, err := GetSearchValues(oreq.Query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := client.FindUsers(ctx, &cs3user.FindUsersRequest{
|
||||
@@ -107,6 +110,7 @@ func (i *CS3) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregrap
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// GetGroups implements the Backend Interface.
|
||||
func (i *CS3) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregraph.Group, error) {
|
||||
logger := i.Logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "cs3").Msg("GetGroups")
|
||||
@@ -153,6 +157,7 @@ func (i *CS3) CreateGroup(ctx context.Context, group libregraph.Group) (*libregr
|
||||
return nil, errorcode.New(errorcode.NotSupported, "not implemented")
|
||||
}
|
||||
|
||||
// GetGroup implements the Backend Interface.
|
||||
func (i *CS3) GetGroup(ctx context.Context, groupID string, queryParam url.Values) (*libregraph.Group, error) {
|
||||
logger := i.Logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "cs3").Msg("GetGroup")
|
||||
|
||||
@@ -4,9 +4,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/CiscoM31/godata"
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/gofrs/uuid"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
@@ -369,20 +368,27 @@ func (i *LDAP) getLDAPUserByFilter(filter string) (*ldap.Entry, error) {
|
||||
return i.searchLDAPEntryByFilter(i.userBaseDN, attrs, filter)
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUser(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.User, error) {
|
||||
// GetUser implements the Backend Interface.
|
||||
func (i *LDAP) GetUser(ctx context.Context, nameOrID string, oreq *godata.GoDataRequest) (*libregraph.User, error) {
|
||||
logger := i.logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "ldap").Msg("GetUser")
|
||||
|
||||
e, err := i.getLDAPUserByNameOrID(nameOrID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := i.createUserModelFromLDAP(e)
|
||||
if u == nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
sel := strings.Split(queryParam.Get("$select"), ",")
|
||||
exp := strings.Split(queryParam.Get("$expand"), ",")
|
||||
if slices.Contains(sel, "memberOf") || slices.Contains(exp, "memberOf") {
|
||||
|
||||
exp, err := GetExpandValues(oreq.Query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if slices.Contains(exp, "memberOf") {
|
||||
userGroups, err := i.getGroupsForUser(e.DN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -392,14 +398,21 @@ func (i *LDAP) GetUser(ctx context.Context, nameOrID string, queryParam url.Valu
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
|
||||
// GetUsers implements the Backend Interface.
|
||||
func (i *LDAP) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.User, error) {
|
||||
logger := i.logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "ldap").Msg("GetUsers")
|
||||
|
||||
search := queryParam.Get("search")
|
||||
if search == "" {
|
||||
search = queryParam.Get("$search")
|
||||
search, err := GetSearchValues(oreq.Query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exp, err := GetExpandValues(oreq.Query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var userFilter string
|
||||
if search != "" {
|
||||
search = ldap.EscapeFilter(search)
|
||||
@@ -439,14 +452,12 @@ func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregra
|
||||
users := make([]*libregraph.User, 0, len(res.Entries))
|
||||
|
||||
for _, e := range res.Entries {
|
||||
sel := strings.Split(queryParam.Get("$select"), ",")
|
||||
exp := strings.Split(queryParam.Get("$expand"), ",")
|
||||
u := i.createUserModelFromLDAP(e)
|
||||
// Skip invalid LDAP users
|
||||
if u == nil {
|
||||
continue
|
||||
}
|
||||
if slices.Contains(sel, "memberOf") || slices.Contains(exp, "memberOf") {
|
||||
if slices.Contains(exp, "memberOf") {
|
||||
userGroups, err := i.getGroupsForUser(e.DN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/CiscoM31/godata"
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
@@ -172,23 +173,24 @@ func TestGetUser(t *testing.T) {
|
||||
nil, ldap.NewError(ldap.LDAPResultSizeLimitExceeded, errors.New("mock")))
|
||||
b, _ := getMockedBackend(lm, lconfig, &logger)
|
||||
|
||||
queryParamExpand := url.Values{
|
||||
"$expand": []string{"memberOf"},
|
||||
odataReqDefault, err := godata.ParseRequest(context.Background(), "",
|
||||
url.Values{})
|
||||
if err != nil {
|
||||
t.Errorf("Expected success got '%s'", err.Error())
|
||||
}
|
||||
queryParamSelect := url.Values{
|
||||
"$select": []string{"memberOf"},
|
||||
|
||||
odataReqExpand, err := godata.ParseRequest(context.Background(), "",
|
||||
url.Values{"$expand": []string{"memberOf"}})
|
||||
if err != nil {
|
||||
t.Errorf("Expected success got '%s'", err.Error())
|
||||
}
|
||||
_, err := b.GetUser(context.Background(), "fred", nil)
|
||||
|
||||
_, err = b.GetUser(context.Background(), "fred", odataReqDefault)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
|
||||
_, err = b.GetUser(context.Background(), "fred", queryParamExpand)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
|
||||
_, err = b.GetUser(context.Background(), "fred", queryParamSelect)
|
||||
_, err = b.GetUser(context.Background(), "fred", odataReqExpand)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -199,17 +201,12 @@ func TestGetUser(t *testing.T) {
|
||||
Return(
|
||||
&ldap.SearchResult{}, nil)
|
||||
b, _ = getMockedBackend(lm, lconfig, &logger)
|
||||
_, err = b.GetUser(context.Background(), "fred", nil)
|
||||
_, err = b.GetUser(context.Background(), "fred", odataReqDefault)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
|
||||
_, err = b.GetUser(context.Background(), "fred", queryParamExpand)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
|
||||
_, err = b.GetUser(context.Background(), "fred", queryParamSelect)
|
||||
_, err = b.GetUser(context.Background(), "fred", odataReqExpand)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -224,21 +221,14 @@ func TestGetUser(t *testing.T) {
|
||||
nil)
|
||||
|
||||
b, _ = getMockedBackend(lm, lconfig, &logger)
|
||||
u, err := b.GetUser(context.Background(), "user", nil)
|
||||
u, err := b.GetUser(context.Background(), "user", odataReqDefault)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetUser to succeed. Got %s", err.Error())
|
||||
} else if *u.Id != userEntry.GetEqualFoldAttributeValue(b.userAttributeMap.id) {
|
||||
t.Errorf("Expected GetUser to return a valid user")
|
||||
}
|
||||
|
||||
u, err = b.GetUser(context.Background(), "user", queryParamExpand)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetUser to succeed. Got %s", err.Error())
|
||||
} else if *u.Id != userEntry.GetEqualFoldAttributeValue(b.userAttributeMap.id) {
|
||||
t.Errorf("Expected GetUser to return a valid user")
|
||||
}
|
||||
|
||||
u, err = b.GetUser(context.Background(), "user", queryParamSelect)
|
||||
u, err = b.GetUser(context.Background(), "user", odataReqExpand)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetUser to succeed. Got %s", err.Error())
|
||||
} else if *u.Id != userEntry.GetEqualFoldAttributeValue(b.userAttributeMap.id) {
|
||||
@@ -266,8 +256,14 @@ func TestGetUsers(t *testing.T) {
|
||||
lm := &mocks.Client{}
|
||||
lm.On("Search", mock.Anything).Return(nil, ldap.NewError(ldap.LDAPResultOperationsError, errors.New("mock")))
|
||||
|
||||
odataReqDefault, err := godata.ParseRequest(context.Background(), "",
|
||||
url.Values{})
|
||||
if err != nil {
|
||||
t.Errorf("Expected success got '%s'", err.Error())
|
||||
}
|
||||
|
||||
b, _ := getMockedBackend(lm, lconfig, &logger)
|
||||
_, err := b.GetUsers(context.Background(), url.Values{})
|
||||
_, err = b.GetUsers(context.Background(), odataReqDefault)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -275,7 +271,7 @@ func TestGetUsers(t *testing.T) {
|
||||
lm = &mocks.Client{}
|
||||
lm.On("Search", mock.Anything).Return(&ldap.SearchResult{}, nil)
|
||||
b, _ = getMockedBackend(lm, lconfig, &logger)
|
||||
g, err := b.GetUsers(context.Background(), url.Values{})
|
||||
g, err := b.GetUsers(context.Background(), odataReqDefault)
|
||||
if err != nil {
|
||||
t.Errorf("Expected success, got '%s'", err.Error())
|
||||
} else if g == nil || len(g) != 0 {
|
||||
|
||||
@@ -5,6 +5,8 @@ package mocks
|
||||
import (
|
||||
context "context"
|
||||
|
||||
godata "github.com/CiscoM31/godata"
|
||||
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
@@ -174,13 +176,13 @@ func (_m *Backend) GetGroups(ctx context.Context, queryParam url.Values) ([]*lib
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUser provides a mock function with given fields: ctx, nameOrID, queryParam
|
||||
func (_m *Backend) GetUser(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.User, error) {
|
||||
ret := _m.Called(ctx, nameOrID, queryParam)
|
||||
// GetUser provides a mock function with given fields: ctx, nameOrID, oreq
|
||||
func (_m *Backend) GetUser(ctx context.Context, nameOrID string, oreq *godata.GoDataRequest) (*libregraph.User, error) {
|
||||
ret := _m.Called(ctx, nameOrID, oreq)
|
||||
|
||||
var r0 *libregraph.User
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, url.Values) *libregraph.User); ok {
|
||||
r0 = rf(ctx, nameOrID, queryParam)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *godata.GoDataRequest) *libregraph.User); ok {
|
||||
r0 = rf(ctx, nameOrID, oreq)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*libregraph.User)
|
||||
@@ -188,8 +190,8 @@ func (_m *Backend) GetUser(ctx context.Context, nameOrID string, queryParam url.
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, url.Values) error); ok {
|
||||
r1 = rf(ctx, nameOrID, queryParam)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, *godata.GoDataRequest) error); ok {
|
||||
r1 = rf(ctx, nameOrID, oreq)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -197,13 +199,13 @@ func (_m *Backend) GetUser(ctx context.Context, nameOrID string, queryParam url.
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUsers provides a mock function with given fields: ctx, queryParam
|
||||
func (_m *Backend) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
|
||||
ret := _m.Called(ctx, queryParam)
|
||||
// GetUsers provides a mock function with given fields: ctx, oreq
|
||||
func (_m *Backend) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.User, error) {
|
||||
ret := _m.Called(ctx, oreq)
|
||||
|
||||
var r0 []*libregraph.User
|
||||
if rf, ok := ret.Get(0).(func(context.Context, url.Values) []*libregraph.User); ok {
|
||||
r0 = rf(ctx, queryParam)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *godata.GoDataRequest) []*libregraph.User); ok {
|
||||
r0 = rf(ctx, oreq)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*libregraph.User)
|
||||
@@ -211,8 +213,8 @@ func (_m *Backend) GetUsers(ctx context.Context, queryParam url.Values) ([]*libr
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, url.Values) error); ok {
|
||||
r1 = rf(ctx, queryParam)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *godata.GoDataRequest) error); ok {
|
||||
r1 = rf(ctx, oreq)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
41
services/graph/pkg/identity/odata.go
Normal file
41
services/graph/pkg/identity/odata.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package identity
|
||||
|
||||
import "github.com/CiscoM31/godata"
|
||||
|
||||
// GetExpandValues extracts the values of the $expand query parameter and
|
||||
// returns them in a []string, rejects any $expand value that consists of more
|
||||
// than just a single path segment
|
||||
func GetExpandValues(req *godata.GoDataQuery) ([]string, error) {
|
||||
if req == nil || req.Expand == nil {
|
||||
return []string{}, nil
|
||||
}
|
||||
expand := make([]string, 0, len(req.Expand.ExpandItems))
|
||||
for _, item := range req.Expand.ExpandItems {
|
||||
if item.Filter != nil || item.At != nil || item.Search != nil ||
|
||||
item.OrderBy != nil || item.Skip != nil || item.Top != nil ||
|
||||
item.Select != nil || item.Compute != nil || item.Expand != nil ||
|
||||
item.Levels != 0 {
|
||||
return []string{}, godata.NotImplementedError("options for $expand not supported")
|
||||
}
|
||||
if len(item.Path) > 1 {
|
||||
return []string{}, godata.NotImplementedError("multiple segments in $expand not supported")
|
||||
}
|
||||
expand = append(expand, item.Path[0].Value)
|
||||
}
|
||||
return expand, nil
|
||||
}
|
||||
|
||||
// GetSearchValues extracts the value of the $search query parameter and returns
|
||||
// it as a string. Rejects any search query that is more than just a simple string
|
||||
func GetSearchValues(req *godata.GoDataQuery) (string, error) {
|
||||
if req == nil || req.Search == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Only allow simple search queries for now
|
||||
if len(req.Search.Tree.Children) != 0 {
|
||||
return "", godata.NotImplementedError("complex search queries are not supported")
|
||||
}
|
||||
|
||||
return req.Search.Tree.Token.Value, nil
|
||||
}
|
||||
@@ -322,6 +322,7 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, newDrive)
|
||||
}
|
||||
|
||||
// UpdateDrive updates the properties of a storage drive (space).
|
||||
func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||
logger.Info().Msg("calling update drive")
|
||||
@@ -594,7 +595,7 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
|
||||
} else {
|
||||
var user libregraph.User
|
||||
if item := g.usersCache.Get(id); item == nil {
|
||||
if requestedUser, err := g.identityBackend.GetUser(ctx, id, url.Values{}); err == nil {
|
||||
if requestedUser, err := g.identityBackend.GetUser(ctx, id, &godata.GoDataRequest{}); err == nil {
|
||||
user = *requestedUser
|
||||
g.usersCache.Set(id, user, ttlcache.DefaultTTL)
|
||||
}
|
||||
@@ -881,6 +882,7 @@ func listStorageSpacesTypeFilter(spaceType string) *storageprovider.ListStorageS
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteDrive deletes a storage drive (space).
|
||||
func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
|
||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||
logger.Info().Msg("calling delete drive")
|
||||
|
||||
@@ -32,6 +32,14 @@ import (
|
||||
func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
|
||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||
logger.Info().Msg("calling get user in /me")
|
||||
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
|
||||
|
||||
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: query error")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
u, ok := revactx.ContextGetUser(r.Context())
|
||||
if !ok {
|
||||
@@ -39,7 +47,14 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "user not in context")
|
||||
return
|
||||
}
|
||||
exp := strings.Split(r.URL.Query().Get("$expand"), ",")
|
||||
|
||||
exp, err := identity.GetExpandValues(odataReq.Query)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: $expand error")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var me *libregraph.User
|
||||
// We can just return the user from context unless we need to expand the group memberships
|
||||
if !slices.Contains(exp, "memberOf") {
|
||||
@@ -47,7 +62,7 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
var err error
|
||||
logger.Debug().Msg("calling get user on backend")
|
||||
me, err = g.identityBackend.GetUser(r.Context(), u.GetId().GetOpaqueId(), r.URL.Query())
|
||||
me, err = g.identityBackend.GetUser(r.Context(), u.GetId().GetOpaqueId(), odataReq)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("user", u).Msg("could not get user from backend")
|
||||
var errcode errorcode.Error
|
||||
@@ -111,7 +126,7 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
logger.Debug().Interface("query", r.URL.Query()).Msg("calling get users on backend")
|
||||
users, err := g.identityBackend.GetUsers(r.Context(), r.URL.Query())
|
||||
users, err := g.identityBackend.GetUsers(r.Context(), odataReq)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users from backend")
|
||||
var errcode errorcode.Error
|
||||
@@ -123,8 +138,12 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// expand appRoleAssignments if requested
|
||||
exp := strings.Split(r.URL.Query().Get("$expand"), ",")
|
||||
exp, err := identity.GetExpandValues(odataReq.Query)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: $expand error")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
expandAppRoleAssignments := slices.Contains(exp, "appRoleAssignments")
|
||||
expandMemberOf := slices.Contains(exp, "memberOf")
|
||||
for _, u := range users {
|
||||
@@ -240,6 +259,9 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
|
||||
func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||
logger.Info().Msg("calling get user")
|
||||
|
||||
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
|
||||
|
||||
userID := chi.URLParam(r, "userID")
|
||||
userID, err := url.PathUnescape(userID)
|
||||
if err != nil {
|
||||
@@ -254,8 +276,22 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: query error")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
exp, err := identity.GetExpandValues(odataReq.Query)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: $expand error")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug().Str("id", userID).Msg("calling get user from backend")
|
||||
user, err := g.identityBackend.GetUser(r.Context(), userID, r.URL.Query())
|
||||
user, err := g.identityBackend.GetUser(r.Context(), userID, odataReq)
|
||||
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Msg("could not get user: error fetching user from backend")
|
||||
@@ -267,10 +303,9 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
return
|
||||
}
|
||||
sel := strings.Split(r.URL.Query().Get("$select"), ",")
|
||||
exp := strings.Split(r.URL.Query().Get("$expand"), ",")
|
||||
listDrives := slices.Contains(sel, "drives") || slices.Contains(exp, "drives")
|
||||
listDrive := slices.Contains(sel, "drive") || slices.Contains(exp, "drive")
|
||||
|
||||
listDrives := slices.Contains(exp, "drives")
|
||||
listDrive := slices.Contains(exp, "drive")
|
||||
|
||||
// do we need to list all or only the personal drive
|
||||
filters := []*storageprovider.ListStorageSpacesRequest_Filter{}
|
||||
@@ -368,6 +403,7 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||
logger.Info().Msg("calling delete user")
|
||||
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
|
||||
userID := chi.URLParam(r, "userID")
|
||||
userID, err := url.PathUnescape(userID)
|
||||
if err != nil {
|
||||
@@ -381,8 +417,16 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
|
||||
return
|
||||
}
|
||||
|
||||
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: query error")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug().Str("id", userID).Msg("calling get user on user backend")
|
||||
user, err := g.identityBackend.GetUser(r.Context(), userID, r.URL.Query())
|
||||
user, err := g.identityBackend.GetUser(r.Context(), userID, odataReq)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Str("userID", userID).Msg("failed to get user from backend")
|
||||
var errcode errorcode.Error
|
||||
|
||||
Reference in New Issue
Block a user