Skip to content

Commit

Permalink
Add logic for finding groups to user provider service (#1239)
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 authored Oct 22, 2020
1 parent cdaa04b commit 9379fa0
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 6 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/find-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Add logic for finding groups to user provider service

To create shares with user groups, the functionality for searching for these
based on a pattern is needed. This PR adds that.

https://github.com/cs3org/reva/pull/1239
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/cheggaaa/pb v1.0.29
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e
github.com/cs3org/go-cs3apis v0.0.0-20200929101248-821df597ec8d
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/eventials/go-tus v0.0.0-20200718001131-45c7ec8f5d59
github.com/go-ldap/ldap/v3 v3.2.4
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJff
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
github.com/cs3org/go-cs3apis v0.0.0-20200929101248-821df597ec8d h1:YDnGz3eTIYQDXzJd/zefEsl0qbz/P63e8KWjSjYlb5Q=
github.com/cs3org/go-cs3apis v0.0.0-20200929101248-821df597ec8d/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
22 changes: 19 additions & 3 deletions internal/grpc/services/gateway/userprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,23 @@ func (s *svc) FindUsers(ctx context.Context, req *user.FindUsersRequest) (*user.

res, err := c.FindUsers(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling GetUser")
return nil, errors.Wrap(err, "gateway: error calling FindUsers")
}

return res, nil
}

func (s *svc) FindGroups(ctx context.Context, req *user.FindGroupsRequest) (*user.FindGroupsResponse, error) {
c, err := pool.GetUserProviderServiceClient(s.c.UserProviderEndpoint)
if err != nil {
return &user.FindGroupsResponse{
Status: status.NewInternal(ctx, err, "error getting auth client"),
}, nil
}

res, err := c.FindGroups(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling FindGroups")
}

return res, nil
Expand All @@ -85,7 +101,7 @@ func (s *svc) GetUserGroups(ctx context.Context, req *user.GetUserGroupsRequest)

res, err := c.GetUserGroups(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling GetUser")
return nil, errors.Wrap(err, "gateway: error calling GetUserGroups")
}

return res, nil
Expand All @@ -101,7 +117,7 @@ func (s *svc) IsInGroup(ctx context.Context, req *user.IsInGroupRequest) (*user.

res, err := c.IsInGroup(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling GetUser")
return nil, errors.Wrap(err, "gateway: error calling IsInGroup")
}

return res, nil
Expand Down
17 changes: 17 additions & 0 deletions internal/grpc/services/userprovider/userprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,23 @@ func (s *service) FindUsers(ctx context.Context, req *userpb.FindUsersRequest) (
return res, nil
}

func (s *service) FindGroups(ctx context.Context, req *userpb.FindGroupsRequest) (*userpb.FindGroupsResponse, error) {
groups, err := s.usermgr.FindGroups(ctx, req.Filter)
if err != nil {
err = errors.Wrap(err, "userprovidersvc: error finding groups")
res := &userpb.FindGroupsResponse{
Status: status.NewInternal(ctx, err, "error finding groups"),
}
return res, nil
}

res := &userpb.FindGroupsResponse{
Status: status.NewOK(ctx),
Groups: groups,
}
return res, nil
}

func (s *service) GetUserGroups(ctx context.Context, req *userpb.GetUserGroupsRequest) (*userpb.GetUserGroupsResponse, error) {
groups, err := s.usermgr.GetUserGroups(ctx, req.UserId)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion internal/http/services/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ func (s *svc) Close() error {

// Prefix returns the main endpoint of this service.
func (s *svc) Prefix() string {
return ""
// We use a dummy endpoint as the service is not expected to be exposed
// directly to the user, but just start a background process.
return "register_metrics"
}

// Unprotected returns all endpoints that can be queried without prior authorization.
Expand Down
17 changes: 17 additions & 0 deletions pkg/user/manager/demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,23 @@ func (m *manager) FindUsers(ctx context.Context, query string) ([]*userpb.User,
return users, nil
}

func (m *manager) FindGroups(ctx context.Context, query string) ([]string, error) {
groupSet := make(map[string]bool)
for _, u := range m.catalog {
for _, g := range u.Groups {
if strings.Contains(g, query) {
groupSet[g] = true
}
}
}

groups := []string{}
for k := range groupSet {
groups = append(groups, k)
}
return groups, nil
}

func (m *manager) GetUserGroups(ctx context.Context, uid *userpb.UserId) ([]string, error) {
user, err := m.GetUser(ctx, uid)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions pkg/user/manager/demo/demo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ func TestUserManager(t *testing.T) {
t.Fatalf("user not in group: expected=%v got=%v", []*userpb.User{}, resUsers)
}

// test FindGroups
resFindGroups, _ := manager.FindGroups(ctx, "violin")
if len(resFindGroups) != 1 {
t.Fatalf("too many groups found: expected=%d got=%+v", 1, resFindGroups)
}
if resFindGroups[0] != "violin-haters" {
t.Fatalf("group differs: expected=%v got=%v", "violin-haters", resFindGroups[0])
}

// positive test IsInGroup
resInGroup, _ := manager.IsInGroup(ctx, uidEinstein, "physics-lovers")
if !resInGroup {
Expand Down
17 changes: 17 additions & 0 deletions pkg/user/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@ func (m *manager) FindUsers(ctx context.Context, query string) ([]*userpb.User,
return users, nil
}

func (m *manager) FindGroups(ctx context.Context, query string) ([]string, error) {
groupSet := make(map[string]bool)
for _, u := range m.users {
for _, g := range u.Groups {
if strings.Contains(g, query) {
groupSet[g] = true
}
}
}

groups := []string{}
for k := range groupSet {
groups = append(groups, k)
}
return groups, nil
}

func (m *manager) GetUserGroups(ctx context.Context, uid *userpb.UserId) ([]string, error) {
user, err := m.GetUser(ctx, uid)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions pkg/user/manager/json/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,15 @@ func TestUserManager(t *testing.T) {
t.Fatalf("user differ: expected=%v got=%v", "einstein", resUser[0].Username)
}

// test FindGroups
resFindGroups, _ := manager.FindGroups(ctx, "violin")
if len(resFindGroups) != 1 {
t.Fatalf("too many groups found: expected=%d got=%+v", 1, resFindGroups)
}
if resFindGroups[0] != "violin-haters" {
t.Fatalf("group differs: expected=%v got=%v", "violin-haters", resFindGroups[0])
}

// positive test IsInGroup
resInGroup, _ := manager.IsInGroup(ctx, uidEinstein, "physics-lovers")
if !resInGroup {
Expand Down
4 changes: 4 additions & 0 deletions pkg/user/manager/ldap/ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ func (m *manager) FindUsers(ctx context.Context, query string) ([]*userpb.User,
return users, nil
}

func (m *manager) FindGroups(ctx context.Context, query string) ([]string, error) {
return nil, errtypes.NotSupported("ldap: FindGroups is not supported")
}

func (m *manager) GetUserGroups(ctx context.Context, uid *userpb.UserId) ([]string, error) {
l, err := ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", m.c.Hostname, m.c.Port), &tls.Config{InsecureSkipVerify: true})
if err != nil {
Expand Down
26 changes: 25 additions & 1 deletion pkg/user/manager/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,14 +420,38 @@ func (m *manager) FindUsers(ctx context.Context, query string) ([]*userpb.User,
}
}

userSlice := make([]*userpb.User, len(users))
userSlice := []*userpb.User{}
for _, v := range users {
userSlice = append(userSlice, v)
}

return userSlice, nil
}

func (m *manager) FindGroups(ctx context.Context, query string) ([]string, error) {
url := fmt.Sprintf("%s/Group?filter=groupIdentifier:contains:%s", m.conf.APIBaseURL, query)
responseData, err := m.sendAPIRequest(ctx, url)
if err != nil {
return nil, err
}

groupSet := make(map[string]bool)
for _, g := range responseData {
group, ok := g.(map[string]interface{})
if !ok {
return nil, errors.New("rest: error in type assertion")
}
groupSet[group["groupIdentifier"].(string)] = true
}

groups := []string{}
for k := range groupSet {
groups = append(groups, k)
}

return groups, nil
}

func (m *manager) GetUserGroups(ctx context.Context, uid *userpb.UserId) ([]string, error) {

groups, err := m.fetchCachedUserGroups(uid)
Expand Down
1 change: 1 addition & 0 deletions pkg/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ type Manager interface {
GetUserGroups(ctx context.Context, uid *userpb.UserId) ([]string, error)
IsInGroup(ctx context.Context, uid *userpb.UserId, group string) (bool, error)
FindUsers(ctx context.Context, query string) ([]*userpb.User, error)
FindGroups(ctx context.Context, query string) ([]string, error)
}

0 comments on commit 9379fa0

Please sign in to comment.