add memberOf slice to /user/{id} & members slice to /groups/{id} endpoint
Signed-off-by: Christian Richter <crichter@owncloud.com>
This commit is contained in:
@@ -15,14 +15,14 @@ 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) (*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)
|
||||
|
||||
// CreateGroup creates the supplied group in the identity backend.
|
||||
CreateGroup(ctx context.Context, group libregraph.Group) (*libregraph.Group, error)
|
||||
// DeleteGroup deletes a given group, identified by id
|
||||
DeleteGroup(ctx context.Context, id string) error
|
||||
GetGroup(ctx context.Context, nameOrID string) (*libregraph.Group, error)
|
||||
GetGroup(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.Group, error)
|
||||
GetGroups(ctx context.Context, queryParam url.Values) ([]*libregraph.Group, error)
|
||||
GetGroupMembers(ctx context.Context, id string) ([]*libregraph.User, error)
|
||||
// AddMembersToGroup adds new members (reference by a slice of IDs) to supplied group in the identity backend.
|
||||
|
||||
@@ -39,7 +39,7 @@ func (i *CS3) UpdateUser(ctx context.Context, nameOrID string, user libregraph.U
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (i *CS3) GetUser(ctx context.Context, userID string) (*libregraph.User, error) {
|
||||
func (i *CS3) GetUser(ctx context.Context, userID string, queryParam url.Values) (*libregraph.User, error) {
|
||||
client, err := pool.GetGatewayServiceClient(i.Config.Address)
|
||||
if err != nil {
|
||||
i.Logger.Error().Err(err).Msg("could not get client")
|
||||
@@ -147,7 +147,7 @@ func (i *CS3) CreateGroup(ctx context.Context, group libregraph.Group) (*libregr
|
||||
return nil, errorcode.New(errorcode.NotSupported, "not implemented")
|
||||
}
|
||||
|
||||
func (i *CS3) GetGroup(ctx context.Context, groupID string) (*libregraph.Group, error) {
|
||||
func (i *CS3) GetGroup(ctx context.Context, groupID string, queryParam url.Values) (*libregraph.Group, error) {
|
||||
client, err := pool.GetGatewayServiceClient(i.Config.Address)
|
||||
if err != nil {
|
||||
i.Logger.Error().Err(err).Msg("could not get client")
|
||||
|
||||
@@ -355,13 +355,32 @@ func (i *LDAP) getLDAPUserByFilter(filter string) (*ldap.Entry, error) {
|
||||
return res.Entries[0], nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUser(ctx context.Context, nameOrID string) (*libregraph.User, error) {
|
||||
func (i *LDAP) GetUser(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.User, error) {
|
||||
i.logger.Debug().Str("backend", "ldap").Msg("GetUser")
|
||||
e, err := i.getLDAPUserByNameOrID(nameOrID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.createUserModelFromLDAP(e), nil
|
||||
userGroups, err := i.getGroupsForUser(e.DN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sel := strings.Split(queryParam.Get("$select"), ",")
|
||||
exp := strings.Split(queryParam.Get("$expand"), ",")
|
||||
u := i.createUserModelFromLDAP(e)
|
||||
if slices.Contains(sel, "memberOf") || slices.Contains(exp, "memberOf") {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(userGroups) > 0 {
|
||||
groups := make([]libregraph.Group, 0, len(userGroups))
|
||||
for _, g := range userGroups {
|
||||
groups = append(groups, *i.createGroupModelFromLDAP(g))
|
||||
}
|
||||
u.MemberOf = groups
|
||||
}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
|
||||
@@ -406,11 +425,7 @@ func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregra
|
||||
exp := strings.Split(queryParam.Get("$expand"), ",")
|
||||
u := i.createUserModelFromLDAP(e)
|
||||
if slices.Contains(sel, "memberOf") || slices.Contains(exp, "memberOf") {
|
||||
groupFilter := fmt.Sprintf(
|
||||
"(%s=%s)",
|
||||
i.groupAttributeMap.member, e.DN,
|
||||
)
|
||||
userGroups, err := i.getLDAPGroupsByFilter(groupFilter, false, false)
|
||||
userGroups, err := i.getGroupsForUser(e.DN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -431,13 +446,41 @@ func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregra
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetGroup(ctx context.Context, nameOrID string) (*libregraph.Group, error) {
|
||||
func (i *LDAP) getGroupsForUser(dn string) ([]*ldap.Entry, error) {
|
||||
groupFilter := fmt.Sprintf(
|
||||
"(%s=%s)",
|
||||
i.groupAttributeMap.member, dn,
|
||||
)
|
||||
userGroups, err := i.getLDAPGroupsByFilter(groupFilter, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userGroups, nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetGroup(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.Group, error) {
|
||||
i.logger.Debug().Str("backend", "ldap").Msg("GetGroup")
|
||||
e, err := i.getLDAPGroupByNameOrID(nameOrID, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.createGroupModelFromLDAP(e), nil
|
||||
sel := strings.Split(queryParam.Get("$select"), ",")
|
||||
exp := strings.Split(queryParam.Get("$expand"), ",")
|
||||
g := i.createGroupModelFromLDAP(e)
|
||||
if slices.Contains(sel, "members") || slices.Contains(exp, "members") {
|
||||
members, err := i.GetGroupMembers(ctx, *g.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(members) > 1 {
|
||||
m := make([]libregraph.User, 0, len(members))
|
||||
for _, u := range members {
|
||||
m = append(m, *u)
|
||||
}
|
||||
g.Members = m
|
||||
}
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (i *LDAP) getLDAPGroupByID(id string, requestMembers bool) (*ldap.Entry, error) {
|
||||
@@ -581,7 +624,6 @@ func (i *LDAP) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregr
|
||||
exp := strings.Split(queryParam.Get("$expand"), ",")
|
||||
g := i.createGroupModelFromLDAP(e)
|
||||
if slices.Contains(sel, "members") || slices.Contains(exp, "members") {
|
||||
|
||||
members, err := i.GetGroupMembers(ctx, *g.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -125,7 +125,24 @@ func TestGetUser(t *testing.T) {
|
||||
return nil, ldap.NewError(ldap.LDAPResultSizeLimitExceeded, errors.New("mock"))
|
||||
}
|
||||
b, _ := getMockedBackend(&sf, lconfig, &logger)
|
||||
_, err := b.GetUser(context.Background(), "fred")
|
||||
|
||||
queryParamExpand := url.Values{
|
||||
"$expand": []string{"memberOf"},
|
||||
}
|
||||
queryParamSelect := url.Values{
|
||||
"$select": []string{"memberOf"},
|
||||
}
|
||||
_, err := b.GetUser(context.Background(), "fred", nil)
|
||||
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)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -135,7 +152,17 @@ func TestGetUser(t *testing.T) {
|
||||
return &ldap.SearchResult{}, nil
|
||||
}
|
||||
b, _ = getMockedBackend(&sf, lconfig, &logger)
|
||||
_, err = b.GetUser(context.Background(), "fred")
|
||||
_, err = b.GetUser(context.Background(), "fred", nil)
|
||||
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)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -147,7 +174,21 @@ func TestGetUser(t *testing.T) {
|
||||
}, nil
|
||||
}
|
||||
b, _ = getMockedBackend(&sf, lconfig, &logger)
|
||||
u, err := b.GetUser(context.Background(), "user")
|
||||
u, err := b.GetUser(context.Background(), "user", nil)
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetUser to succeed. Got %s", err.Error())
|
||||
} else if *u.Id != userEntry.GetEqualFoldAttributeValue(b.userAttributeMap.id) {
|
||||
@@ -182,8 +223,22 @@ func TestGetGroup(t *testing.T) {
|
||||
var sf searchFunc = func(*ldap.SearchRequest) (*ldap.SearchResult, error) {
|
||||
return nil, ldap.NewError(ldap.LDAPResultSizeLimitExceeded, errors.New("mock"))
|
||||
}
|
||||
queryParamExpand := url.Values{
|
||||
"$expand": []string{"memberOf"},
|
||||
}
|
||||
queryParamSelect := url.Values{
|
||||
"$select": []string{"memberOf"},
|
||||
}
|
||||
b, _ := getMockedBackend(&sf, lconfig, &logger)
|
||||
_, err := b.GetGroup(context.Background(), "group")
|
||||
_, err := b.GetGroup(context.Background(), "group", nil)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
_, err = b.GetGroup(context.Background(), "group", queryParamExpand)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
_, err = b.GetGroup(context.Background(), "group", queryParamSelect)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -193,7 +248,15 @@ func TestGetGroup(t *testing.T) {
|
||||
return &ldap.SearchResult{}, nil
|
||||
}
|
||||
b, _ = getMockedBackend(&sf, lconfig, &logger)
|
||||
_, err = b.GetGroup(context.Background(), "group")
|
||||
_, err = b.GetGroup(context.Background(), "group", nil)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
_, err = b.GetGroup(context.Background(), "group", queryParamExpand)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
_, err = b.GetGroup(context.Background(), "group", queryParamSelect)
|
||||
if err == nil || err.Error() != "itemNotFound" {
|
||||
t.Errorf("Expected 'itemNotFound' got '%s'", err.Error())
|
||||
}
|
||||
@@ -205,7 +268,19 @@ func TestGetGroup(t *testing.T) {
|
||||
}, nil
|
||||
}
|
||||
b, _ = getMockedBackend(&sf, lconfig, &logger)
|
||||
g, err := b.GetGroup(context.Background(), "group")
|
||||
g, err := b.GetGroup(context.Background(), "group", nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetGroup to succeed. Got %s", err.Error())
|
||||
} else if *g.Id != groupEntry.GetEqualFoldAttributeValue(b.groupAttributeMap.id) {
|
||||
t.Errorf("Expected GetGroup to return a valid group")
|
||||
}
|
||||
g, err = b.GetGroup(context.Background(), "group", queryParamExpand)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetGroup to succeed. Got %s", err.Error())
|
||||
} else if *g.Id != groupEntry.GetEqualFoldAttributeValue(b.groupAttributeMap.id) {
|
||||
t.Errorf("Expected GetGroup to return a valid group")
|
||||
}
|
||||
g, err = b.GetGroup(context.Background(), "group", queryParamSelect)
|
||||
if err != nil {
|
||||
t.Errorf("Expected GetGroup to succeed. Got %s", err.Error())
|
||||
} else if *g.Id != groupEntry.GetEqualFoldAttributeValue(b.groupAttributeMap.id) {
|
||||
|
||||
@@ -162,7 +162,7 @@ func (g Graph) GetGroup(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
group, err := g.identityBackend.GetGroup(r.Context(), groupID)
|
||||
group, err := g.identityBackend.GetGroup(r.Context(), groupID, r.URL.Query())
|
||||
if err != nil {
|
||||
var errcode errorcode.Error
|
||||
if errors.As(err, &errcode) {
|
||||
|
||||
@@ -159,7 +159,7 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := g.identityBackend.GetUser(r.Context(), userID)
|
||||
user, err := g.identityBackend.GetUser(r.Context(), userID, r.URL.Query())
|
||||
|
||||
if err != nil {
|
||||
var errcode errorcode.Error
|
||||
|
||||
Reference in New Issue
Block a user