mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-20 01:04:15 +00:00
fix pagination on crew record check
This commit is contained in:
+62
-45
@@ -324,56 +324,73 @@ func (a *RemoteHoldAuthorizer) IsCrewMember(ctx context.Context, holdDID, userDI
|
||||
}
|
||||
|
||||
// isCrewMemberNoCache queries XRPC without caching (internal helper)
|
||||
// Handles pagination to check all crew records, not just the first page
|
||||
func (a *RemoteHoldAuthorizer) isCrewMemberNoCache(ctx context.Context, holdDID, userDID string) (bool, error) {
|
||||
// Resolve DID to URL
|
||||
holdURL := atproto.ResolveHoldURL(holdDID)
|
||||
|
||||
// Build XRPC request URL
|
||||
// GET /xrpc/com.atproto.repo.listRecords?repo={did}&collection=io.atcr.hold.crew
|
||||
xrpcURL := fmt.Sprintf("%s%s?repo=%s&collection=%s",
|
||||
holdURL, atproto.RepoListRecords, url.QueryEscape(holdDID), url.QueryEscape(atproto.CrewCollection))
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", xrpcURL, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
resp, err := a.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("XRPC request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return false, fmt.Errorf("XRPC request failed: status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// Parse response
|
||||
var xrpcResp struct {
|
||||
Records []struct {
|
||||
URI string `json:"uri"`
|
||||
CID string `json:"cid"`
|
||||
Value struct {
|
||||
Type string `json:"$type"`
|
||||
Member string `json:"member"`
|
||||
Role string `json:"role"`
|
||||
Permissions []string `json:"permissions"`
|
||||
AddedAt string `json:"addedAt"`
|
||||
} `json:"value"`
|
||||
} `json:"records"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&xrpcResp); err != nil {
|
||||
return false, fmt.Errorf("failed to decode XRPC response: %w", err)
|
||||
}
|
||||
|
||||
// Check if userDID is in the crew list
|
||||
for _, record := range xrpcResp.Records {
|
||||
if record.Value.Member == userDID {
|
||||
// TODO: Check expiration if set
|
||||
return true, nil
|
||||
// Paginate through all crew records
|
||||
cursor := ""
|
||||
for {
|
||||
// Build XRPC request URL with pagination
|
||||
// GET /xrpc/com.atproto.repo.listRecords?repo={did}&collection=io.atcr.hold.crew&limit=100
|
||||
xrpcURL := fmt.Sprintf("%s%s?repo=%s&collection=%s&limit=100",
|
||||
holdURL, atproto.RepoListRecords, url.QueryEscape(holdDID), url.QueryEscape(atproto.CrewCollection))
|
||||
if cursor != "" {
|
||||
xrpcURL += "&cursor=" + url.QueryEscape(cursor)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", xrpcURL, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
resp, err := a.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("XRPC request failed: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
return false, fmt.Errorf("XRPC request failed: status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// Parse response
|
||||
var xrpcResp struct {
|
||||
Cursor string `json:"cursor"`
|
||||
Records []struct {
|
||||
URI string `json:"uri"`
|
||||
CID string `json:"cid"`
|
||||
Value struct {
|
||||
Type string `json:"$type"`
|
||||
Member string `json:"member"`
|
||||
Role string `json:"role"`
|
||||
Permissions []string `json:"permissions"`
|
||||
AddedAt string `json:"addedAt"`
|
||||
} `json:"value"`
|
||||
} `json:"records"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&xrpcResp); err != nil {
|
||||
resp.Body.Close()
|
||||
return false, fmt.Errorf("failed to decode XRPC response: %w", err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
// Check if userDID is in this page of crew records
|
||||
for _, record := range xrpcResp.Records {
|
||||
if record.Value.Member == userDID {
|
||||
// TODO: Check expiration if set
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there are more pages
|
||||
if xrpcResp.Cursor == "" || len(xrpcResp.Records) == 0 {
|
||||
break
|
||||
}
|
||||
cursor = xrpcResp.Cursor
|
||||
}
|
||||
|
||||
return false, nil
|
||||
|
||||
Reference in New Issue
Block a user