Adding special mailing list behavior for email formatted messages

This commit is contained in:
Chuck 2013-07-10 15:26:10 +07:00
parent abe94b3ca5
commit cb7618f1b6
5 changed files with 212 additions and 85 deletions

View File

@ -1962,6 +1962,7 @@ class MyForm(QtGui.QMainWindow):
shared.config.set(str(addressAtCurrentRow), 'mailinglistname', str(
self.dialog.ui.lineEditMailingListName.text().toUtf8()))
self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177))
shared.config.set(str(addressAtCurrentRow), 'foremail', str(self.dialog.ui.checkBoxWrapMessagesWithEmailHeaders.isChecked()))
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
self.rerenderInboxToLabels()
@ -2997,6 +2998,9 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
addressAtCurrentRow, 'mailinglistname')
except:
mailingListName = ''
self.ui.checkBoxWrapMessagesWithEmailHeaders.setChecked(
shared.safeConfigGetBoolean(addressAtCurrentRow, 'foremail'))
self.ui.lineEditMailingListName.setText(
unicode(mailingListName, 'utf-8'))
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))

View File

@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'specialaddressbehavior.ui'
#
# Created: Fri Apr 26 17:43:31 2013
# by: PyQt4 UI code generator 4.9.4
# Created: Wed Jul 10 15:20:02 2013
# by: PyQt4 UI code generator 4.10.1
#
# WARNING! All changes made in this file will be lost!
@ -12,12 +12,21 @@ from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_SpecialAddressBehaviorDialog(object):
def setupUi(self, SpecialAddressBehaviorDialog):
SpecialAddressBehaviorDialog.setObjectName(_fromUtf8("SpecialAddressBehaviorDialog"))
SpecialAddressBehaviorDialog.resize(386, 172)
SpecialAddressBehaviorDialog.resize(386, 186)
self.gridLayout = QtGui.QGridLayout(SpecialAddressBehaviorDialog)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.radioButtonBehaveNormalAddress = QtGui.QRadioButton(SpecialAddressBehaviorDialog)
@ -30,20 +39,23 @@ class Ui_SpecialAddressBehaviorDialog(object):
self.label = QtGui.QLabel(SpecialAddressBehaviorDialog)
self.label.setWordWrap(True)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
self.gridLayout.addWidget(self.label, 3, 0, 1, 1)
self.label_2 = QtGui.QLabel(SpecialAddressBehaviorDialog)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1)
self.gridLayout.addWidget(self.label_2, 4, 0, 1, 1)
self.lineEditMailingListName = QtGui.QLineEdit(SpecialAddressBehaviorDialog)
self.lineEditMailingListName.setEnabled(False)
self.lineEditMailingListName.setObjectName(_fromUtf8("lineEditMailingListName"))
self.gridLayout.addWidget(self.lineEditMailingListName, 4, 0, 1, 1)
self.gridLayout.addWidget(self.lineEditMailingListName, 5, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(SpecialAddressBehaviorDialog)
self.buttonBox.setMinimumSize(QtCore.QSize(368, 0))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
self.gridLayout.addWidget(self.buttonBox, 6, 0, 1, 1)
self.checkBoxWrapMessagesWithEmailHeaders = QtGui.QCheckBox(SpecialAddressBehaviorDialog)
self.checkBoxWrapMessagesWithEmailHeaders.setObjectName(_fromUtf8("checkBoxWrapMessagesWithEmailHeaders"))
self.gridLayout.addWidget(self.checkBoxWrapMessagesWithEmailHeaders, 2, 0, 1, 1)
self.retranslateUi(SpecialAddressBehaviorDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), SpecialAddressBehaviorDialog.accept)
@ -56,9 +68,10 @@ class Ui_SpecialAddressBehaviorDialog(object):
SpecialAddressBehaviorDialog.setTabOrder(self.lineEditMailingListName, self.buttonBox)
def retranslateUi(self, SpecialAddressBehaviorDialog):
SpecialAddressBehaviorDialog.setWindowTitle(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Special Address Behavior", None, QtGui.QApplication.UnicodeUTF8))
self.radioButtonBehaveNormalAddress.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Behave as a normal address", None, QtGui.QApplication.UnicodeUTF8))
self.radioButtonBehaviorMailingList.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Behave as a pseudo-mailing-list address", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public).", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Name of the pseudo-mailing-list:", None, QtGui.QApplication.UnicodeUTF8))
SpecialAddressBehaviorDialog.setWindowTitle(_translate("SpecialAddressBehaviorDialog", "Special Address Behavior", None))
self.radioButtonBehaveNormalAddress.setText(_translate("SpecialAddressBehaviorDialog", "Behave as a normal address", None))
self.radioButtonBehaviorMailingList.setText(_translate("SpecialAddressBehaviorDialog", "Behave as a pseudo-mailing-list address", None))
self.label.setText(_translate("SpecialAddressBehaviorDialog", "Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public).", None))
self.label_2.setText(_translate("SpecialAddressBehaviorDialog", "Name of the pseudo-mailing-list:", None))
self.checkBoxWrapMessagesWithEmailHeaders.setText(_translate("SpecialAddressBehaviorDialog", "Ensure all incoming messages have standard E-mail headers", None))

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>386</width>
<height>172</height>
<height>186</height>
</rect>
</property>
<property name="windowTitle">
@ -31,7 +31,7 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public).</string>
@ -41,21 +41,21 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Name of the pseudo-mailing-list:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLineEdit" name="lineEditMailingListName">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="minimumSize">
<size>
@ -71,6 +71,13 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBoxWrapMessagesWithEmailHeaders">
<property name="text">
<string>Ensure all incoming messages have standard E-mail headers</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>

