Python code does not work as expected

#1

I’m new to Python, and I’m trying to implement dynamic authentication and authorization, but for some reason my code doesn’t work as expected.

Here is a example of the code: https://repl.it/repls/AnguishedAttentiveKeys

Here are syntax examples that work as expected:

https://repl.it/repls/GiantSeveralControlpanel

https://repl.it/repls/FixedAnnualRuntime

But in the working code, in the first case, an error is thrown

if (details is None) or (not 'Bearer token' in details['authextra']):
builtins.TypeError: argument of type 'NoneType' is not iterable

And, in the second case,

if (details is None):
    principal[u'extra'][u'error'] = u"Access denied: No Bearer token in authexta"

    return principal

token = details['authextra']['Bearer token']

return is not executed and the code continues execution

token = details['authextra']['Bearer token'];
builtins.TypeError: 'NoneType' object is not subscriptable

And here is another 3rd example: https://repl.it/repls/DependentUnselfishDevelopment

but in the working code

try:
    payload = jwt.decode(token, JWT_SECRET)
except Exception as e:
    # todo: Log in case of system error

    principal[u'extra'][u'error'] = e

    return principal

The return is not executed again and the error is thrown: “WAMP message serialization error: Object of type ‘InvalidSignatureError’ is not JSON serializable”
https://pyjwt.readthedocs.io/en/latest/api.html#jwt.exceptions.InvalidSignatureError

Why can this happen?

>crossbar version

:::::::::::::::::
      :::::          _____                      __
:::::   :   :::::   / ___/____ ___   ___  ___  / /  ___ _ ____
:::::::   :::::::  / /__ / __// _ \ (_-< (_-< / _ \/ _ `// __/
:::::   :   :::::  \___//_/   \___//___//___//_.__/\_,_//_/
      :::::
:::::::::::::::::   Crossbar v19.2.1

Copyright (c) 2013-2019 Crossbar.io Technologies GmbH, licensed under AGPL 3.0.

 Crossbar.io        : 19.2.1
   txaio            : 18.8.1
   Autobahn         : 19.2.1
   Twisted          : 18.9.0-IOCPReactor
   LMDB             : 0.94/lmdb-0.9.22
   Python           : 3.6.8/CPython
 Frozen executable  : no
 Operating system   : Windows-10-10.0.17763-SP0
 Host machine       : AMD64
 Release key        : RWR2yD4qEkDnHAOwcTx6qTqaTT55n+J5pWez5jXUFT89fwlfVO77nFaV
0 Likes

#2

Hi, just looking through the code some things that might help;

If you print out values for variables as you go (like details) you may get some insight into what’s going wrong. It “looks” like in the first instance that ‘authextra’ is set to ‘None’ … so a more ‘defensive’ way to code this might be;

if (details is None) or \
    ('Bearer token' not in details.get('authextra') \
     if details.get('authextra') else True)
...

Or for readability maybe;

authextra = details.get('authextra')
if not details or not authextra or 'Bearer token' not in authextra:
...

Which should fail gracefully when ‘authextra’ isn’t present or None.

In the third example, it’s going to try to return ‘principle’ to the calling client … so principle will be serialized (eg; dict->JSON), sent, then decoded (eg; JSON->dict) by the client. The encoding / decoding process typically can cope with pure variables, but not classes or methods, and in this case ‘e’ will be an instance of ‘Exception’, which it can’t encode. (try assigning “str(e)” instead of “e”)

hth

1 Like