Serve PGP messages after reconnect

This commit is contained in:
Reckless_Satoshi 2022-05-28 07:59:32 -07:00
parent f304fa27f9
commit aa7155974c
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
4 changed files with 153 additions and 48 deletions

View File

@ -25,12 +25,13 @@ class MessageAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
list_display = (
"id",
"chatroom_link",
"index",
"order_link",
"sender_link",
"receiver_link",
"created_at",
)
change_links = ["chatroom","order","sender","receiver"]
search_fields = ["id","order"]
ordering = ("-index", )
search_fields = ["id","index"]
ordering = ["-chatroom_id","-index"]
list_filter = ("chatroom",)

View File

@ -47,28 +47,33 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
return None
@database_sync_to_async
def save_new_message(self):
def save_new_PGP_message(self, PGP_message):
'''Creates a Message object'''
order = Order.objects.get(id=self.order_id)
chatroom = ChatRoom.objects.get(order=order)
index = 0
last_message = Message.objects.filter(order=order).latest()
if last_message:
try:
last_message = Message.objects.filter(order=order).latest()
index = last_message.index + 1
except:
index = 1
sender = self.scope["user"]
if order.taker == sender:
receiver = order.maker
elif order.maker == sender:
receiver = order.taker
Message.objects.create(
msg_obj = Message.objects.create(
order=order,
chatroom=chatroom,
index=index,
sender = sender,
PGP_message=self.PGP_message,
sender=sender,
receiver=receiver,
PGP_message=PGP_message,
)
return None
return msg_obj
@database_sync_to_async
def save_disconnect_user(self):
@ -103,6 +108,36 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
if chatroom.taker == self.user:
return chatroom.maker_connected
@database_sync_to_async
def get_peer_PGP_public_key(self):
'''Returns peer PGP public key'''
order = Order.objects.get(id=self.order_id)
if order.maker == self.user:
return order.taker.profile.public_key
if order.taker == self.user:
return order.maker.profile.public_key
@database_sync_to_async
def get_all_PGP_messages(self):
'''Returns all PGP messages'''
order = Order.objects.get(id=self.order_id)
messages = Message.objects.filter(order=order)
msgs = []
for message in messages:
msgs.append({
"index": message.index,
"time": str(message.created_at),
"message": message.PGP_message,
"nick": str(message.sender),
})
return msgs
async def connect(self):
self.order_id = self.scope["url_route"]["kwargs"]["order_id"]
self.room_group_name = f"chat_order_{self.order_id}"
@ -118,6 +153,33 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
await self.accept()
# Send peer PGP public keys
peer_public_key = await self.get_peer_PGP_public_key()
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "chatroom_message",
"message": peer_public_key,
"nick": self.scope["user"].username,
"peer_connected": None,
},
)
# If there is any stored message, serve them.
msgs = await self.get_all_PGP_messages()
for msg in msgs:
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "PGP_message",
"index": msg['index'],
"time": msg['time'],
"message": msg['message'],
"nick": msg['nick'],
"peer_connected": None,
},
)
async def disconnect(self, close_code):
await self.save_disconnect_user()
await self.channel_layer.group_discard(self.room_group_name,
@ -135,22 +197,39 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json["message"]
peer_connected = await self.is_peer_connected()
# Encrypted messages are stored. They are served later when a user reconnects.
if message[0,27] == '-----BEGIN PGP MESSAGE-----':
self.PGP_message = message
await self.save_new_message()
peer_connected = await self.is_peer_connected()
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "chatroom_message",
"message": message,
"nick": self.scope["user"].username,
"peer_connected": peer_connected,
},
)
if message[0:27] == '-----BEGIN PGP MESSAGE-----':
# save to database
msg_obj = await self.save_new_PGP_message(message)
index = msg_obj.index
message = msg_obj.PGP_message
time = str(msg_obj.created_at)
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "PGP_message",
"index": index,
"message": message,
"time": time,
"nick": self.scope["user"].username,
"peer_connected": peer_connected,
},
)
else:
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "chatroom_message",
"message": message,
"nick": self.scope["user"].username,
"peer_connected": peer_connected,
},
)
async def chatroom_message(self, event):
message = event["message"]
@ -161,7 +240,19 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
"message": message,
"user_nick": nick,
"peer_connected": peer_connected,
"time":str(timezone.now()),
}))
pass
async def PGP_message(self, event):
message = event["message"]
nick = event["nick"]
index = event["index"]
peer_connected = event["peer_connected"]
time = event["time"]
await self.send(text_data=json.dumps({
"index": index,
"message": message,
"user_nick": nick,
"peer_connected": peer_connected,
"time":time,
}))

View File