View File

@ -293,7 +293,7 @@ class bitmessagePOP3Server(asyncore.dispatcher):
_ = bitmessagePOP3Connection(sock, peer_address, debug=self.debug)
@staticmethod
def reformatMessageForEmail(toAddress, fromAddress, body, subject):
def reformatMessageForReceipt(toAddress, fromAddress, body, subject):
message = parser.Parser().parsestr(body)
print(message)
@ -307,7 +307,7 @@ class bitmessagePOP3Server(asyncore.dispatcher):
flags = tmp[i-21:i]
checksum = int(flags[-4:], 16)
# Checksum to makesure incoming message hasn't been tampered with
# Checksum to make sure incoming message hasn't been tampered with
c = hashlib.sha256(body).digest()[:2]
c = (ord(checksum[0]) << 8) | ord(checksum[1])
@ -338,9 +338,7 @@ class bitmessagePOP3Server(asyncore.dispatcher):
message['From'] = fromLabel
message['Date'] = utils.formatdate()
#if subject_is_valid and body_is_valid:
# return body, subject
message['X-Bitmessage-Subject'] = subject
if not subject_is_valid and 'Subject' not in message:
message['Subject'] = subject
@ -378,3 +376,101 @@ class bitmessagePOP3Server(asyncore.dispatcher):
return message_as_text, subject
@staticmethod
def addMailingListNameToSubject(subject, mailingListName):
withoutre = subject = subject.strip()
re = ''
if subject[:3] == 'Re:' or subject[:3] == 'RE:':
re = subject[:3] + ' '
withoutre = subject[3:].strip()
a = '[' + mailingListName + ']'
if withoutre.startswith(a):
return subject
else:
return re + a + ' ' + subject
@staticmethod
def reformatMessageForMailingList(toAddress, fromAddress, body, subject, mailingListName):
message = parser.Parser().parsestr(body)
print(message)
subject_is_valid = False
i = subject.find('<Bitmessage Mail: ')
if i >= 0:
tmp = subject[i:]
i = tmp.find('>')
if i >= 0:
flags = tmp[i-21:i]
checksum = int(flags[-4:], 16)
# Checksum to make sure incoming message hasn't been tampered with
c = hashlib.sha256(body).digest()[:2]
c = (ord(checksum[0]) << 8) | ord(checksum[1])
# Valid Bitmessage subject line already
if c == checksum:
subject_is_valid = True
else:
with shared.printLock:
print 'Got E-Mail formatted message with incorrect checksum...'
# The mailing list code will override some headers, including Date and From, so
# that the trust can be moved from the original sender to the mailing list owner.
fromLabel = '{}@{}'.format(getBase58Capitaliation(fromAddress), fromAddress)
if 'From' in message:
originalFrom = message['From']
message['X-Original-From'] = originalFrom
i = originalFrom.find('<' + fromLabel + '>')
if i >= 0:
fromLabel = '{} <{}>'.format(originalFrom[:i].strip(), fromLabel)
message['From'] = fromLabel
message['Date'] = utils.formatdate()
message['X-Bitmessage-Subject'] = subject
if 'Subject' not in message:
if not subject_is_valid:
message['Subject'] = bitmessagePOP3Server.addMailingListNameToSubject(subject, mailingListName)
else:
# TODO - strip <Bitmessage Mail: ...> from bitmessage subject?
message['Subject'] = bitmessagePOP3Server.addMailingListNameToSubject('', mailingListName)
else:
message['Subject'] = bitmessagePOP3Server.addMailingListNameToSubject(message['Subject'], mailingListName)
toLabel = '{}@{}'.format(getBase58Capitaliation(toAddress), toAddress)
try:
toLabel = '{} <{}>'.format(shared.config.get(toAddress, 'label'), toLabel)
except:
pass
if 'To' in message:
message['X-Original-To'] = message['To']
message['To'] = toLabel
# X-Bitmessage-MailingList-Name
message['X-Bitmessage-MailingList-Name'] = mailingListName
# X-Bitmessage-MailingList-Address
mailingListAddress = "{}@{}".format(getBase58Capitaliation(toAddress), toAddress)
message['X-Bitmessage-MailingList-Address'] = mailingListAddress
# X-Bitmessage-MailingList-Version
message["X-Bitmessage-MailingList-Version"] = shared.softwareVersion
fp = StringIO()
gen = generator.Generator(fp, mangle_from_=False, maxheaderlen=128)
gen.flatten(message)
message_as_text = fp.getvalue()
# Checksum to makesure incoming message hasn't been tampered with
# TODO - if subject_is_valid, then don't completely overwrite the subject, instead include all the data outside of <> too
checksum = hashlib.sha256(message_as_text).digest()[:2]
checksum = (ord(checksum[0]) << 8) | ord(checksum[1])
subject = bitmessagePOP3Server.addMailingListNameToSubject("<Bitmessage Mail: 0000000000000000{:04x}>".format(checksum), mailingListAddress)
return message_as_text, subject

