-
Notifications
You must be signed in to change notification settings - Fork 258
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
feat(auth): add subscription items endpoint #1478
feat(auth): add subscription items endpoint #1478
Conversation
4fb5e2a
to
2a24abb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments 😄
auth/tests/api/users.rs
Outdated
|
||
let response = app.send_request(request).await; | ||
|
||
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, since the bearer is missing this should be 'Unauthorized' right? (old bug)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The layer is designed to return 400 (although it should be 401) for this, but since there is no token in the request axum returns a 500 due to failing to set the extension. When we pass an invalid token in the next test, however, the extension should not be set either, but that returns the expected 400. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but that returns the expected 400.
You mean 401?
Should we open a ticket for this bug if it is unrelated to the code changes, and fix it separately? It is important for our monitoring. @oddgrd you can assign it to me if you do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expected in the sense that the current jwt layer implementation would return a 400 for an invalid jwt. I'll open a ticket for it, since I am a bit confused about the code path that leads to this behavior: https://github.com/shuttle-hq/shuttle/blob/main/common/src/backends/auth.rs#L351-L355.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we just proceed with the request, calling inner if there is no bearer token, which seems incorrect since that should return a 401.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment #1478 (comment) prompted me to add a scopedlayer to the endpoint, and now it does return 401, since the jwt auth layer calls the next layer, which is the scopedlayer, and that correctly returns 401 for missing token.
auth/src/api/builder.rs
Outdated
add_subscription_items.layer(JwtAuthenticationLayer::new(move || { | ||
let public_key = public_key.clone(); | ||
async move { public_key.clone() } | ||
})), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed only on this endpoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The auth API has only dealt with API keys or cookies so far, but rather than creating an admin user for provisioner and using that api key to call auth, we decided to just pass on the JWT of the user. This will be the only endpoint that needs to take a JWT, so we're just putting the layer on this handler for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what happens if there is no cached JWT and the first request made is to this endpoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, what do you mean by that? The provisioner needs a JWT to provision RDS, and it then uses this JWT to call the subscription update. It could be problematic if the JWT expires while provisioning the RDS instance, though, but in that case (which should be rare) we may just delete the RDS instance and the user needs to try again.
dash in auth uri
I was incorrectly assuming that there was no valid subscription if it returned false
rather than hardcoding the price id, pass it as startup arg, and fetch it from router state when updating subscriptions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First part of the review (auth and common realated). Continuing tomorrow with the deployer and provisioner parts.
# filters: | ||
# branches: | ||
# only: main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminder: to be removed before merging.
auth/tests/api/users.rs
Outdated
|
||
let response = app.send_request(request).await; | ||
|
||
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but that returns the expected 400.
You mean 401?
Should we open a ticket for this bug if it is unrelated to the code changes, and fix it separately? It is important for our monitoring. @oddgrd you can assign it to me if you do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Description of change
Add an endpoint to auth so we can add subscription items when we provision resources. This will add RDS (or other price_ids) as a product to the existing subscription, as a recurring item. If it is added in the middle of a subscription period, only the cost of the remaining days will be added to the invoice.
An endpoint to remove items from the subscription will follow in a subsequent PR.
How has this been tested? (if applicable)
I have tested this manually on staging, it deployed correctly with the new arg, it increased the subscription correctly and returned the expected message for the initial deployment of the resource.
I also refactored the tests to make it a bit easier to mock stripe, and added a test for the new endpoint.