anitabyte / etsyv3

Python client for the Etsy OpenAPI v3
GNU General Public License v3.0
58 stars 24 forks source link

RuntimeError: No active exception to reraise #14

Closed heaven7 closed 1 year ago

heaven7 commented 1 year ago

Hello there, first thanks a lot for your efforts to bring us that etsy package :).

I wanted to integrate API with the AuthHelper class. I could manage to get the callback_url, but then i stuck here:

views.route("/etsy_callback", methods=['GET'])
@login_required
def etsy_callback():
    data = request.args
    state = data['state']
    code = data['code']
    if state and code:
        res = AuthHelper(etsy_api_key, 'https://localhost:5000/etsy_callback', 'listings_w listings_d listings_r')
        res.set_authorisation_code(state, code) # <-- here the error occurs
        ...

and here is the output

RuntimeError: No active exception to reraise

What do i miss here?

kiblik1 commented 1 year ago

you switched parameters

https://github.com/anitabyte/etsyv3/blob/8af196816ed64e8bc62a9adfb7f035999ec96fb7/etsyv3/util/auth/auth_helper.py#L42

state,code != code,state

heaven7 commented 1 year ago

@kiblik1 same error with correct params:

File "[...]/views.py", line 92, in etsy_callback
res.set_authorisation_code(code, state)
File "[...]/venv/lib/python3.10/site-packages/etsyv3/util/auth/auth_helper.py", line 46, in set_authorisation_code
raise
RuntimeError: No active exception to reraise

could you get the token successfully?

d-winch commented 1 year ago

@kiblik1 same error with correct params:

File "[...]/views.py", line 92, in etsy_callback
res.set_authorisation_code(code, state)
File "[...]/venv/lib/python3.10/site-packages/etsyv3/util/auth/auth_helper.py", line 46, in set_authorisation_code
raise
RuntimeError: No active exception to reraise

could you get the token successfully?

You haven't passed a state argument to the AuthHelper class, so it generates one in the init method. self.state = secrets.token_urlsafe(16) if state is None else state

So I'm assuming the state you're passing here res.set_authorisation_code(state, code) is not equal to the one just generated in AuthHelper. So the following equivalence check fails.

def set_authorisation_code(self, code: str, state: str) -> None:
    if state == self.state:
        self.auth_code = code
    else:
        raise

Here's the example in the README:


def oauth_callback(request):
    state = request.GET["state"]
    code = request.GET["code"]
    auth = AuthHelper(
        keystring, redirect_uri, code_verifier="super_secret_and_random_code_verifier_string", state="super_secret_and_random_code_state_string"
    )
    auth.set_authorisation_code(code, state)
    token = auth.get_access_token()
    save_this_for_later(token)
    return HttpResponse("Logged in!")```
heaven7 commented 1 year ago

@d-winch thanks for pointing into the right direction! This is a working solution for me:

from hashlib import sha256

def my_method(etsy_api_key, callback_url, code, state):
    code_verifizer_str = 'super_secret_and_random_string'
    state_str = 'another_super_secret_and_random_string' 
    code_verifizer = sha256(code_verifizer_str.encode('utf-8')).hexdigest()

    auth = AuthHelper(keystring=etsy_api_key, redirect_uri=callback_url, scopes='listings_w listings_d 
    listings_r', code_verifier=code_verifizer, state=state_str)
    auth.set_authorisation_code(code, state)
    token = auth.get_access_token()
    if token:        
        # save data in db, etc.

It is also important to note, that the code_verifizer string needs to be a sha256 hash. @anitabyte could you please update the readme accordingly.