Skip to content

Commit b67fb27

Browse files
authored
Merge pull request #55 from ConductorOne/lauren/use-group-member-all-endpoint
use group member all endpoint to get members and pending invites
2 parents f328bf8 + 849c422 commit b67fb27

File tree

3 files changed

+29
-72
lines changed

3 files changed

+29
-72
lines changed

pkg/connector/client/client.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,21 @@ func (c *GitlabClient) GetGroup(ctx context.Context, groupID string) (*Group, *v
190190
return &group, rateLimitDesc, nil
191191
}
192192

193+
// ListAllGroupMembers retrieves members and pending invites of a specific group.
194+
func (c *GitlabClient) ListAllGroupMembers(ctx context.Context, groupID string, nextPageToken string) ([]*GroupMember, string, *v2.RateLimitDescription, error) {
195+
var members []*GroupMember
196+
197+
apiURL, _ := url.Parse(fmt.Sprintf("/api/v4/groups/%s/members/all", PathEscape(groupID)))
198+
WithOffsetPagination(apiURL, nextPageToken)
199+
headers, rateLimitDesc, err := c.doRequest(ctx, http.MethodGet, apiURL.String(), &members, nil)
200+
if err != nil {
201+
return nil, "", rateLimitDesc, err
202+
}
203+
204+
nextToken := headers.Get("X-Next-Page")
205+
return members, nextToken, rateLimitDesc, nil
206+
}
207+
193208
// ListGroupMembers retrieves members of a specific group.
194209
func (c *GitlabClient) ListGroupMembers(ctx context.Context, groupID string, nextPageToken string) ([]*GroupMember, string, *v2.RateLimitDescription, error) {
195210
var members []*GroupMember

pkg/connector/helpers.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,3 @@ func parseAccessLevelFromEntitlementID(entitlementID string) (int, error) {
3232
}
3333
return int(levelValue), nil
3434
}
35-
36-
func getNextTokenState(currentType, nextPageFromAPI, nextTypeOnFinish string) cloudListToken {
37-
if nextPageFromAPI != "" {
38-
return cloudListToken{Type: currentType, Token: nextPageFromAPI}
39-
}
40-
return cloudListToken{Type: nextTypeOnFinish, Token: ""}
41-
}

pkg/connector/users.go

Lines changed: 14 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package connector
22

