Affects Version/s: 3.5.2, 3.6
Fix Version/s: None
Affected Branches:MOODLE_35_STABLE, MOODLE_36_STABLE
This is a bit involved, but, basically, if the function get_system_oauth_client() is called from 2 different login sessions, then each user gets a different token (generated from the system client's refresh token), with the generation of the token for the second user potentially invalidating the token held by the first user.
- get_system_oauth_client() calls new \core\oauth2\client()
- this calls get_stored_token()
- which looks in $SESSION for a token
- get_system_oauth_client() then calls is_logged_in() - which checks to see if the token that might have been in the $SESSION is still valid or to see if there is a new token via optional_param()
- if is_logged_in() returns false (no token from $SESSION and no token from optional_param()), then upgrade_refesh_token() is called
- upgrade_refresh_token(), pulls the refresh token (if any) from the DB, uses the API to generate a new token, then stores it in $SESSION (and stores the new refresh token in the DB).
If another user logs in and get_system_oauth_client() is called, then they also go through those above steps, using the refresh token to generate a new token, which is stored in their own $SESSION.
Using the refresh token will invalidate the old token on the remote server (this may be server dependent, but is certainly the case when connecting to an OwnCloud server via OAuth).
The first user still appears to have a valid token (it has a token and the expiry date has not been reached), but will get a login error when they try to use it.
Proposed solution: store the system oauth client token in an application cache, rather than in the $SESSION variable.