Skip to content

Commit 7e6cfae

Browse files
Allow access to access_authority tracks when properly signed (#689)
When reqs are signed by access_authority, allow those tracks to be returned (otherwise, streaming is a needle in a haystack kind of problem). Doesn't have much performance impact b/c most rows are null access_authorities and those that are have a quick comparison.
1 parent 7a90a4a commit 7e6cfae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+258
-132
lines changed

api/auth_middleware.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,22 @@ func (app *ApiServer) isAuthorizedRequest(ctx context.Context, userId int32, aut
9797
return isAuthorized
9898
}
9999

100+
// get the wallet that signed the request
100101
func (app *ApiServer) getAuthedWallet(c *fiber.Ctx) string {
101102
return c.Locals("authedWallet").(string)
102103
}
103104

105+
// get the wallet that signed the request, or "" if not set
106+
func (app *ApiServer) tryGetAuthedWallet(c *fiber.Ctx) string {
107+
if c == nil {
108+
return ""
109+
}
110+
if w, ok := c.Locals("authedWallet").(string); ok {
111+
return w
112+
}
113+
return ""
114+
}
115+
104116
// validateOAuthJWTTokenToUserId validates the OAuth JWT and returns the userId from the payload.
105117
func (app *ApiServer) validateOAuthJWTTokenToUserId(ctx context.Context, token string) (trashid.HashId, error) {
106118
tokenParts := strings.Split(token, ".")

api/dbv1/get_tracks.sql.go

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/dbv1/parallel.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import (
77
)
88

99
type ParallelParams struct {
10-
UserIds []int32
11-
TrackIds []int32
12-
PlaylistIds []int32
13-
MyID int32
10+
UserIds []int32
11+
TrackIds []int32
12+
PlaylistIds []int32
13+
MyID int32
14+
AuthedWallet string
1415
}
1516

1617
type ParallelResult struct {
@@ -42,8 +43,9 @@ func (q *Queries) Parallel(ctx context.Context, arg ParallelParams) (*ParallelRe
4243
var err error
4344
trackMap, err = q.TracksKeyed(ctx, TracksParams{
4445
GetTracksParams: GetTracksParams{
45-
Ids: arg.TrackIds,
46-
MyID: arg.MyID,
46+
Ids: arg.TrackIds,
47+
MyID: arg.MyID,
48+
AuthedWallet: arg.AuthedWallet,
4749
},
4850
})
4951
return err
@@ -58,6 +60,7 @@ func (q *Queries) Parallel(ctx context.Context, arg ParallelParams) (*ParallelRe
5860
Ids: arg.PlaylistIds,
5961
MyID: arg.MyID,
6062
},
63+
AuthedWallet: arg.AuthedWallet,
6164
})
6265
return err
6366
})

