Exemple #1
0
    def construct(payload, isEncrypted=True):
        '''Factory constructor using a given payload and extracting the fields'''
        if not payload:
            return None
        signatureKey = None
        if isEncrypted:
            # Decrypt the payload with our key
            decrypted, signatureKey = CryptoClient.decryptAndCheckSignature(
                payload)
        else:
            decrypted = payload
        if decrypted:
            print("Asymmetric message, length of decrypted is", len(decrypted))
        else:
            print("Asymmetric message has no decrypted")
        # Separate fields of message into common ones and the type-specific payload
        msgType, subpayload, tstmp = AsymmetricMessage._stripFields(decrypted)
        print("Recovered timestamp='", tstmp, "' (", len(tstmp), ")")

        # Find a suitable subclass to call using the messageType
        msg = None
        if msgType == Message.TYPE_CONTACT_RESPONSE:
            msg = ContactResponseMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_STATUS_NOTIFY:
            msg = StatusNotifyMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_ASYM_MESSAGE:
            msg = RegularMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_INFO_REQUEST:
            msg = InfoRequestMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_INFO_RESPONSE:
            msg = InfoResponseMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_FRIEND_REFERRAL:
            msg = ContactReferralMessage.constructFrom(subpayload)
        elif msgType == Message.TYPE_FRIENDREFER_REQUEST:
            msg = ContactReferRequestMessage.constructFrom(subpayload)
        # Ask the message if it's ok to have no signature
        if isEncrypted and msg:
            if msg.acceptUnrecognisedSignature():
                # Save the encrypted contents so we can verify it later
                msg.encryptedContents = payload
            elif not signatureKey:
                msg = None
        if msg:
            try:
                msgTimestamp = tstmp.decode('utf-8')
            except:
                msgTimestamp = msg.makeCurrentTimestamp()
            msg.timestamp = Message.convertTimestampFromString(msgTimestamp)
            msg.signatureKeyId = signatureKey
            if signatureKey:
                print(
                    "Asymm setting senderId because I've got a signatureKey: '%s'"
                    % signatureKey)
                signatureId = DbI.findUserIdFromKeyId(signatureKey)
                if signatureId:
                    msg.senderId = signatureId
        return msg
Exemple #2
0
 def construct(payload, isEncrypted):
     '''Construct a message from its payload'''
     originalPayload, signKey = CryptoClient.verifySignedData(
         payload) if isEncrypted else (payload, None)
     if originalPayload:
         # The payload could be verified and extracted, but we still don't know
         # if the contents are for me or for somebody else (probably for somebody else!)
         messageForMe = Message.MessageFromReceivedData(
             originalPayload, isEncrypted)
         if messageForMe:
             return messageForMe
         else:
             msg = RelayingMessage(rcvdBytes=originalPayload)
             msg.senderId = DbI.findUserIdFromKeyId(signKey)
             return msg
Exemple #3
0
    def servePage(self, view, url, params):
        self.requirePageResources(
            ['button-compose.png', 'default.css', 'jquery-3.1.1.js'])
        DbI.exportAllAvatars(Config.getWebCacheDir())

        messageList = None
        if url == "/send":
            print("send message of type '%(messageType)s' to id '%(sendTo)s'" %
                  params)
            if params['messageType'] == "contactresponse":
                torId = params['sendTo']
                if params.get("accept", "0") == "1":
                    ContactMaker.handleAccept(torId)
                    # Make sure this new contact has an empty avatar
                    DbI.exportAllAvatars(Config.getWebCacheDir())
                    outmsg = message.ContactResponseMessage(
                        message=params['messageBody'])
                else:
                    ContactMaker.handleDeny(torId)
                    outmsg = message.ContactDenyMessage()
                # Construct a ContactResponse message object for sending
                outmsg.recipients = [params['sendTo']]
                DbI.addToOutbox(outmsg)
        elif url.startswith("/delete/"):
            DbI.deleteFromInbox(params.get("msgId", ""))
        elif url in ["/search", "/search/"]:
            messageList = DbI.searchInboxMessages(params.get("searchTerm"))

        # Make dictionary to convert ids to names
        contactNames = {
            c['torid']: c['displayName']
            for c in DbI.getProfiles()
        }
        unknownSender = I18nManager.getText("messages.sender.unknown")
        unknownRecpt = I18nManager.getText("messages.recpt.unknown")
        # Get contact requests, responses and mails from inbox
        conreqs = []
        conresps = []
        mailTree = MessageTree()
        if messageList is None:
            messageList = DbI.getInboxMessages()
        # TODO: Paging options?
        for m in messageList:
            if not m:
                continue
            m['msgId'] = str(m.get("_id", ""))
            if m['messageType'] == "contactrequest":
                conreqs.append(m)
            elif m['messageType'] == "contactrefer":
                senderId = m.get('fromId', None)
                m['senderName'] = contactNames.get(senderId, unknownSender)
                conreqs.append(m)
            elif m['messageType'] == "contactresponse":
                if not m.get('accepted', False):
                    m['messageBody'] = I18nManager.getText(
                        "messages.contactrequest.refused")
                    m['fromName'] = DbI.getProfile(m['fromId'])["displayName"]
                elif not m.get('messageBody', False):
                    m['messageBody'] = I18nManager.getText(
                        "messages.contactrequest.accepted")
                conresps.append(m)
            else:
                senderId = m.get('fromId', None)
                if not senderId and m.get('signatureKeyId', None):
                    senderId = DbI.findUserIdFromKeyId(m['signatureKeyId'])
                m['senderName'] = contactNames.get(senderId, unknownSender)
                m['sentTimeStr'] = self.makeLocalTimeString(m['timestamp'])
                # Split m['recipients'] by commas, and look up each id with contactNames
                recpts = m.get('recipients', '')
                if recpts:
                    replyAll = recpts.split(",")
                    m['recipients'] = ", ".join(
                        [contactNames.get(i, unknownRecpt) for i in replyAll])
                    replyAll.append(senderId)
                    m['replyAll'] = ",".join(replyAll)
                else:
                    m['recipients'] = unknownRecpt
                    m['replyAll'] = ""
                mailTree.addMsg(m)
        mails = mailTree.build()
        bodytext = self.messagestemplate.getHtml({
            "contactrequests":
            conreqs,
            "contactresponses":
            conresps,
            "mails":
            mails,
            "nummessages":
            len(conreqs) + len(conresps) + len(mails),
            "webcachedir":
            Config.getWebCacheDir()
        })
        contents = self.buildPage({
            'pageTitle':
            I18nManager.getText("messages.title"),
            'pageBody':
            bodytext,
            'pageFooter':
            "<p>Footer</p>"
        })
        view.setHtml(contents)