Skip to content

Handle unexpected ORCID token replies instead of returning a 500 - #2899

Open
tompollard wants to merge 1 commit into
devfrom
tp/orcid-token-errors
Open

tompollard wants to merge 1 commit into
devfrom
tp/orcid-token-errors

Conversation

@tompollard

Copy link
Copy Markdown
Member

Fixes a 500 error seen in production on /authorcid/:

MissingTokenError at /authorcid/
(missing_token) Missing access token parameter.
  user/views.py in _fetch_and_validate_token: token = oauth_session.fetch_token(...)

Cause

When someone links (or logs in with) ORCID, the server exchanges the code from ORCID for a token. _fetch_and_validate_token only caught InvalidGrantError, which is what a standard rejection such as an expired or reused code raises. Two other cases weren't caught, and both gave the user a 500:

  • A reply with no token and no OAuth error, such as an HTML error page from ORCID or a proxy, an empty body, or a rate-limit page. oauthlib raises MissingTokenError for these. That's what happened here; a standard rejection would have raised InvalidGrantError instead.
  • ORCID can't be reached: a connection error or timeout raises a requests exception.

We can't tell what ORCID actually sent, because the reply wasn't logged.

Changes

  • Errors are caught: _fetch_and_validate_token now also catches OAuth2Error and requests.RequestException. The user is sent back to the ORCID settings page (or the login page) with "ORCID did not respond as expected. Please try again in a few minutes."
  • ORCID's reply is logged: a requests_oauthlib compliance hook keeps the reply. The log line has the status, the content type and the first 300 characters of the body. The body is left out if it contains "token", so a token can't end up in the logs.
  • Nothing else changes: an expired or invalid code shows the same message as before, and token validation is the same. This covers ORCID linking and ORCID login, since both use this function.

Testing

  • New tests in user/test_orcid.py:
    • the token endpoint returns a 502 HTML page when linking (the case from production): no 500, the retry message, nothing linked, and the log has the status and body
    • a reply that may contain a token isn't logged
    • ORCID can't be reached
    • the token endpoint returns a 503 when logging in with ORCID: no 500, and the user isn't logged in
  • Checked against the old code: all four new tests error with the exceptions above. With the fix, all 53 ORCID tests pass.
  • Full suite: passes except physionet.test_urls for the anonymous access URL of demoecg, which also fails on dev locally without this change.

Linking or logging in with ORCID only caught InvalidGrantError from the
token request. Any other reply without a token (an error page, an empty
body) raised MissingTokenError, and a network error raised a requests
exception, both giving the user a 500.

Catch any OAuth error and request error, show a message asking the user
to try again, and log ORCID's status, content type and the start of the
reply (left out if it might contain a token).

This branch has not been deployed

No deployments
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.

1 participant