Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsc: Add route to check for valid api key #1549

Merged
merged 5 commits into from
May 2, 2024
Merged

rsc: Add route to check for valid api key #1549

merged 5 commits into from
May 2, 2024

Conversation

V-FEXrt
Copy link
Contributor

@V-FEXrt V-FEXrt commented Apr 24, 2024

Add the route POST /auth/check which returns 200 on valid auth key and 401 on invalid auth key. It will be used as an early warning to actors they they may have incorrectly specified their auth key when connecting to the rsc

@V-FEXrt V-FEXrt requested a review from colinschmidt April 24, 2024 22:42
Copy link
Collaborator

@ag-eitilt ag-eitilt left a comment

Choose a reason for hiding this comment

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

I tend to nerd out a bit over HTTP codes, but other than that this looks good so far as I can tell.

@@ -497,6 +504,36 @@ mod tests {

assert_eq!(res.status(), StatusCode::BAD_REQUEST);

// Authorization check with invalid auth should 401
Copy link
Collaborator

Choose a reason for hiding this comment

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

MDN suggests this often means "unauthenticated" in practice rather than a literal "unauthorized", and while there's definitely no reason not to follow the literal meaning since we're using a very specific client software, I might have gone with a 403 Forbidden as an unambiguous response.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, I agree that 401 means "unauthenticated" which imo is correct here since the point is to check if the provided auth key grants authentication :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Makes sense -- I was reading it as the auth key basically being the credentials themselves, in which case you've got valid authentication and just not authorization (i.e. this would be the gate for a restricted-push store), but sounds like my model of what's going on was slightly off.


assert_eq!(res.status(), StatusCode::UNAUTHORIZED);

// Authorization check with valid auth should 200
Copy link
Collaborator

Choose a reason for hiding this comment

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

This one is probably the best code. There's potential in 204 No Content, but I'm not sure the connotations there exactly match up.

# ```
export def rscApiCheckAuthorization (api: RemoteCacheApi): Result Unit Error =
require Some auth = api.getRemoteCacheApiAuthorization
else failWithError "rsc: Checking authorization requires authorization but none was provided"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know what sort of logic chokepoints you have closer to the surface and with this being export it might indeed be the best way to handle it,1 but don't forget that if everything ultimately funnels through a small number of narrow necks, you can collect all the rsc: prefixes through addErrorContext and save a bit of typing/typo risk.

Footnotes

  1. Actually, why is it exported? Doesn't seem like anything which would be helpful for general audiences, but I don't know what sort of package organization you're planning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why is it exported

I consider any HTTP web route as a public part of the RemoteCacheApi interface. Anyone with an instance of the apii should be able to call any function on the remote server.

Since POST auth/check is a function made available on the server, anyone should be able to call it.

If everything ultimately funnels through a small number of narrow necks, you can collect all the rsc: prefixes

I'll need you to give an example of what you mean, but maybe given the above comment this doesn't make sense anymore? The important thing to keep in mind is that this library is just a wrapper around what is available as the public interface on the server. What the consumer does with it (in this case remote_cache_runner) is entirely up to them

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, part 1 makes sense and with that clarification, part 2 is indeed invalid. I basically just meant that if you had a lot of potential errors which were not in directly-exported functions but instead were only accessible by going through a small number of entry points, you wouldn't have to add the rsc: prefix to each of the errors at the place you throw them, and could instead call addErrorContext "rsc" at those chokepoints, for what would likely be fewer times than you have errors.


RemoteCacheApi domain port auth
| Pass
# TODO: check for compatable wake version
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought this version check would be on the server side? What could we check for here?

Copy link
Contributor Author

@V-FEXrt V-FEXrt Apr 30, 2024

Choose a reason for hiding this comment

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

see followup PR :)

but tl;dr we send our version to the server and it tells us if it thinks we are compatible

require Some auth = api.getRemoteCacheApiAuthorization
else failWithError "rsc: Checking authorization requires authorization but none was provided"

require Pass response =
Copy link
Contributor

Choose a reason for hiding this comment

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

How frequently is this function called?
The db should cache the HTTPRequest job but I'm curious if the wake function should be a target?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How frequently is this function called?

Two answers here

  1. As much as the consuming client calls it
  2. In the case of RemoteCacheRunner/default wake implementation, only once per wake invocation so a target doesn't change anything here

Aside:

The db should cache the HTTPRequest job

This isn't the case. Web requests are never safe to cache as the result can change at any time. Because of that web request jobs are never stored in the db

Copy link
Contributor

Choose a reason for hiding this comment

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

SGTM.

Base automatically changed from rsc-post-blob-auth to master May 2, 2024 17:35
@V-FEXrt V-FEXrt merged commit e29acab into master May 2, 2024
12 checks passed
@V-FEXrt V-FEXrt deleted the rsc-check-auth branch May 2, 2024 20:51
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