api/dbv1/playlists.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import (
99

1010
type PlaylistsParams struct {
1111
GetPlaylistsParams
12-
OmitTracks bool
13-
TrackLimit int // 0 means use default (200), positive values set the limit
12+
OmitTracks bool
13+
TrackLimit int // 0 means use default (200), positive values set the limit
14+
AuthedWallet string // wallet that signed the request; tracks with matching access_authorities are shown
1415
}
1516

1617
type Playlist struct {
@@ -68,9 +69,10 @@ func (q *Queries) PlaylistsKeyed(ctx context.Context, arg PlaylistsParams) (map[
6869

6970
// fetch users + tracks in parallel
7071
loaded, err := q.Parallel(ctx, ParallelParams{
71-
UserIds: userIds,
72-
TrackIds: trackIds,
73-
MyID: arg.MyID.(int32),
72+
UserIds: userIds,
73+
TrackIds: trackIds,
74+
MyID: arg.MyID.(int32),
75+
AuthedWallet: arg.AuthedWallet,
7476
})
7577
if err != nil {
7678
return nil, err

api/dbv1/queries/get_tracks.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ LEFT JOIN aggregate_plays on play_item_id = t.track_id
209209
LEFT JOIN track_routes on t.track_id = track_routes.track_id and track_routes.is_current = true
210210
WHERE (is_unlisted = false OR t.owner_id = @my_id OR @include_unlisted::bool = TRUE)
211211
AND t.track_id = ANY(@ids::int[])
212-
AND t.access_authorities IS NULL
212+
AND (t.access_authorities IS NULL
213+
OR (COALESCE(@authed_wallet, '') <> ''
214+
AND EXISTS (SELECT 1 FROM unnest(t.access_authorities) aa WHERE lower(aa) = lower(@authed_wallet))))
213215
ORDER BY t.track_id
214216
;

api/request_helpers.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"github.com/ethereum/go-ethereum/crypto"
1212
"github.com/gofiber/fiber/v2"
13-
"github.com/jackc/pgx/v5"
1413
"github.com/jackc/pgx/v5/pgtype"
1514
)
1615

@@ -139,22 +138,30 @@ func (app *ApiServer) getSignerFromApiAccessKey(ctx context.Context, apiAccessKe
139138
JOIN api_keys ak ON LOWER(ak.api_key) = LOWER(aak.api_key)
140139
WHERE aak.api_access_key = $1 AND aak.is_active = true
141140
`, apiAccessKey).Scan(&parentApiKey, &apiSecret)
142-
if err == pgx.ErrNoRows || err != nil || apiSecret == "" {
143-
return nil
141+
if err == nil && apiSecret != "" {
142+
privateKey, keyErr := crypto.HexToECDSA(strings.TrimPrefix(apiSecret, "0x"))
143+
if keyErr != nil {
144+
return nil
145+
}
146+
parentApiKeyLower := strings.ToLower(parentApiKey)
147+
app.apiAccessKeySignerCache.Set(apiAccessKey, apiAccessKeySignerEntry{
148+
ApiKey: parentApiKeyLower,
149+
ApiSecret: apiSecret,
150+
})
151+
return &Signer{
152+
Address: parentApiKeyLower,
153+
PrivateKey: privateKey,
154+
}
144155
}
145156

146-
parentApiKeyLower := strings.ToLower(parentApiKey)
147-
app.apiAccessKeySignerCache.Set(apiAccessKey, apiAccessKeySignerEntry{
148-
ApiKey: parentApiKeyLower,
149-
ApiSecret: apiSecret,
150-
})
151-
152-
privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(apiSecret, "0x"))
157+
// Fallback: use apiAccessKey as raw private key when no api_secret is found
158+
privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(apiAccessKey, "0x"))
153159
if err != nil {
154160
return nil
155161
}
162+
address := crypto.PubkeyToAddress(privateKey.PublicKey)
156163
return &Signer{
157-
Address: parentApiKeyLower,
164+
Address: address.Hex(),
158165
PrivateKey: privateKey,
159166
}
160167
}

api/v1_comments.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ func (app *ApiServer) queryFullComments(
109109
}
110110
}
111111
related, err := app.queries.Parallel(c.Context(), dbv1.ParallelParams{
112-
UserIds: userIds,
113-
TrackIds: trackIds,
114-
MyID: app.getMyId(c),
112+
UserIds: userIds,
113+
TrackIds: trackIds,
114+
MyID: app.getMyId(c),
115+
AuthedWallet: app.tryGetAuthedWallet(c),
115116
})
116117
if err != nil {
117118
return err

api/v1_explore_best_selling.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,10 @@ func (app *ApiServer) v1ExploreBestSelling(c *fiber.Ctx) error {
111111
}
112112
}
113113
related, err := app.queries.Parallel(c.Context(), dbv1.ParallelParams{
114-
PlaylistIds: playlistIds,
115-
TrackIds: trackIds,
116-
MyID: app.getMyId(c),
114+
PlaylistIds: playlistIds,
115+
TrackIds: trackIds,
116+
MyID: app.getMyId(c),
117+
AuthedWallet: app.tryGetAuthedWallet(c),
117118
})
118119
if err != nil {
119120
return err

api/v1_playlist.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func (app *ApiServer) v1Playlist(c *fiber.Ctx) error {
8181
MyID: myId,
8282
Ids: []int32{int32(playlistId)},
8383
},
84+
AuthedWallet: app.tryGetAuthedWallet(c),
8485
})
8586
if err != nil {
8687
return err

api/v1_playlist_by_permalink.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func (app *ApiServer) v1PlaylistByPermalink(c *fiber.Ctx) error {
3333
MyID: myId,
3434
Ids: ids,
3535
},
36+
AuthedWallet: app.tryGetAuthedWallet(c),
3637
})
3738
if err != nil {
3839
return err

0 commit comments

Comments
 (0)