def broadcastOnlineStatus(self): '''Queue a status notification message for each of our trusted contacts''' print("Outgoing postman is broadcasting the status...") self._broadcasting = True profileList = DbClient.getContactList("trusted") if profileList: msg = StatusNotifyMessage(online=True, ping=True, profileHash=None) msg.recipients = [c['torid'] for c in profileList] DbClient.addMessageToOutbox(msg) self._broadcasting = False self.flushSignal.emit()
def keyFingerprintChecked(torId): '''The fingerprint of this contact's public key has been checked (over a separate channel)''' # Check that userid exists and that status is currently "untrusted" (trusted also doesn't hurt) profile = DbClient.getProfile(torId, False) if profile and profile.get("status", "nostatus") in ["untrusted", "trusted"]: # Update the user's status to trusted DbClient.updateContact(torId, {"status" : "trusted"}) # Trigger a StatusNotify to tell them we're online notify = StatusNotifyMessage(online=True, ping=True, profileHash=None) notify.recipients = [torId] DbClient.addMessageToOutbox(notify)
def servePage(self, view, url, params): print("Compose: %s, params %s" % (url, ",".join(params))) if url == "/start": self.requirePageResources(['default.css']) parentHash = params.get("reply", None) recpts = params.get("sendto", None) # Build list of contacts to whom we can send userboxes = [] for p in DbClient.getMessageableContacts(): box = Bean() box.dispName = p['displayName'] box.torid = p['torid'] userboxes.append(box) pageParams = {"contactlist":userboxes, "parenthash" : parentHash if parentHash else "", "webcachedir":Config.getWebCacheDir(), "recipientids":recpts} contents = self.buildPage({'pageTitle' : I18nManager.getText("composemessage.title"), 'pageBody' : self.composetemplate.getHtml(pageParams), 'pageFooter' : "<p>Footer</p>"}) view.setHtml(contents) # If we've got no friends, then warn, can't send to anyone if not DbClient.hasFriends(): view.page().mainFrame().evaluateJavaScript("window.alert('No friends :(');") elif url == "/send": print("Submit new message with params:", params) msgBody = params['messagebody'] # TODO: check body isn't empty, throw an exception? parentHash = params.get("parenthash", None) recpts = params['sendto'] # Make a corresponding message object and pass it on msg = message.RegularMessage(sendTo=recpts, messageBody=msgBody, replyToHash=parentHash) msg.recipients = recpts.split(",") DbClient.addMessageToOutbox(msg) # Save a copy of the sent message sentMessage = {"messageType":"normal", "fromId":DbClient.getOwnTorId(), "messageBody":msgBody, "timestamp":msg.timestamp, "messageRead":True, "messageReplied":False, "recipients":recpts, "parentHash":parentHash} DbClient.addMessageToInbox(sentMessage) # Close window after successful send contents = self.buildPage({'pageTitle' : I18nManager.getText("messages.title"), 'pageBody' : self.closingtemplate.getHtml(), 'pageFooter' : "<p>Footer</p>"}) view.setHtml(contents)
def dealWithAsymmetricMessage(message): '''Decide what to do with the given asymmetric message''' if message.senderId == MessageShuffler.getOwnTorId(): print("*** Shouldn't receive a message from myself!") return # Sort message according to type if message.messageType == Message.TYPE_CONTACT_RESPONSE: print("Received a contact accept from", message.senderId, "name", message.senderName) if MessageShuffler._isProfileStatusOk(message.senderId, ['pending', 'requested', 'untrusted']): print(message.senderName, "'s public key is", message.senderKey) ContactMaker.handleReceiveAccept(message.senderId, message.senderName, message.senderKey) # Call DbClient to store new message in inbox rowToStore = {"messageType":"contactresponse", "fromId":message.senderId, "fromName":message.senderName, "messageBody":message.introMessage, "accepted":True, "messageRead":False, "messageReplied":False, "timestamp":message.timestamp, "recipients":MessageShuffler.getOwnTorId()} DbClient.addMessageToInbox(rowToStore) elif MessageShuffler._isProfileStatusOk(message.senderId, [None, 'blocked']): print("Received a contact response but I didn't send them a request!") print("Encrypted contents are:", message.encryptedContents) rowToStore = {"messageType":"contactresponse", "fromId":message.senderId, "fromName":message.senderName, "messageBody":message.introMessage, "accepted":True, "timestamp":message.timestamp, "encryptedMsg":message.encryptedContents} DbClient.addMessageToPendingContacts(rowToStore) elif message.messageType == Message.TYPE_STATUS_NOTIFY: if message.online: print("One of our contacts has just come online- ", message.senderId, "and hash is", message.profileHash) prof = DbClient.getProfile(userid=message.senderId, extend=False) if prof: storedHash = prof.get("profileHash", "empty") if message.profileHash != storedHash: reply = InfoRequestMessage(infoType=InfoRequestMessage.INFO_PROFILE) reply.recipients = [message.senderId] DbClient.addMessageToOutbox(reply) if message.ping: print("Now sending back a pong, too") reply = StatusNotifyMessage(online=True, ping=False, profileHash=None) reply.recipients = [message.senderId] DbClient.addMessageToOutbox(reply) else: print("It's already a pong so I won't reply") Contacts.comeOnline(message.senderId) else: print("One of our contacts is going offline -", message.senderId) Contacts.goneOffline(message.senderId) elif message.messageType == Message.TYPE_INFO_REQUEST: print("I've received an info request message for type", message.infoType) if MessageShuffler._isProfileStatusOk(message.senderId, ['trusted']): reply = InfoResponseMessage(message.messageType) reply.recipients = [message.senderId] DbClient.addMessageToOutbox(reply) elif message.messageType == Message.TYPE_INFO_RESPONSE: if message.profile and MessageShuffler._isProfileStatusOk(message.senderId, ['trusted', 'untrusted']): if message.profileHash: message.profile['profileHash'] = message.profileHash DbClient.updateContact(message.senderId, message.profile) elif message.messageType == Message.TYPE_ASYM_MESSAGE: print("It's a general kind of message, this should go in the Inbox, right?") if MessageShuffler._isProfileStatusOk(message.senderId, ['trusted', 'untrusted']): Contacts.comeOnline(message.senderId) else: # It's another asymmetric message type print("Hä? What kind of asymmetric message type is that? ", message.messageType)
def servePage(self, view, url, params): self.requirePageResources(['button-addperson.png', 'button-drawgraph.png', 'avatar-none.jpg']) DbClient.exportAvatars(Config.getWebCacheDir()) if url == "/add" or url == "/add/": contents = self.generateAddPage() view.setHtml(contents) return elif url == "/submitaddrequest": print("Submit add request!:", url) if len(params) > 0: # request to add a new friend recipientid = params.get('murmeliid', '') dispname = params.get('displayname', '') intromessage = params.get('intromessage', '') if len(recipientid) == 16: # TODO: How to react if: person already added (untrusted/trusted); request already sent (requested) # update the database accordingly ContactMaker.handleInitiate(recipientid, dispname) print("I should send an add request to '%s' now." % recipientid) outmsg = message.ContactRequestMessage(introMessage=intromessage) outmsg.recipients = [recipientid] DbClient.addMessageToOutbox(outmsg) else: print("Hmm, show an error message here?") # in any case, go back to contact list url = "/" + recipientid # ensure that picture is generated for new id DbClient.exportAvatars(Config.getWebCacheDir()) contents = None userid = None pageParams = {} # Split url into components /userid/command command = [i for i in url.split("/") if i != ""] if len(command) > 0 and len(command[0]) == 16 and re.match("([a-zA-Z0-9]+)$", command[0]): userid = command[0] # check for command edit or submit-edit if len(command) == 2: if command[1] == "edit": contents = self.generateListPage(doEdit=True, userid=userid) # show edit fields elif command[1] == "submitedit": DbClient.updateContact(userid, params) # don't generate contents, go back to details elif command[1] == "delete": ContactMaker.handleDeleteContact(userid) userid = None elif command[1] == "checkfingerprint": contents = self.generateFingerprintsPage(userid) elif command[1] == "checkedfingerprint": givenAnswer = int(params.get('answer', -1)) fc = self._makeFingerprintChecker(userid) expectedAnswer = fc.getCorrectAnswer() if expectedAnswer == givenAnswer: ContactMaker.keyFingerprintChecked(userid) # Show page again contents = self.generateFingerprintsPage(userid) else: # Add a message to show when the list page is re-generated pageParams['fingerprint_check_failed'] = True # If we haven't got any contents yet, then do a show details if not contents: # Show details for selected userid (or for self if userid is None) contents = self.generateListPage(doEdit=False, userid=userid, extraParams=pageParams) view.setHtml(contents)