Skip to content

[API-49] Give correct access based on self id and grants#63

Merged
raymondjacobson merged 4 commits intomainfrom
rj-api-49
May 3, 2025
Merged

[API-49] Give correct access based on self id and grants#63
raymondjacobson merged 4 commits intomainfrom
rj-api-49

Conversation

@raymondjacobson
Copy link
Copy Markdown
Member

This PR fixes 3 issues with access:

  1. Currently you will get a stream URL back even if you don't have access (oops!)
  2. Access checker now grants access if authedUserId = myId
  3. Access checker now grants access if authedWallet is a granted app/manager

This feels a bit prop drill-y but I couldn't easily come up with something better.

Would be great to get feedback.

Copy link
Copy Markdown
Contributor

@schottra schottra left a comment

Choose a reason for hiding this comment

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

This works but passing the function around does feel a little messy. I had the thought that we could just change the way auth middleware and context works so that:

  • If you pass a user_id and a wallet, we require the wallet to either be the user or have a grant for the user. In the latter case, if you don't have a grant, we just throw a 403 immediately (in other words, you aren't allowed to make a request with a contextual user you don't have permission to be)
  • Just use myID/userId in the handler and trust that it's been validated before we hit the handler (then we don't need to call the isAuthorizedRequest handler manually)

I could be misunderstanding how myId works (and also I'm not sure what the difference is between that and userId in our Context object)

Comment thread api/dbv1/full_tracks.go

// If you can download it, you can stream it
streamAccess := downloadAccess || q.GetTrackAccess(ctx, arg.MyID.(int32), track.StreamConditions, &track, &user)
streamAccess := downloadAccess || q.GetTrackAccess(
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.

Think maybe a wee littl test on the endpoint for these cases? :-)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yep on it

Comment thread api/dbv1/access.go Outdated
}

// I always have access to my own content
if authedUserId != 0 && authedUserId == myId {
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.

Why does authedUserId matching mean the user owns the track?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

^ LOL good catch. need to check this against the owner not myId... ty

@raymondjacobson
Copy link
Copy Markdown
Member Author

Ok change this PR -

authMiddleware:

  • pulls authedUserId and authedWallet from the signature
  • if you provide myId or :wallet, it checks to see if the auth value matches. if it does not, it 40s

requiresAuthMiddleware:

  • just checks to see if you have auth headers present. if you don't, it 401s

And added new tests!

Comment thread api/auth_middleware.go Outdated
userId, wallet := app.recoverAuthorityFromSignatureHeaders(c)
c.Locals("authedUserId", userId)
c.Locals("authedWallet", wallet)
fmt.Println("authMiddleware", userId, wallet)
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.

logger? or is this for debugging

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

oops ty

Comment thread api/auth_middleware.go
// - the user is not authorized to act on behalf of "requestedWallet"
func (app *ApiServer) authMiddleware(c *fiber.Ctx) error {
userId, wallet := app.recoverAuthorityFromSignatureHeaders(c)
c.Locals("authedUserId", userId)
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.

I don't think this fn cares at all about authedUserId by the looks of it - it really only cares that the wallet recovered has a grant or is the wallet of the user with userId = myId

maybe we can avoid fetching the user ID on every request then, and add a clause to the isAuthorizedRequest query to check if there's a row for userId <=> wallet.

then we can remove authedUserId from the context entirely.

wdyt?

(requireAuthMiddleware can do the query still, since it explicitly wants a user ID, but that's only used in one route)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I like what you're thinking here.

I think the query can be done in a single union all. let me merge this first and open another PR

@raymondjacobson raymondjacobson merged commit f7c9a28 into main May 3, 2025
2 checks passed
@raymondjacobson raymondjacobson deleted the rj-api-49 branch May 3, 2025 02:05
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.

3 participants