33
import (
44
"context"
5-
"encoding/json"
65
"errors"
76
"fmt"
87
"strconv"
@@ -20,15 +19,8 @@ import (
2019

2120
const (
2221
pendingInvitationUser = "pending-invite-"
23-
resourceTypeMembers = "members"
24-
resourceTypeInvites = "invites"
2522
)
2623

27-
type cloudListToken struct {
28-
Type string `json:"type"`
29-
Token string `json:"token"`
30-
}
31-
3224
type userBuilder struct {
3325
client *client.GitlabClient
3426
}
@@ -100,61 +92,28 @@ func (u *userBuilder) listCloudVersion(ctx context.Context, parentResourceID *v2
10092
var nextPageToken string
10193
var outputAnnotations = annotations.New()
10294

103-
tokenState := cloudListToken{
104-
Type: resourceTypeMembers,
105-
}
106-
if pToken != nil && pToken.Token != "" {
107-
err := json.Unmarshal([]byte(pToken.Token), &tokenState)
108-
if err != nil {
109-
return nil, "", nil, fmt.Errorf("invalid pagination token: %w", err)
110-
}
111-
}
112-
11395
switch parentResourceID.ResourceType {
11496
case groupResourceType.Id:
11597
groupId, err := fromGroupResourceId(parentResourceID.Resource)
11698
if err != nil {
11799
return nil, "", nil, fmt.Errorf("error parsing group resource id: %w", err)
118100
}
119-
120-
switch tokenState.Type {
121-
case resourceTypeMembers:
122-
var groupMembers []*client.GroupMember
123-
var rateLimitDescGroupMembers *v2.RateLimitDescription
124-
groupMembers, nextPageToken, rateLimitDescGroupMembers, err = u.client.ListGroupMembers(ctx, groupId, tokenState.Token)
125-
if rateLimitDescGroupMembers != nil {
126-
outputAnnotations.WithRateLimiting(rateLimitDescGroupMembers)
127-
}
128-
if err != nil {
129-
return nil, "", outputAnnotations, err
130-
}
131-
for _, member := range groupMembers {
132-
users = append(users, member)
133-
}
134-
135-
tokenState = getNextTokenState(resourceTypeMembers, nextPageToken, resourceTypeInvites)
136-
137-
case resourceTypeInvites:
138-
var pendingInvites []*client.PendingInviteUser
139-
var rateLimitDescInvites *v2.RateLimitDescription
140-
pendingInvites, nextPageToken, rateLimitDescInvites, err = u.client.ListPendingGroupInvitations(ctx, groupId, tokenState.Token)
141-
if rateLimitDescInvites != nil {
142-
outputAnnotations.WithRateLimiting(rateLimitDescInvites)
143-
}
144-
if err != nil {
145-
return nil, "", outputAnnotations, err
146-
}
147-
for _, invite := range pendingInvites {
148-
users = append(users, invite)
149-
}
150-
151-
tokenState = getNextTokenState(resourceTypeInvites, nextPageToken, "")
101+
var groupMembers []*client.GroupMember
102+
var rateLimitDescGroupMembers *v2.RateLimitDescription
103+
groupMembers, nextPageToken, rateLimitDescGroupMembers, err = u.client.ListAllGroupMembers(ctx, groupId, pToken.Token)
104+
if rateLimitDescGroupMembers != nil {
105+
outputAnnotations.WithRateLimiting(rateLimitDescGroupMembers)
106+
}
107+
if err != nil {
108+
return nil, "", outputAnnotations, err
109+
}
110+
for _, member := range groupMembers {
111+
users = append(users, member)
152112
}
153-
154113
case projectResourceType.Id:
155114
var projectMembers []*client.ProjectMember
156115
var rateLimitDescProjectMembers *v2.RateLimitDescription
157-
projectMembers, nextPageToken, rateLimitDescProjectMembers, err = u.client.ListProjectMembers(ctx, parentResourceID.Resource, tokenState.Token)
116+
projectMembers, nextPageToken, rateLimitDescProjectMembers, err = u.client.ListProjectMembers(ctx, parentResourceID.Resource, pToken.Token)
158117
if rateLimitDescProjectMembers != nil {
159118
outputAnnotations.WithRateLimiting(rateLimitDescProjectMembers)
160119
}
@@ -164,20 +123,9 @@ func (u *userBuilder) listCloudVersion(ctx context.Context, parentResourceID *v2
164123
for _, member := range projectMembers {
165124
users = append(users, member)
166125
}
167-
168-
tokenState = getNextTokenState(resourceTypeMembers, nextPageToken, "")
169-
}
170-
171-
var finalNextPageToken string
172-
if tokenState.Type != "" || tokenState.Token != "" {
173-
nextTokenBytes, err := json.Marshal(tokenState)
174-
if err != nil {
175-
return nil, "", nil, fmt.Errorf("failed to marshal pagination token: %w", err)
176-
}
177-
finalNextPageToken = string(nextTokenBytes)
178126
}
179127

180-
return users, finalNextPageToken, outputAnnotations, nil
128+
return users, nextPageToken, outputAnnotations, nil
181129
}
182130

183131
// Entitlements always returns an empty slice for users.
@@ -500,6 +448,7 @@ func userResource(user any) (*v2.Resource, error) {
500448
userStatus = v2.UserTrait_Status_STATUS_DISABLED
501449
case "pending":
502450
userStatus = v2.UserTrait_Status_STATUS_UNSPECIFIED
451+
name = pendingInvitationUser + strings.ToLower(email)
503452
}
504453

505454
profile := map[string]interface{}{

0 commit comments

Comments
 (0)