Commit 63b2762b authored by Arkadiusz Hiler's avatar Arkadiusz Hiler

mbox: Use the 'From' header from the incoming email

Currently all the patchwork-generated mboxes uses the name and email
address extracted from the last patch that person sent. This is strange
behaviour that leads to problem when a users puts additional information
(e.g. sponsor) in the header or has changed their legal name.

There's no silver bullet to address all the possible scenarios, and this
behaviour causes a lot of confusion.

Luckily we store the vanilla email headers the patch was sent out with
in patch.headers. We can use that to stop the guess game and let the
people to control how they are called for every patch.
Signed-off-by: Arkadiusz Hiler's avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
parent bc45e3ff
...@@ -62,6 +62,47 @@ class MboxPatchResponseTest(TestCase): ...@@ -62,6 +62,47 @@ class MboxPatchResponseTest(TestCase):
'Acked-by: 1\nAcked-by: 2\n') 'Acked-by: 1\nAcked-by: 2\n')
class MboxAuthorship(TestCase):
fixtures = ['default_states', 'default_events']
""" Test that the From in mbox is the same as in the original header """
def setUp(self):
defaults.project.save()
self.original_author = "Orignal Author <original@author.com>"
self.person = defaults.patch_author_person
self.person.name = "Changed Name"
self.person.email = "changed@name.com"
self.person.save()
def testWithChangedPersonName(self):
self.patch = Patch(project=defaults.project,
msgid='p1', name='testpatch',
submitter=self.person, content='',
headers='From: {}'.format(self.original_author))
self.patch.save()
response = self.client.get('/patch/%d/mbox/' % self.patch.id)
self.assertContains(response, 'From: {}'.format(self.original_author))
self.assertNotContains(response, self.person.name)
self.assertNotContains(response, self.person.email)
def testWithoutTheHeaderFallback(self):
""" this should fallback to the Person """
self.patch = Patch(project=defaults.project,
msgid='p1', name='testpatch',
submitter=self.person, content='',
headers='')
self.patch.save()
response = self.client.get('/patch/%d/mbox/' % self.patch.id)
self.assertContains(
response,
'From: {} <{}>'.format(self.person.name, self.person.email))
class MboxPatchSplitResponseTest(TestCase): class MboxPatchSplitResponseTest(TestCase):
fixtures = ['default_states', 'default_events'] fixtures = ['default_states', 'default_events']
......
...@@ -185,6 +185,18 @@ class PatchMbox(MIMENonMultipart): ...@@ -185,6 +185,18 @@ class PatchMbox(MIMENonMultipart):
encode_7or8bit(self) encode_7or8bit(self)
def get_from(patch, charset):
if patch.headers:
headers = HeaderParser().parsestr(patch.headers)
if 'From' in headers:
return headers['From']
# just in case we don't have headers in some old patches
return email.utils.formataddr(
(str(Header(patch.submitter.name, charset)),
patch.submitter.email))
def patch_to_mbox(patch, mbox_options={}): def patch_to_mbox(patch, mbox_options={}):
postscript_re = re.compile('\n-{2,3} ?\n') postscript_re = re.compile('\n-{2,3} ?\n')
...@@ -233,9 +245,7 @@ def patch_to_mbox(patch, mbox_options={}): ...@@ -233,9 +245,7 @@ def patch_to_mbox(patch, mbox_options={}):
mail = PatchMbox(body) mail = PatchMbox(body)
mail['Subject'] = patch.name mail['Subject'] = patch.name
mail['From'] = email.utils.formataddr(( mail['From'] = get_from(patch, mail.patch_charset)
str(Header(patch.submitter.name, mail.patch_charset)),
patch.submitter.email))
mail['X-Patchwork-Id'] = str(patch.id) mail['X-Patchwork-Id'] = str(patch.id)
if patch.delegate: if patch.delegate:
mail['X-Patchwork-Delegate'] = str(patch.delegate.email) mail['X-Patchwork-Delegate'] = str(patch.delegate.email)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment