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

Issue with OAuth2 Scope implementation (Scope has changes from..) #287

Open
iamsarthakjoshi opened this issue Mar 18, 2020 · 9 comments
Open

Comments

@iamsarthakjoshi
Copy link

iamsarthakjoshi commented Mar 18, 2020

I don't understand this problem. I haven't tried changing the scopes in the process, but while verifying with request_uri (after the two-factor authentication) the problem appears every time saying "Scope has changed from...to ..."

image

    def start_xero_auth_view(self, user_key):
        # Get client_id, client_secret from config file or settings then
        credentials = OAuth2Credentials(
            XeroAuth2.client_id, XeroAuth2.client_secret, callback_uri=XeroAuth2.callback_uri,
            scope=[XeroScopes.OFFLINE_ACCESS, XeroScopes.ACCOUNTING_CONTACTS, XeroScopes.ACCOUNTING_TRANSACTIONS]
        )
        authorization_url = credentials.generate_url()
        XeroAuth2.__caches['xero_creds'] = credentials.state
        return authorization_url
    def process_xero_oauth_callback(self, request_uri, auth_code):
        cred_state = XeroAuth2.__caches.get('xero_creds')
        credentials = OAuth2Credentials(**cred_state)
        credentials.verify(request_uri)
        credentials.set_default_tenant()
        XeroAuth2.__caches['xero_creds'] = credentials.state
        return True

Any help is kindly appreciated. :)

Thank you.

@sdolemelipone
Copy link
Contributor

sdolemelipone commented Apr 7, 2020

The scope appears to be reverting to the default scope between the first and second view. Is there a possibility the cache is being changed by another part of your code in-between?

The results are consistent with scope not being passed into OAuth2Credentials.__init__() the second time around.

@deoresheetal
Copy link

I have the same problem. Whereas it also gives me the access_tokens and refresh_tokens

@deoresheetal
Copy link

@iamsarthakjoshi I resolved it with creating new credentials object in callback instead of passing old state

@antlhuede
Copy link

antlhuede commented Nov 20, 2020

I am having the same issue, however the OAuth2Credentials scope is being defined correctly.
When I go to verify it says the scope has changed to the same list of scopes provided by OP.
After inspecting the value of the scope after construction, it is set to the same as it was in the start_auth_view.

The scope in both instances (start_auth_view and callback) is:
['offline_access', 'accounting.contacts.read', 'accounting.transactions.read', 'accounting.attachments.read']

However it gives the following error:
Scope has changed from "accounting.transactions.read offline_access accounting.attachments.read accounting.contacts.read" to "accounting.attachments.read openid accounting.transactions.read offline_access accounting.journals.read accounting.reports.read accounting.contacts.read accounting.transactions projects accounting.attachments profile accounting.settings accounting.settings.read email accounting.contacts assets".

If you need any more contextual information please let me know.

Any help in resolving this other than drastically increasing the requested scope would be appreciated.

@antlhuede
Copy link

I have figured out the issue.

The application you are connecting to has previously granted the user a much larger scope than you are now requesting.

Xero does not reset the scope history of an account / application relationship when disconnecting that application from the organisation. As a result, the only way to reduce the scope granted by an application to a particular account is to delete the application from the Xero Developer portal and link to a new one. The Xero Support team told me that scopes are accumulative and if you have ever requested a larger scope previously it will always return that scope in the access token being granted.

Considering this, the only way to receive the exact scope you are expecting is to:

  1. Delete the application in the Xero Developer / My Apps page
  2. Create a new application in Xero Developer / My Apps
    • This will have to also have the correct redirect uri, etc
  3. Update your project to refer to the new application Client Id / Secret

Once you have done this, the scope you receive will be as expected.

If you don't mind that the scope has changed during the request, you can add the following to your settings.py file:
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = 'True'

This will tell the OAuth requests lib to not care about a changing scope during the request.

@sdolemelipone
Copy link
Contributor

Thanks for sharing the solution!

@antlhuede
Copy link

Thanks for sharing the solution!

Glad the solution could help, I've been on and off trying to figure this out for a while, hopefully it will save others time in the future

@schinckel
Copy link
Collaborator

schinckel commented Mar 16, 2021

Is there something we can do in PyXero to make this "handled" better?

(Or is this resolved and I can close it?)

@antlhuede
Copy link

Is there something we can do in PyXero to make this "handled" better?

(Or is this resolved and I can close it?)

I think it's resolved as there is nothing you can really do on your end, other than maybe providing more information on this particular problem in your docs?

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

No branches or pull requests

5 participants