def test_new_security_bug(self): # Structural subscribers are not notified of security bugs. maintainer = self.factory.makePerson(name='maintainer') project = self.factory.makeProduct(name='fnord', owner=maintainer) subscriber = self.factory.makePerson(name='subscriber') with person_logged_in(subscriber): project.addBugSubscription(subscriber, subscriber) transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='bad thing\n security yes\n affects fnord', subject='security issue', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('security issue', bug.title) self.assertTrue(bug.security_related) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target) recipients = set() for notification in BugNotification.select(): for recipient in notification.recipients: recipients.add(recipient.person) self.assertContentEqual([maintainer], recipients)
def test_new_security_bug(self): # Structural subscribers are not notified of security bugs. maintainer = self.factory.makePerson(name='maintainer') project = self.factory.makeProduct(name='fnord', owner=maintainer) subscriber = self.factory.makePerson(name='subscriber') with person_logged_in(subscriber): project.addBugSubscription(subscriber, subscriber) transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='bad thing\n security yes\n affects fnord', subject='security issue', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('security issue', bug.title) self.assertTrue(bug.security_related) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target) recipients = set() for notification in BugNotification.select(): for recipient in notification.recipients: recipients.add(recipient.person) self.assertContentEqual([maintainer], recipients)
def test_good_signature_timestamp(self): # An email message's GPG signature's timestamp checked to be sure it # isn't too far in the future or past. This test shows that a # signature with a timestamp of appxoimately now will be accepted. signing_context = GPGSigningContext(import_secret_test_key(), password='******') msg = self.factory.makeSignedMessage(body=' security no', signing_context=signing_context) handler = MaloneHandler() with person_logged_in(self.factory.makePerson()): handler.process(msg, msg['To']) # Since there were no commands in the poorly-timestamped message, no # error emails were generated. self.assertEmailQueueLength(0)
def test_good_signature_timestamp(self): # An email message's GPG signature's timestamp checked to be sure it # isn't too far in the future or past. This test shows that a # signature with a timestamp of appxoimately now will be accepted. signing_context = GPGSigningContext( import_secret_test_key().fingerprint, password='******') msg = self.factory.makeSignedMessage( body=' security no', signing_context=signing_context) handler = MaloneHandler() with person_logged_in(self.factory.makePerson()): handler.process(msg, msg['To']) transaction.commit() # Since there were no commands in the poorly-timestamped message, no # error emails were generated. self.assertEqual(stub.test_emails, [])
def test_information_type(self): project = self.factory.makeProduct(name='fnord') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='unsecure\n informationtype userdata\n affects fnord', subject='unsecure code', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('unsecure code', bug.title) self.assertEqual(InformationType.USERDATA, bug.information_type) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target)
def test_information_type(self): project = self.factory.makeProduct(name='fnord') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='unsecure\n informationtype userdata\n affects fnord', subject='unsecure code', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('unsecure code', bug.title) self.assertEqual(InformationType.USERDATA, bug.information_type) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target)
def test_new_bug_with_sharing_policy_proprietary(self): project = self.factory.makeProduct(name='fnord') self.factory.makeCommercialSubscription(product=project) with person_logged_in(project.owner): project.setBugSharingPolicy(BugSharingPolicy.PROPRIETARY) transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='borked\n affects fnord', subject='subject borked', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual([project.owner], list(bug.getDirectSubscribers())) self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
def test_new_bug_with_sharing_policy_proprietary(self): project = self.factory.makeProduct(name='fnord') self.factory.makeCommercialSubscription(product=project) with person_logged_in(project.owner): project.setBugSharingPolicy(BugSharingPolicy.PROPRIETARY) transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='borked\n affects fnord', subject='subject borked', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual([project.owner], list(bug.getDirectSubscribers())) self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
def test_new_affect_command_interleaved_with_bug_commands(self): # The bug commands can appear before and after the affects command. project = self.factory.makeProduct(name='fnord') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='unsecure\n security yes\n affects fnord\n tag ajax', subject='unsecure code', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('unsecure code', bug.title) self.assertTrue(bug.security_related) self.assertEqual(['ajax'], bug.tags) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target)
def test_new_affect_command_interleaved_with_bug_commands(self): # The bug commands can appear before and after the affects command. project = self.factory.makeProduct(name='fnord') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='unsecure\n security yes\n affects fnord\n tag ajax', subject='unsecure code', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('unsecure code', bug.title) self.assertTrue(bug.security_related) self.assertEqual(['ajax'], bug.tags) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target)
def test_bad_timestamp_but_no_commands(self): # If an email message's GPG signature's timestamp is too far in the # future or past but it doesn't contain any commands, the email is # processed anyway. msg = self.factory.makeSignedMessage( body='I really hope this bug gets fixed.') now = time.time() one_week = 60 * 60 * 24 * 7 msg.signature = FakeSignature(timestamp=now + one_week) handler = MaloneHandler() # Clear old emails before potentially generating more. pop_notifications() with person_logged_in(self.factory.makePerson()): handler.process(msg, msg['To']) # Since there were no commands in the poorly-timestamped message, no # error emails were generated. self.assertEmailQueueLength(0)
def test_new_bug_with_one_misplaced_affects_line(self): # Affects commands in the wrong position are processed as the user # intended when the bug is new and there is only one affects. project = self.factory.makeProduct(name='fnord') assignee = self.factory.makePerson(name='pting') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='borked\n assignee pting\n affects fnord', subject='affects after assignee', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('affects after assignee', bug.title) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target) self.assertEqual(assignee, bug.bugtasks[0].assignee)
def test_new_bug(self): project = self.factory.makeProduct(name='fnord') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='borked\n affects fnord', subject='subject borked', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual([project.owner], list(bug.getDirectSubscribers())) self.assertEqual(project.owner, bug.owner) self.assertEqual('subject borked', bug.title) self.assertEqual(1, bug.messages.count()) self.assertEqual('borked\n affects fnord', bug.description) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target)
def test_bad_timestamp_but_no_commands(self): # If an email message's GPG signature's timestamp is too far in the # future or past but it doesn't contain any commands, the email is # processed anyway. msg = self.factory.makeSignedMessage( body='I really hope this bug gets fixed.') now = time.time() one_week = 60 * 60 * 24 * 7 msg.signature = FakeSignature(timestamp=now + one_week) handler = MaloneHandler() # Clear old emails before potentially generating more. del stub.test_emails[:] with person_logged_in(self.factory.makePerson()): handler.process(msg, msg['To']) transaction.commit() # Since there were no commands in the poorly-timestamped message, no # error emails were generated. self.assertEqual(stub.test_emails, [])
def test_new_bug_with_one_misplaced_affects_line(self): # Affects commands in the wrong position are processed as the user # intended when the bug is new and there is only one affects. project = self.factory.makeProduct(name='fnord') assignee = self.factory.makePerson(name='pting') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='borked\n assignee pting\n affects fnord', subject='affects after assignee', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual('affects after assignee', bug.title) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target) self.assertEqual(assignee, bug.bugtasks[0].assignee)
def test_new_bug(self): project = self.factory.makeProduct(name='fnord') transaction.commit() handler = MaloneHandler() with person_logged_in(project.owner): msg = self.factory.makeSignedMessage( body='borked\n affects fnord', subject='subject borked', to_address='*****@*****.**') handler.process(msg, msg['To']) notification = self.getLatestBugNotification() bug = notification.bug self.assertEqual( [project.owner], list(bug.getDirectSubscribers())) self.assertEqual(project.owner, bug.owner) self.assertEqual('subject borked', bug.title) self.assertEqual(1, bug.messages.count()) self.assertEqual('borked\n affects fnord', bug.description) self.assertEqual(1, len(bug.bugtasks)) self.assertEqual(project, bug.bugtasks[0].target)
def getFailureForMessage(self, to_address, from_address=None, body=None): mail = self.factory.makeSignedMessage(body=body, email_address=from_address) switch_dbuser(config.processmail.dbuser) # Rejection email goes to the preferred email of the current user. # The current user is extracted from the current interaction, which is # set up using the authenticateEmail method. However that expects # real GPG signed emails, which we are faking here. login(mail['from']) handler = MaloneHandler() self.assertTrue(handler.process(mail, to_address, None)) notifications = pop_notifications() if not notifications: return None notification = notifications[0] self.assertEqual('Submit Request Failure', notification['subject']) # The returned message is a multipart message, the first part is # the message, and the second is the original message. message, original = notification.get_payload() return message.get_payload(decode=True)
def getFailureForMessage(self, to_address, from_address=None, body=None): mail = self.factory.makeSignedMessage( body=body, email_address=from_address) switch_dbuser(config.processmail.dbuser) # Rejection email goes to the preferred email of the current user. # The current user is extracted from the current interaction, which is # set up using the authenticateEmail method. However that expects # real GPG signed emails, which we are faking here. login(mail['from']) handler = MaloneHandler() self.assertTrue(handler.process(mail, to_address, None)) notifications = pop_notifications() if not notifications: return None notification = notifications[0] self.assertEqual('Submit Request Failure', notification['subject']) # The returned message is a multipart message, the first part is # the message, and the second is the original message. message, original = notification.get_payload() return message.get_payload(decode=True)