-
Notifications
You must be signed in to change notification settings - Fork 0
/
externalapis.py
254 lines (231 loc) · 9.9 KB
/
externalapis.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
import cherrypy
import nacl.encoding
import nacl.signing
import base64
import json
import urllib.request
import pprint
import nacl.utils
import nacl.secret
import time
import os.path
import loginserver
import helper
import database
import re
import urllib.error
'''
this class deals with incoming apis handled by cherrypy
in general, it validates the signature
'''
class MainApp(object):
#CherryPy Configuration
_cp_config = {'tools.encode.on': True,
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : 'True',
}
# If they try somewhere we don't know, catch it here and send them to the right place.
@cherrypy.expose()
@cherrypy.tools.json_out()
def default(self, *args, **kwargs):
"""The default page, given when we don't recognise where the request is for."""
print("DEFAULT MESSAGE")
code = 404
msg = "invalid endpoint"
return {"response": "error", "message": msg }
'''
for broadcasting
verifies signature of message
updates db if valid
composes error message if not
'''
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def rx_broadcast(self):
error = "ok"
print("recieving broadcast message!")
print(cherrypy.request)
payload = cherrypy.request.json
loginserver_record = payload.get("loginserver_record", None)
message = payload.get("message", None)
sender_created_at = payload.get("sender_created_at", None)
signature = payload.get("signature", None)
if not loginserver_record or not message or not signature:
error = "missing parameters in request"
else:
username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
message_signature = str(loginserver_record)+str(message)+str(sender_created_at)
try:
helper.verifyMessageSignature(message_signature, pubkey, signature)
except nacl.exceptions.BadSignatureError as e:
error = "bad signature error."
print(e)
else:
isMeta = re.search("^!Meta:(\w+):\[*?(\w+)\]*", message)
if not isMeta:
response = database.addBroadCast(loginserver_record, message, sender_created_at, signature, username, 'false')
else:
response = database.addBroadCast(loginserver_record, message, sender_created_at, signature, username, 'true')
key = isMeta.group(1)
val = isMeta.group(2)
if response.get("response", None) == "ok":
helper.addMetaData(key,val,username)
success = response.get("response", "error")
if success == 'error':
error = "failed to add to database"
response = helper.generateResponseJSON(error)
return response
'''
implements ping check as illsutrated by protocol
'''
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def ping_check(self):
response = {}
error = "ok"
print("recieving broadcast message!")
payload = cherrypy.request.json
their_time = payload.get("my_time", None)
their_active_usernames = payload.get("my_active_usernames", None)
their_address = payload.get("connection_address", None)
their_location = payload.get("connection_location", None)
if not their_time or not their_address or not their_location:
error = "missing parameters in request"
response["response"] = "error"
response["message"] = error
else:
response["my_time"] = str(time.time())
active_users = database.getAllUsersStatus("online")
if not active_users:
active_users = []
users = []
for user in active_users:
users.append(user.get("username"))
response["my_active_users"] = users
return response
'''
receiving private messages
verifies signature
if valid, add to database
'''
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def rx_privatemessage(self):
error = "ok"
print("recieving prvate message!")
payload = cherrypy.request.json
loginserver_record = payload.get("loginserver_record", None)
target_pubkey = payload.get("target_pubkey", None)
encr_message = payload.get("encrypted_message", None)
sender_created_at = payload.get("sender_created_at", None)
signature = payload.get("signature", None)
target_username = payload.get("target_username", None)
username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
if not loginserver_record or not encr_message or not signature or not target_pubkey or not target_pubkey or not sender_created_at:
error = "missing parameters in request"
else:
username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
message = str(loginserver_record)+str(target_pubkey)+str(target_username)+str(encr_message)+str(sender_created_at)
try:
helper.verifyMessageSignature(message, pubkey, signature)
print(signature_str)
except nacl.exceptions.BadSignatureError as e:
error = "bad signature error."
print(e)
else:
r = database.addReceivedMessage(target_username, target_pubkey, encr_message, sender_created_at, encr_message, username, loginserver_record, "false")
success = r.get("response", "error")
if success == 'error':
error = "failed to add to database"
response = helper.generateResponseJSON(error)
return response
'''
accepts group invites
verifies message signature
adds goup key and message to database
'''
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def rx_groupinvite(self):
error = "ok"
print("recieving group invite!")
payload = cherrypy.request.json
loginserver_record = payload.get("loginserver_record", None)
target_pubkey = payload.get("target_pubkey", None)
groupkey_hash = payload.get("groupkey_hash", None)
encr_groupkey = payload.get("encrypted_groupkey", None)
sender_created_at = payload.get("sender_created_at", None)
signature = payload.get("signature", None)
target_username = payload.get("target_username", None)
if not loginserver_record or not target_pubkey or not groupkey_hash or not encr_groupkey or not signature or not sender_created_at:
error = "missing parameters in request"
else:
username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
message = str(loginserver_record)+str(groupkey_hash)+str(target_pubkey)+str(target_username)+str(encr_groupkey)+str(sender_created_at)
try:
helper.verifyMessageSignature(message, pubkey, signature)
except nacl.exceptions.BadSignatureError as e:
error = "bad signature error."
print(e)
else:
r = database.addGroupKey(target_username, encr_groupkey) #adding the group key.
r = database.addGroupChatReceived(groupkey_hash, target_username)
success = r.get("response", "error")
if success == 'error':
error = "failed to add to database"
response = helper.generateResponseJSON(error)
return response
'''
receving group messages
'''
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def rx_groupmessage(self):
error = "ok"
print("recieving group message!")
payload = cherrypy.request.json
loginserver_record = payload.get("loginserver_record", None)
groupkey_hash = payload.get("groupkey_hash", None)
group_message = payload.get("group_message", None)
sender_created_at = payload.get("sender_created_at", None)
signature = payload.get("signature", None)
if not loginserver_record or not groupkey_hash or not group_message or not signature or not sender_created_at:
error = "missing parameters in request"
else:
username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
message = str(loginserver_record)+str(group_message)+str(sender_created_at)
try:
helper.verifyMessageSignature(message, pubkey, signature)
except nacl.exceptions.BadSignatureError as e:
error = "bad signature error."
print(e)
else:
r = database.addGroupMessage(groupkey_hash, username, group_message, sender_created_at, 'false')
success = r.get("response", "error")
if success == 'error':
error = "failed to add to database"
response = helper.generateResponseJSON(error)
return response
'''
implements check messages
returns all broadcasts and private messages db already has
'''
@cherrypy.expose
@cherrypy.tools.json_out()
def rx_checkmessages(self, since=None):
print("recieving check messages!")
if not since:
since = 0
broadcasts = database.getAllBroadcasts(since=int(since), checkMessages=True)
pms = database.getAllMessages(since=int(since), checkMessages=None)
payload = {
"response": "ok",
"broadcasts": broadcasts,
"private_messages": pms
}
return payload