Skip to content
Merged
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
25 changes: 22 additions & 3 deletions pkg/connector/usage_event_feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,11 @@ func (f *usageEventFeed) ListEvents(
events = append(events, evt)
}

if resp != nil && resp.NextPageToken != "" && !reachedBoundary {
cursor.AuditLogCursor = resp.NextPageToken
continue
if resp != nil && !reachedBoundary {
if nextPage := nextAuditLogPage(resp); nextPage != "" {
cursor.AuditLogCursor = nextPage
continue
}
}

// Done with this org for this pass - advance to the next one.
Expand Down Expand Up @@ -237,6 +239,23 @@ func (f *usageEventFeed) ListEvents(
return events, &pagination.StreamState{Cursor: tokenStr, HasMore: true}, annos, nil
}

// nextAuditLogPage returns the token to request the next audit-log page, or
// "" if there isn't one. GitHub's org audit-log endpoint returns opaque
// cursor pagination on github.com/GHEC (go-github parses the Link header's
// non-numeric "page" value into Response.NextPageToken), but GHES-style
// numeric "page=N" Link headers parse into Response.NextPage (int) instead,
// leaving NextPageToken empty. Checking only NextPageToken silently truncates
// GHES audit logs to a single page.
func nextAuditLogPage(resp *github.Response) string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The new GHES numeric-page branch has no test coverage. TestUsageEventFeed_ListEvents_ContinuesPastAnAllFilteredPage only exercises the GHEC path (Link: <...?page=cursor2>; rel="next"), so the resp.NextPage fallback this PR adds would still pass if it regressed. Consider adding a sibling test whose mocked handler emits a numeric Link: <...?page=2>; rel="next" header and asserting the second request is issued with page=2. (confidence: high)

if resp.NextPageToken != "" {
return resp.NextPageToken
}
if resp.NextPage != 0 {
return strconv.Itoa(resp.NextPage)
}
return ""
}

// usageEventFromAuditEntry converts one audit-log entry into a usage event
// targeting the usage-app resource (see usage_app.go). Returns ok=false when
// the entry can't be attributed to a synced user.
Expand Down
Loading