View File

@ -1031,17 +1031,18 @@ class receiveDataThread(threading.Thread):
body = 'Unknown encoding type.\n\n' + repr(message)
subject = ''
formattedBody, formattedSubject = body, subject
if isEmailAddress:
# The above 'message/subject' formatting may give us weird values if messageEncodingType is bad
body, subject = bitmessagePOP3Server.reformatMessageForEmail(toAddress, fromAddress, body, subject)
formattedBody, formattedSubject = bitmessagePOP3Server.reformatMessageForReceipt(toAddress, fromAddress, body, subject)
if messageEncodingType != 0:
t = (self.inventoryHash, toAddress, fromAddress, subject, int(
time.time()), body, 'inbox', messageEncodingType, 0)
t = (self.inventoryHash, toAddress, fromAddress, formattedSubject, int(
time.time()), formattedBody, 'inbox', messageEncodingType, 0)
helper_inbox.insert(t)
shared.UISignalQueue.put(('displayNewInboxMessage', (
self.inventoryHash, toAddress, fromAddress, subject, body)))
self.inventoryHash, toAddress, fromAddress, formattedSubject, formattedBody)))
# If we are behaving as an API then we might need to run an
# outside command to let some program know that a new message
@ -1063,12 +1064,18 @@ class receiveDataThread(threading.Thread):
toAddress, 'mailinglistname')
except:
mailingListName = ''
if isEmailAddress:
# The above 'message/subject' formatting may give us weird values if messageEncodingType is bad
message, subject = bitmessagePOP3Server.reformatMessageForMailingList(toAddress, fromAddress, body, subject, mailingListName)
else:
# Let us send out this message as a broadcast
subject = self.addMailingListNameToSubject(
subject, mailingListName)
# Let us now send this message out as a broadcast
message = time.strftime("%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime(
)) + ' Message ostensibly from ' + fromAddress + ':\n\n' + body
fromAddress = toAddress # The fromAddress for the broadcast that we are about to send is the toAddress (my address) for the msg message we are currently processing.
ackdata = OpenSSL.rand(
32) # We don't actually need the ackdata for acknowledgement since this is a broadcast message but we can use it to update the user interface when the POW is done generating.