Description
Summary
Limiting the scopes of an app using the xero-python library operated by a user with extensive Xero permissions fails. The app in question is a variant of xero-python-oauth2-app.
Although section 3.3 of RFC6749 permits auth servers to "fully or partially ignore" the requested client scope, it seems prudent to restrict scopes when these are a subset of those permitted to the user. The current behaviour contradicts the advice on the Xero Developer docs to "request the minimum scopes required for whatever action that user is performing".
Additionally it would be good if the library caught errors where more extensive scopes than requested have been granted (however undesirable this may be from a security standpoint). At present the app fails with a warning whether or not the calling app is in DEBUG mode
Details
For example, setting the requested scopes to:
offline_access profile accounting.transactions openid accounting.reports.read email
fails on callback with the following warning:
Warning: Scope has changed from "offline_access profile accounting.transactions openid accounting.reports.read email" to "payroll.payslip projects profile accounting.transactions openid accounting.contacts.read accounting.settings payroll.payruns accounting.settings.read accounting.contacts offline_access accounting.transactions.read accounting.journals.read accounting.attachments.read accounting.attachments accounting.reports.read payroll.employees email files payroll.timesheets payroll.settings assets".
The backtrace is as follows:
Traceback (most recent call last):
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask/app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/rory/src/xero-manualjournals/app.py", line 393, in oauth_callback
response = xero.authorized_response()
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/flask_oauthlib/contrib/client/application.py", line 267, in authorized_response
token = oauth.fetch_token(
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/requests_oauthlib/oauth2_session.py", line 244, in fetch_token
self._client.parse_request_body_response(r.text, scope=self.scope)
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 411, in parse_request_body_response
self.token = parse_token_response(body, scope=scope)
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 379, in parse_token_response
validate_token_parameters(params)
File "/home/rory/src/xero-manualjournals/venv/lib/python3.9/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 409, in validate_token_parameters
raise w
Warning: Scope has changed from "offline_access profile accounting.transactions openid accounting.reports.read email" to "payroll.payslip projects profile accounting.transactions openid accounting.contacts.read accounting.settings payroll.payruns accounting.settings.read accounting.contacts offline_access accounting.transactions.read accounting.journals.read accounting.attachments.read accounting.attachments accounting.reports.read payroll.employees email files payroll.timesheets payroll.settings assets".