Skip to content

Allow access authorities to view unlisted tracks#760

Closed
rickyrombo wants to merge 1 commit intomainfrom
mjp-access-authority-unlisted-tracks
Closed

Allow access authorities to view unlisted tracks#760
rickyrombo wants to merge 1 commit intomainfrom
mjp-access-authority-unlisted-tracks

Conversation

@rickyrombo
Copy link
Copy Markdown
Contributor

Summary

  • Adds the authedWallet access authority check to the is_unlisted filter in get_tracks.sql, so unlisted tracks gated by access_authorities are returned when the requesting wallet matches
  • Adds TestGetUnlistedTrackWithAccessAuthority test covering the new behavior

Test plan

  • Verify unlisted tracks with access_authorities are returned when request is signed by a matching authority
  • Verify unlisted tracks with access_authorities are still hidden for unauthenticated requests
  • Verify non-unlisted tracks with access_authorities continue to work as before

🤖 Generated with Claude Code

The is_unlisted filter was blocking tracks even when the requesting
wallet matched an access authority. Add the access authority check
to the unlisted condition so gated unlisted tracks are visible to
their access authorities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the track fetch query so that unlisted tracks gated by access_authorities can be returned when the request is authenticated by a matching authority wallet, and adds a regression test intended to cover that behavior.

Changes:

  • Extend get_tracks SQL is_unlisted filtering to allow access-authority-authenticated wallets to retrieve unlisted gated tracks.
  • Regenerate the sqlc-generated Go query wrapper to reflect the SQL parameter changes.
  • Add a new API test for “unlisted + access_authorities” behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
api/v1_tracks_test.go Adds a test intended to validate returning an unlisted gated track when signed by an access authority.
api/dbv1/queries/get_tracks.sql Adds an authed_wallet-based exception to the is_unlisted filter for access-authority-gated tracks.
api/dbv1/get_tracks.sql.go sqlc-generated update reflecting the SQL predicate and parameter ordering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +80 to +86
// Without auth: unlisted + gated track must not be returned
status, _ := testGet(t, app, "/v1/full/tracks?id=eYZmn", &resp)
assert.Equal(t, 200, status)
assert.Len(t, resp.Data, 0, "unlisted track with access_authorities must not be returned when unauthenticated")

// With auth signed by access authority: unlisted track must be returned
status, _ = testGetWithWallet(t, app, "/v1/full/tracks?id=eYZmn", gateWallet, &resp)
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

This test hits /v1/full/tracks, which (per handler implementation) always sets IncludeUnlisted: true, so the unlisted filter is already bypassed. As a result, this test would still pass even without the new is_unlisted/authed_wallet SQL change, and doesn’t actually validate the new behavior (unlisted track visibility when IncludeUnlisted is false). Consider exercising the db query directly (e.g., app.queries.Tracks / GetTracks with IncludeUnlisted: false) or using an endpoint/path that does not force-include unlisted tracks.

Suggested change
// Without auth: unlisted + gated track must not be returned
status, _ := testGet(t, app, "/v1/full/tracks?id=eYZmn", &resp)
assert.Equal(t, 200, status)
assert.Len(t, resp.Data, 0, "unlisted track with access_authorities must not be returned when unauthenticated")
// With auth signed by access authority: unlisted track must be returned
status, _ = testGetWithWallet(t, app, "/v1/full/tracks?id=eYZmn", gateWallet, &resp)
// Use the non-full tracks endpoint so IncludeUnlisted is not force-enabled.
// Without auth: unlisted + gated track must not be returned.
status, _ := testGet(t, app, "/v1/tracks?id=eYZmn", &resp)
assert.Equal(t, 200, status)
assert.Len(t, resp.Data, 0, "unlisted track with access_authorities must not be returned when unauthenticated")
// With auth signed by access authority: unlisted track must be returned.
status, _ = testGetWithWallet(t, app, "/v1/tracks?id=eYZmn", gateWallet, &resp)

Copilot uses AI. Check for mistakes.
Comment on lines +223 to +224
AND t.access_authorities IS NOT NULL
AND EXISTS (SELECT 1 FROM unnest(t.access_authorities) aa WHERE lower(aa) = lower(@authed_wallet))))
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The access-authority wallet match (EXISTS (SELECT 1 FROM unnest(t.access_authorities) ...)) is computed twice now: once inside the is_unlisted OR clause and again in the existing AND (t.access_authorities IS NULL OR ...) gate below. Since the AND clause already enforces the wallet match whenever access_authorities is non-NULL, the OR clause only needs to check that @authed_wallet is set and t.access_authorities is non-NULL; duplicating the EXISTS/unnest adds per-row work and makes the predicate harder to maintain.

Suggested change
AND t.access_authorities IS NOT NULL
AND EXISTS (SELECT 1 FROM unnest(t.access_authorities) aa WHERE lower(aa) = lower(@authed_wallet))))
AND t.access_authorities IS NOT NULL))

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants