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
Error handling: Fix status codes #1854
Conversation
HTTP 401 should be used when logging in (i.e. authenticating) would make a difference; HTTP 403 is reserved for requests that fail because the already authenticated user is not authorized (i.e. lacking permissions) to do something.
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.
Because of the assertRegistered
in ListUsersController
, guests can no longer search or view user(s) even if they have permission to.
Otherwise, this seems to be working as intended.
EDIT: Do we just want the API to use 401 error codes ? Or should a page like /admin
also return 401 if not signed in ?
Good catch, on it!
Right now, it returns a 403 and "An error occurred while trying to load this page." Yeah, we might want to fix that. |
This will cause the right error (HTTP 401) to be thrown whenever we're checking for a specific permission, but the user is not even logged in. Authenticated users will still get HTTP 403.
Re. admin page: status code is fixed with this PR, the error message has been fixed by adding a line to the English language pack. |
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.
Seems to work just fine. We probably want to add the error stacktrace back to the API response when debug mode is on, though.
In #1854, I changed the implementation of `assertCan()` to be more aware of the user's log-in status. I came across this when unifying our API's response status code when actors are not authenticated or not authorized to do something. @luceos rightfully had to tweak this again in ea84fc4, because the behavior changed for one of the few API endpoints that checked for a permission that even guests can have. It turns out having this complex behavior in `assertCan()` is quite misleading, because the name suggests a simple permission check and nothing more. Where we actually want to differ between HTTP 401 and 403, we can do this using two method calls, and enforce it with our tests. If this turns out to be problematic or extremely common, we can revisit this and introduce a method with a different, better name in the future. This commit restores the method's behavior in the last release, so we also avoid another breaking change for extensions.
In #1854, I changed the implementation of `assertCan()` to be more aware of the user's log-in status. I came across this when unifying our API's response status code when actors are not authenticated or not authorized to do something. @luceos rightfully had to tweak this again in ea84fc4, because the behavior changed for one of the few API endpoints that checked for a permission that even guests can have. It turns out having this complex behavior in `assertCan()` is quite misleading, because the name suggests a simple permission check and nothing more. Where we actually want to differ between HTTP 401 and 403, we can do this using two method calls, and enforce it with our tests. If this turns out to be problematic or extremely common, we can revisit this and introduce a method with a different, better name in the future. This commit restores the method's behavior in the last release, so we also avoid another breaking change for extensions.
In #1854, I changed the implementation of `assertCan()` to be more aware of the user's log-in status. I came across this when unifying our API's response status code when actors are not authenticated or not authorized to do something. @luceos rightfully had to tweak this again in ea84fc4, because the behavior changed for one of the few API endpoints that checked for a permission that even guests can have. It turns out having this complex behavior in `assertCan()` is quite misleading, because the name suggests a simple permission check and nothing more. Where we actually want to differ between HTTP 401 and 403, we can do this using two method calls, and enforce it with our tests. If this turns out to be problematic or extremely common, we can revisit this and introduce a method with a different, better name in the future. This commit restores the method's behavior in the last release, so we also avoid another breaking change for extensions.
This fixes a regression from flarum#1843 and flarum#1854. Now, the frontend again shows the proper "Incorrect login details" message instead of "You do not have permission to do that".
This test would have failed without commit ea84fc4. Next, I will revert that commit and most of my PR flarum#1854, so we need this test to ensure the API continues to behave as desired.
In flarum#1854, I changed the implementation of `assertCan()` to be more aware of the user's log-in status. I came across this when unifying our API's response status code when actors are not authenticated or not authorized to do something. @luceos rightfully had to tweak this again in ea84fc4, because the behavior changed for one of the few API endpoints that checked for a permission that even guests can have. It turns out having this complex behavior in `assertCan()` is quite misleading, because the name suggests a simple permission check and nothing more. Where we actually want to differ between HTTP 401 and 403, we can do this using two method calls, and enforce it with our tests. If this turns out to be problematic or extremely common, we can revisit this and introduce a method with a different, better name in the future. This commit restores the method's behavior in the last release, so we also avoid another breaking change for extensions.
Refs #1641
Changes proposed in this pull request:
This builds on top of #1843 to make error status codes consistent.
Before my refactoring, two exceptions were handled differently by the API
layer (which let the exception handlers determine the status code) vs. the
middleware used by the frontends (which used the "code" that was set
when throwing the exceptions).
When extracting the logic, I mostly used the exception codes, which
now changed the behavior of the API, e.g. when raising a "permission
denied" error when incorrect login credentials were entered.
For the case of login, this actually meant that you would now get a rather
confusing generic error message when trying to login with an incorrect
password. This is now fixed.
Reviewers should focus on:
Confirmed
php vendor/bin/phpunit
).