@ -47,7 +47,10 @@ class ChatRoom(models.Model):
return f"Chat:{str(self.order.id)}"
class Message(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
class Meta:
get_latest_by = 'index'
# id = models.PositiveBigIntegerField(primary_key=True, default=uuid.uuid4, editable=False)
order = models.ForeignKey(
Order,
related_name="message",
@ -67,6 +70,12 @@ class Message(models.Model):
on_delete=models.SET_NULL,
null=True,
default=None)
receiver = models.ForeignKey(
User,
related_name="message_receiver",
on_delete=models.SET_NULL,
null=True,
default=None)
PGP_message = models.TextField(max_length=5000,
null=True,
@ -76,4 +85,4 @@ class Message(models.Model):
created_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return f"Chat:{str(self.order.id)}-Index:{self.order.index}"
return f"Chat:{str(self.order.id)} - Idx:{self.index}"

View File

@ -34,6 +34,7 @@ class Chat extends Component {
showPGP: new Array,
waitingEcho: false,
lastSent: '---BLANK---',
latestIndex: 0,
};
rws = new ReconnectingWebSocket('ws://' + window.location.host + '/ws/chat/' + this.props.orderId + '/');
@ -42,13 +43,13 @@ class Chat extends Component {
this.rws.addEventListener('open', () => {
console.log('Connected!');
this.setState({connected: true});
if ( this.state.peer_pub_key == null){
this.rws.send(JSON.stringify({
type: "message",
message: "----PLEASE SEND YOUR PUBKEY----",
nick: this.props.ur_nick,
}));
}
// if ( this.state.peer_pub_key == null){
// this.rws.send(JSON.stringify({
// type: "message",
// message: "----PLEASE SEND YOUR PUBKEY----",
// nick: this.props.ur_nick,
// }));
// }
this.rws.send(JSON.stringify({
type: "message",
message: this.state.own_pub_key,
@ -60,24 +61,24 @@ class Chat extends Component {
const dataFromServer = JSON.parse(message.data);
console.log('Got reply!', dataFromServer.type);
console.log('PGP message index', dataFromServer.index, ' latestIndex ',this.state.latestIndex);
if (dataFromServer){
console.log(dataFromServer)
// If we receive our own key on a message
if (dataFromServer.message == this.state.own_pub_key){console.log("ECHO OF OWN PUB KEY RECEIVED!!")}
if (dataFromServer.message == this.state.own_pub_key){console.log("OWN PUB KEY RECEIVED!!")}
// If we receive a request to send our public key
if (dataFromServer.message == `----PLEASE SEND YOUR PUBKEY----`) {
this.rws.send(JSON.stringify({
type: "message",
message: this.state.own_pub_key,
nick: this.props.ur_nick,
}));
} else
// if (dataFromServer.message == `----PLEASE SEND YOUR PUBKEY----`) {
// this.rws.send(JSON.stringify({
// type: "message",
// message: this.state.own_pub_key,
// nick: this.props.ur_nick,
// }));
// } else
// If we receive a public key other than ours (our peer key!)
if (dataFromServer.message.substring(0,36) == `-----BEGIN PGP PUBLIC KEY BLOCK-----` & dataFromServer.message != this.state.own_pub_key) {
if (dataFromServer.message.substring(0,36) == `-----BEGIN PGP PUBLIC KEY BLOCK-----` && dataFromServer.message != this.state.own_pub_key) {
if (dataFromServer.message == this.state.peer_pub_key){
console.log("PEER HAS RECONNECTED USING HIS PREVIOUSLY KNOWN PUBKEY")
} else if (dataFromServer.message != this.state.peer_pub_key & this.state.peer_pub_key != null){
@ -88,7 +89,8 @@ class Chat extends Component {
} else
// If we receive an encrypted message
if (dataFromServer.message.substring(0,27) == `-----BEGIN PGP MESSAGE-----`){
if (dataFromServer.message.substring(0,27) == `-----BEGIN PGP MESSAGE-----` && dataFromServer.index > this.state.latestIndex){
decryptMessage(
dataFromServer.message.split('\\').join('\n'),
dataFromServer.user_nick == this.props.ur_nick ? this.state.own_pub_key : this.state.peer_pub_key,
@ -99,8 +101,10 @@ class Chat extends Component {
({
waitingEcho: this.state.waitingEcho == true ? (decryptedData.decryptedMessage == this.state.lastSent ? false: true ) : false,
lastSent: decryptedData.decryptedMessage == this.state.lastSent ? '----BLANK----': this.state.lastSent,
latestIndex: dataFromServer.index > this.state.latestIndex ? dataFromServer.index : this.state.latestIndex,
messages: [...state.messages,
{
{
index: dataFromServer.index,
encryptedMessage: dataFromServer.message.split('\\').join('\n'),
plainTextMessage: decryptedData.decryptedMessage,
validSignature: decryptedData.validSignature,