11import base64
2- from calendar import timegm
32import hashlib
43import hmac
5- import jwt
64import random
75import time
6+ from calendar import timegm
87from datetime import datetime
98
10- from pyverless .exceptions import Unauthorized
9+ import jwt
10+
1111from pyverless .config import settings
12+ from pyverless .exceptions import Unauthorized
1213
1314
1415def get_json_web_token (payload , expires = True , expiry = settings .JWT_EXPIRY ):
@@ -19,17 +20,22 @@ def get_json_web_token(payload, expires=True, expiry=settings.JWT_EXPIRY):
1920 # This is how PyJwt computes now, check:
2021 # https://github.com/jpadilla/pyjwt/blob/master/jwt/api_jwt.py#L153
2122 now = timegm (datetime .utcnow ().utctimetuple ())
22- payload [' exp' ] = now + int (expiry )
23+ payload [" exp" ] = now + int (expiry )
2324
24- return jwt .encode (payload , settings .SECRET_KEY , settings .JWT_ALGORITHM ). decode ( 'utf-8' )
25+ return jwt .encode (payload , settings .SECRET_KEY , settings .JWT_ALGORITHM )
2526
2627
2728def decode_json_web_token (token , leeway = settings .JWT_LEEWAY ):
2829 """
2930 Decode a JWT. Leeway time may be provided.
3031 """
3132 try :
32- decoded = jwt .decode (token , settings .SECRET_KEY , leeway = leeway , algorithms = [settings .JWT_ALGORITHM ])
33+ decoded = jwt .decode (
34+ token ,
35+ settings .SECRET_KEY ,
36+ leeway = leeway ,
37+ algorithms = [settings .JWT_ALGORITHM ],
38+ )
3339 except jwt .exceptions .DecodeError :
3440 raise Unauthorized ()
3541 except jwt .exceptions .ExpiredSignatureError :
@@ -52,26 +58,27 @@ def is_expired(expiry):
5258# and it can be found here:
5359# https://github.com/django/django/blob/master/django/contrib/auth/hashers.py
5460# https://github.com/django/django/blob/master/django/utils/crypto.py
55- def get_random_string (length = 12 ,
56- allowed_chars = 'abcdefghijklmnopqrstuvwxyz'
57- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' ):
61+ def get_random_string (
62+ length = 12 ,
63+ allowed_chars = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ,
64+ ):
5865 """
5966 Return a securely generated random string.
6067 The default length of 12 with the a-z, A-Z, 0-9 character set returns
6168 a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
6269 """
6370 random .seed (
6471 hashlib .sha256 (
65- (' %s%s%s' % (random .getstate (), time .time (), settings .SECRET_KEY )).encode ()
72+ (" %s%s%s" % (random .getstate (), time .time (), settings .SECRET_KEY )).encode ()
6673 ).digest ()
6774 )
68- return '' .join (random .choice (allowed_chars ) for i in range (length ))
75+ return "" .join (random .choice (allowed_chars ) for i in range (length ))
6976
7077
7178def constant_time_compare (val1 , val2 ):
7279 """Return True if the two strings are equal, False otherwise."""
73- val1 = val1 .encode (' utf-8' , ' strict' )
74- val2 = val2 .encode (' utf-8' , ' strict' )
80+ val1 = val1 .encode (" utf-8" , " strict" )
81+ val2 = val2 .encode (" utf-8" , " strict" )
7582 return hmac .compare_digest (val1 , val2 )
7683
7784
@@ -81,18 +88,19 @@ def pbkdf2(password, salt, iterations, dklen=0, digest=None):
8188 digest = hashlib .sha256
8289 if not dklen :
8390 dklen = None
84- password = password .encode (' utf-8' , ' strict' )
85- salt = salt .encode (' utf-8' , ' strict' )
91+ password = password .encode (" utf-8" , " strict" )
92+ salt = salt .encode (" utf-8" , " strict" )
8693 return hashlib .pbkdf2_hmac (digest ().name , password , salt , iterations , dklen )
8794
8895
89- class PBKDF2PasswordHasher () :
96+ class PBKDF2PasswordHasher :
9097 """
9198 Secure password hashing using the PBKDF2 algorithm (recommended)
9299 Configured to use PBKDF2 + HMAC + SHA256.
93100 The result is a 64 byte binary string. Iterations may be changed
94101 safely but you must rename the algorithm if you change SHA256.
95102 """
103+
96104 algorithm = "pbkdf2_sha256"
97105 iterations = 100000
98106 digest = hashlib .sha256
@@ -105,11 +113,11 @@ def encode(self, password, salt=None, iterations=None):
105113 iterations = self .iterations
106114
107115 hash = pbkdf2 (password , salt , iterations , digest = self .digest )
108- hash = base64 .b64encode (hash ).decode (' ascii' ).strip ()
116+ hash = base64 .b64encode (hash ).decode (" ascii" ).strip ()
109117 return "%s$%d$%s$%s" % (self .algorithm , iterations , salt , hash )
110118
111119 def verify (self , password , encoded ):
112- algorithm , iterations , salt , hash = encoded .split ('$' , 3 )
120+ algorithm , iterations , salt , hash = encoded .split ("$" , 3 )
113121 assert algorithm == self .algorithm
114122 encoded_2 = self .encode (password , salt , int (iterations ))
115123 return constant_time_compare (encoded , encoded_2 )
0 commit comments