-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathweb_auth_helper.py
More file actions
56 lines (49 loc) · 1.76 KB
/
web_auth_helper.py
File metadata and controls
56 lines (49 loc) · 1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import base64
import hmac
import pickle
class DecodeException(Exception):
def __init__(self, value="Decode failed."):
self.value = value
def __str__(self):
return repr(self.value)
def encode(object_to_encode, key):
"""Returns a concatenated string of: HMAC MD5 signature, a period (.),
and a base64encoded serialized dump of a python object.
Parameters:
object_to_encode: A serializable python object.
key: A secret key string.
"""
serialized_obj_str = pickle.dumps(object_to_encode)
hmac_obj = hmac.new(key, msg=serialized_obj_str)
signed_request = base64.b64encode(hmac_obj.digest()) + '.' + \
base64.b64encode(serialized_obj_str)
return signed_request
def decode(signed_request, key):
"""Accepts a string representing a signed request, and a secret key which
needs to be used to unpack the actual python object.
Returns:
On success: The actual deserialized python object.
On failure: Raises a DecodeException.
"""
# Split the signature and the data.
try:
sig, payload = signed_request.split('.', 1)
except ValueError:
raise DecodeException()
# Decode the data back as serialized object.
try:
decoded_obj_str = base64.b64decode(payload)
except TypeError:
raise DecodeException()
# Get the signature generated using the serialized object and
# the key.
expected_sig = base64.b64encode(hmac.new(key, msg=decoded_obj_str).digest())
# If both the signatures matches.
if sig == expected_sig:
try:
return pickle.loads(decoded_obj_str)
except:
raise DecodeException()
# The signatures doesn't match.
else:
raise DecodeException()