-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmain.py
130 lines (102 loc) · 3.65 KB
/
main.py
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Your Paddle public key.
public_key = '''-----BEGIN PUBLIC KEY-----
YOUR_PUBLIC_KEY_HERE
-----END PUBLIC KEY-----'''
import collections
import base64
import logging
from google.cloud import firestore
import json
def update_firebase(data, collection, doc_id):
logging.info('fb update - collection {} doc_id {}'.format(collection, doc_id))
db = firestore.Client()
doc_ref = db.collection(collection).document(doc_id)
doc_ref.set(data)
# add the event
event_ref = db.collection(collection).document(doc_id).collection('event').document(data['alert_id'])
event_ref.set(data)
def verify(input_data):
# Crypto can be found at https://pypi.org/project/pycryptodome/
from Crypto.PublicKey import RSA
try:
from Crypto.Hash import SHA1
except ImportError:
# Maybe it's called SHA
logging.debug('Import SHA')
from Crypto.Hash import SHA as SHA1
try:
from Crypto.Signature import PKCS1_v1_5
except ImportError:
# Maybe it's called pkcs1_15
logging.debug('Import pksc1_15')
from Crypto.Signature import pkcs1_15 as PKCS1_v1_5
import hashlib
import phpserialize
# Convert key from PEM to DER - Strip the first and last lines and newlines, and decode
public_key_encoded = public_key[26:-25].replace('\n', '')
public_key_der = base64.b64decode(public_key_encoded)
# input_data represents all of the POST fields sent with the request
# Get the p_signature parameter & base64 decode it.
signature = input_data['p_signature']
# Remove the p_signature parameter
del input_data['p_signature']
# Ensure all the data fields are strings
for field in input_data:
input_data[field] = str(input_data[field])
# Sort the data
sorted_data = collections.OrderedDict(sorted(input_data.items()))
# and serialize the fields
serialized_data = phpserialize.dumps(sorted_data)
# verify the data
key = RSA.importKey(public_key_der)
digest = SHA1.new()
digest.update(serialized_data)
verifier = PKCS1_v1_5.new(key)
signature = base64.b64decode(signature)
if verifier.verify(digest, signature):
print('Signature is valid')
return True
else:
print('The signature is invalid!')
return False
def paddle(request):
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
"""
request_data = request.form.to_dict()
logging.info(request_data)
verified = False
try:
verified = verify(request_data)
except Exception as ex:
print(ex)
if not verified:
return "Not Verified!"
uid = None
try:
# should contain json of form {"uid":"an_id"}
passthrough = request_data.get('passthrough')
if passthrough:
p_obj = json.loads(passthrough)
else:
return "No passthrough"
uid = p_obj.get('uid')
if not uid:
return "No passthrough['uid']"
except Exception as ex:
print(ex)
return "Error fetching passthrough uid"
logging.info('passthrough uid: ' + uid)
alert = request_data['alert_name']
sub_events = ['subscription_created',
'subscription_updated',
'subscription_cancelled']
if alert in sub_events and uid:
update_firebase(request_data, 'subscriptions', uid)
return "Subscription: " + alert
return 'No update made'