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

Error handling: Fix status codes #1854

Merged
merged 5 commits into from Sep 2, 2019
Merged

Conversation

franzliedke
Copy link
Contributor

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:

  • Does this make sense?
  • Logic correct?
  • Any cases I missed?

Confirmed

  • Backend changes: tests are green (run php vendor/bin/phpunit).

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.
Copy link
Member

@dsevillamartin dsevillamartin left a 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 ?

@franzliedke
Copy link
Contributor Author

Good catch, on it!

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 ?

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.
@franzliedke
Copy link
Contributor Author

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.

Copy link
Member

@dsevillamartin dsevillamartin left a 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.

@franzliedke franzliedke merged commit 2c43ccf into master Sep 2, 2019
@franzliedke franzliedke deleted the fl/1641-fix-status-codes branch September 2, 2019 14:33
franzliedke added a commit that referenced this pull request Sep 13, 2019
This fixes a regression from #1843 and #1854. Now, the frontend again
shows the proper "Incorrect login details" message instead of "You
do not have permission to do that".
franzliedke added a commit that referenced this pull request Sep 14, 2019
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.
franzliedke added a commit that referenced this pull request Sep 14, 2019
This test would have failed without commit ea84fc4. Next, I will revert
that commit and most of my PR #1854, so we need this test to ensure the
API continues to behave as desired.
franzliedke added a commit that referenced this pull request Sep 14, 2019
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.
luceos pushed a commit that referenced this pull request Feb 4, 2020
This fixes a regression from #1843 and #1854. Now, the frontend again
shows the proper "Incorrect login details" message instead of "You
do not have permission to do that".
luceos pushed a commit that referenced this pull request Feb 4, 2020
This test would have failed without commit ea84fc4. Next, I will revert
that commit and most of my PR #1854, so we need this test to ensure the
API continues to behave as desired.
luceos pushed a commit that referenced this pull request Feb 4, 2020
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.
wzdiyb pushed a commit to wzdiyb/core that referenced this pull request Feb 16, 2020
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".
wzdiyb pushed a commit to wzdiyb/core that referenced this pull request Feb 16, 2020
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.
wzdiyb pushed a commit to wzdiyb/core that referenced this pull request Feb 16, 2020
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.
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.

None yet

2 participants