8000 Add jwt library in contrib · michaelhelmick/twilio-python@e87ba8f · GitHub
[go: up one dir, main page]

Skip to content

Commit e87ba8f

Browse files
committed
Add jwt library in contrib
1 parent 3e7e8f3 commit e87ba8f

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

twilio/contrib/jwt/__init__.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
""" JSON Web Token implementation
2+
3+
Minimum implementation based on this spec:
4+
http://self-issued.info/docs/draft-jones-json-web-token-01.html
5+
"""
6+
import base64
7+
import hashlib
8+
import hmac
9+
10+
try:
11+
import json
12+
except ImportError:
13+
import simplejson as json
14+
15+
__all__ = ['encode', 'decode', 'DecodeError']
16+
17+
class DecodeError(Exception): pass
18+
19+
signing_methods = {
20+
'HS256': lambda msg, key: hmac.new(key, msg, hashlib.sha256).digest(),
21+
'HS384': lambda msg, key: hmac.new(key, msg, hashlib.sha384).digest(),
22+
'HS512': lambda msg, key: hmac.new(key, msg, hashlib.sha512).digest(),
23+
}
24+
25+
def base64url_decode(input):
26+
input += '=' * (4 - (len(input) % 4))
27+
return base64.urlsafe_b64decode(input)
28+
29+
def base64url_encode(input):
30+
return base64.urlsafe_b64encode(input).replace('=', '')
31+
32+
def header(jwt):
33+
header_segment = jwt.split('.', 1)[0]
34+
try:
35+
return json.loads(base64url_decode(header_segment))
36+
except (ValueError, TypeError):
37+
raise DecodeError("Invalid header encoding")
38+
39+
def encode(payload, key, algorithm='HS256'):
40+
segments = []
41+
header = {"typ": "JWT", "alg": algorithm}
42+
segments.append(base64url_encode(json.dumps(header)))
43+
segments.append(base64url_encode(json.dumps(payload)))
44+
signing_input = '.'.join(segments)
45+
try:
46+
ascii_key = unicode(key).encode('utf8')
47+
signature = signing_methods[algorithm](signing_input, ascii_key)
48+
except KeyError:
49+
raise NotImplementedError("Algorithm not supported")
50+
segments.append(base64url_encode(signature))
51+
return '.'.join(segments)
52+
53+
def decode(jwt, key='', verify=True):
54+
try:
55+
signing_input, crypto_segment = jwt.rsplit('.', 1)
56+
header_segment, payload_segment = signing_input.split('.', 1)
57+
except ValueError:
58+
raise DecodeError("Not enough segments")
59+
try:
60+
header = json.loads(base64url_decode(header_segment))
61+
payload = json.loads(base64url_decode(payload_segment))
62+
signature = base64url_decode(crypto_segment)
63+
except (ValueError, TypeError):
64+
raise DecodeError("Invalid segment encoding")
65+
if verify:
66+
try:
67+
ascii_key = unicode(key).encode('utf8')
68+
if not signature == signing_methods[header['alg']](signing_input, ascii_key):
69+
raise DecodeError("Signature verification failed")
70+
except KeyError:
71+
raise DecodeError("Algorithm not supported")
72+
return payload

0 commit comments

Comments
 (0)
0