Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pkg/connector/client/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/slack-go/slack"
"go.uber.org/zap"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)

Expand Down Expand Up @@ -88,6 +89,11 @@ func WrapError(err error, contextMsg string, annos *annotations.Annotations) err
return uhttp.WrapErrors(grpcCode, contextMsg, err)
}

// Preserve the gRPC code if the error already has one (e.g. from uhttp/businessPlusClient).
// Only fall back to Unknown if no code is set.
if code := status.Code(err); code != codes.OK {
return uhttp.WrapErrors(code, contextMsg, err)
}
return uhttp.WrapErrors(codes.Unknown, contextMsg, err)
}

Expand Down
33 changes: 30 additions & 3 deletions pkg/connector/user_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package connector
import (
"context"
"fmt"
"strconv"

v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
"github.com/conductorone/baton-sdk/pkg/annotations"
Expand All @@ -14,6 +15,8 @@ import (
"github.com/slack-go/slack"
)

const userGroupGrantPageSize = 20

type userGroupResourceType struct {
resourceType *v2.ResourceType
client *slack.Client
Expand Down Expand Up @@ -129,7 +132,7 @@ func (o *userGroupResourceType) Entitlements(
func (o *userGroupResourceType) Grants(
ctx context.Context,
res *v2.Resource,
_ resource.SyncOpAttrs,
attrs resource.SyncOpAttrs,
) (
[]*v2.Grant,
*resource.SyncOpResults,
Expand All @@ -141,8 +144,26 @@ func (o *userGroupResourceType) Grants(
return nil, &resource.SyncOpResults{Annotations: outputAnnotations}, client.WrapError(err, fmt.Sprintf("fetching user group members for group %s", res.Id.Resource), &outputAnnotations)
}

// Parse the page offset from the token. On the first call this is 0.
offset := 0
if attrs.PageToken.Token != "" {
offset, err = strconv.Atoi(attrs.PageToken.Token)
if err != nil {
return nil, nil, fmt.Errorf("baton-slack: parsing page token: %w", err)
}
}

// Group membership may have changed between pages.
if offset >= len(groupMembers) {
return nil, &resource.SyncOpResults{Annotations: outputAnnotations}, nil
}

// Slice the member list for this page.
end := min(offset+userGroupGrantPageSize, len(groupMembers))
page := groupMembers[offset:end]

var rv []*v2.Grant
for _, member := range groupMembers {
for _, member := range page {
user, err := o.client.GetUserInfoContext(ctx, member)
if err != nil {
return nil, &resource.SyncOpResults{Annotations: outputAnnotations}, client.WrapError(err, fmt.Sprintf("fetching user info for member %s", member), &outputAnnotations)
Expand All @@ -156,5 +177,11 @@ func (o *userGroupResourceType) Grants(
rv = append(rv, grant)
}

return rv, &resource.SyncOpResults{Annotations: outputAnnotations}, nil
// If there are more members, return a token so the SDK calls us again.
var nextPageToken string
if end < len(groupMembers) {
nextPageToken = strconv.Itoa(end)
}

return rv, &resource.SyncOpResults{NextPageToken: nextPageToken, Annotations: outputAnnotations}, nil
}
Loading