comparison test/test_mailgw.py @ 4540:bf67fed13ef9

Fix PGP implementation The pyme API has changed significantly since this worked (API is now better). Add regression-test for PGP support (this isn't run if pyme isn't installed). We're testing only reception of a signed message for now.
author Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
date Thu, 06 Oct 2011 21:02:09 +0000
parents ddff9669361b
children 62239a524beb
comparison
equal deleted inserted replaced
4539:c246f176e7bb 4540:bf67fed13ef9
12 # $Id: test_mailgw.py,v 1.96 2008-08-19 01:40:59 richard Exp $ 12 # $Id: test_mailgw.py,v 1.96 2008-08-19 01:40:59 richard Exp $
13 13
14 # TODO: test bcc 14 # TODO: test bcc
15 15
16 import unittest, tempfile, os, shutil, errno, imp, sys, difflib, rfc822, time 16 import unittest, tempfile, os, shutil, errno, imp, sys, difflib, rfc822, time
17
18
19 try:
20 import pyme, pyme.core
21 except ImportError:
22 pyme = None
23
17 24
18 from cStringIO import StringIO 25 from cStringIO import StringIO
19 26
20 if not os.environ.has_key('SENDMAILDEBUG'): 27 if not os.environ.has_key('SENDMAILDEBUG'):
21 os.environ['SENDMAILDEBUG'] = 'mail-test.log' 28 os.environ['SENDMAILDEBUG'] = 'mail-test.log'
114 res.append('- %s'%l1[i]) 121 res.append('- %s'%l1[i])
115 res.append('+ %s'%l2[j]) 122 res.append('+ %s'%l2[j])
116 123
117 return res 124 return res
118 125
119 class MailgwTestCase(unittest.TestCase, DiffHelper): 126 class MailgwTestAbstractBase(unittest.TestCase, DiffHelper):
120 count = 0 127 count = 0
121 schema = 'classic' 128 schema = 'classic'
122 def setUp(self): 129 def setUp(self):
123 self.old_translate_ = mailgw._ 130 self.old_translate_ = mailgw._
124 roundupdb._ = mailgw._ = i18n.get_translation(language='C').gettext 131 roundupdb._ = mailgw._ = i18n.get_translation(language='C').gettext
125 MailgwTestCase.count = MailgwTestCase.count + 1 132 self.__class__.count = self.__class__.count + 1
126 133
127 # and open the database / "instance" 134 # and open the database / "instance"
128 self.db = memorydb.create('admin') 135 self.db = memorydb.create('admin')
129 self.instance = Tracker() 136 self.instance = Tracker()
130 self.instance.db = self.db 137 self.instance.db = self.db
167 try: 174 try:
168 return f.read() 175 return f.read()
169 finally: 176 finally:
170 f.close() 177 f.close()
171 178
179 # Normal test-case used for both non-pgp test and a test while pgp
180 # is enabled, so this test is run in both test suites.
172 def testEmptyMessage(self): 181 def testEmptyMessage(self):
173 nodeid = self._handle_mail('''Content-Type: text/plain; 182 nodeid = self._handle_mail('''Content-Type: text/plain;
174 charset="iso-8859-1" 183 charset="iso-8859-1"
175 From: Chef <chef@bork.bork.bork> 184 From: Chef <chef@bork.bork.bork>
176 To: issue_tracker@your.tracker.email.domain.example 185 To: issue_tracker@your.tracker.email.domain.example
180 Subject: [issue] Testing... 189 Subject: [issue] Testing...
181 190
182 ''') 191 ''')
183 assert not os.path.exists(SENDMAILDEBUG) 192 assert not os.path.exists(SENDMAILDEBUG)
184 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...') 193 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...')
194
195
196 class MailgwTestCase(MailgwTestAbstractBase):
185 197
186 def testMessageWithFromInIt(self): 198 def testMessageWithFromInIt(self):
187 nodeid = self._handle_mail('''Content-Type: text/plain; 199 nodeid = self._handle_mail('''Content-Type: text/plain;
188 charset="iso-8859-1" 200 charset="iso-8859-1"
189 From: Chef <chef@bork.bork.bork> 201 From: Chef <chef@bork.bork.bork>
1778 1790
1779 Unknown address: fubar@bork.bork.bork 1791 Unknown address: fubar@bork.bork.bork
1780 """) 1792 """)
1781 assert not body_diff, body_diff 1793 assert not body_diff, body_diff
1782 else: 1794 else:
1783 raise AssertionError, "Unathorized not raised when handling mail" 1795 raise AssertionError, "Unauthorized not raised when handling mail"
1784 1796
1785 # Make sure list of users is the same as before. 1797 # Make sure list of users is the same as before.
1786 m = self.db.user.list() 1798 m = self.db.user.list()
1787 m.sort() 1799 m.sort()
1788 self.assertEqual(l, m) 1800 self.assertEqual(l, m)
2948 'Catch this exception and log it without emailing.') 2960 'Catch this exception and log it without emailing.')
2949 self.assertEqual(self.db.msg.get(msgid, 'files'), ['1']) 2961 self.assertEqual(self.db.msg.get(msgid, 'files'), ['1'])
2950 fileid = self.db.msg.get(msgid, 'files')[0] 2962 fileid = self.db.msg.get(msgid, 'files')[0]
2951 self.assertEqual(self.db.file.get(fileid, 'type'), 'message/rfc822') 2963 self.assertEqual(self.db.file.get(fileid, 'type'), 'message/rfc822')
2952 2964
2965 pgp_test_key = """
2966 -----BEGIN PGP PRIVATE KEY BLOCK-----
2967 Version: GnuPG v1.4.10 (GNU/Linux)
2968
2969 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
3021 =3uFZ
3022 -----END PGP PRIVATE KEY BLOCK-----
3023 """
3024
3025 john_doe_key = """
3026 -----BEGIN PGP PRIVATE KEY BLOCK-----
3027 Version: GnuPG v1.4.10 (GNU/Linux)
3028
3029 lQHYBE6NwvABBACxg7QqV2qHywwM3wae6HAHJVEo7EeYA6Lv0pZlW3Aw4CCCnpgJ
3030 jA7CekGFcmGmoCaN9ezuVAPTgUlK4yt8a7P6cT0vw1q341Om9IEKAu59RpNZN/H9
3031 6GfZ95bU51W/hdTFysH1DRwbCR3MowvLeA6Pk4cZlPsYHD0SD3De2i1BewARAQAB
3032 AAP+IRi4L6jKwPS3k3LFrj0SHhL0Fdgv5QTQjTxLNCyfN02iYhglqqoFWncm3jWc
3033 RU/YwGEYwrrBV97kBmVihzkhfgFRsxynE9PMGKKEAuRcAl21RPJDFA6Dlnp6M2No
3034 rR6eoAhrlZ8+KsK9JaXSMalzO/Yh4u3mOinq3f3XL96wAEkCAMAxeZMF5pnXARNR
3035 Y7u2clhNNnLuf+BzpENCFMaWzWPyTcvbf4xNK7ZHPxFVZpX5/qAPJ8rnTaOTHxnN
3036 5PgqbO8CAOxyrTw/muakTJLg+FXdn8BgxZGJXMT7KmkU9SReefjo7c1WlnZxKIAy
3037 6vLIG8WMGpdfCFDve0YLr/GGyDtOjDUB/RN3gn6qnAJThBnVk2wESZVx41fihbIF
3038 ACCKc9heFskzwurtvvp+bunM3quwrSH1hWvxiWJlDmGSn8zQFypGChifgLQZSm9o
3039 biBEb2UgPGpvaG5AdGVzdC50ZXN0Poi4BBMBAgAiBQJOjcLwAhsDBgsJCAcDAgYV
3040 CAIJCgsEFgIDAQIeAQIXgAAKCRC/z7qg+FujnPWiA/9T5SOGraRNIVVIyvJvYwkG
3041 OTAfQ0K3QMlLoQMPmaEbx9Q+isF15M9sOMcl1XGO4UNWuCPIIN8z/y/OLgAB0ZuL
3042 GlnAPPOOZ+MlaUXiMYo8oi416QZrMDf2H/Nkc10csiXm+zMl8RqeIQBEeljNyJ+t
3043 MG1EWn/PHTwFTd/VePuQdJ0B2AROjcLwAQQApw+72jKy0/wqg5SAtnVSkA1F3Jna
3044 /OG+ufz5dX57jkMFRvFoksWIWqHmiCjdE5QV8j+XTnjElhLsmrgjl7aAFveb30R6
3045 ImmcpKMN31vAp4RZlnyYbYUCY4IXFuz3n1CaUL+mRx5yNJykrZNfpWNf2pwozkZq
3046 lcDI69ymIW5acXUAEQEAAQAD/R7Jdf98l1scngMYo228ikYUxBqm2eX/fiQNXDWM
3047 ZR2u+TJ9O53MvFejfXX7Pd6lTDQUBwDFncjgXO0YYSrMzabhqpqoKLqOIpZmBuWC
3048 Hh1lvcFoIYoDR2LkiJ9EPBUEVUBDsUO8ajkILEE3G+DDpCaf9Vo82lCVyhDESqyt
3049 v4lxAgDOLpoq1Whv5Ejr6FifTWytCiQjH2P1SmePlQmy6oEJRUYA1t4zYrzCJUX8
3050 VAvPjh9JXilP6mhDbyQArWllewV9AgDPbVOf75ktRwfhje26tZsukqWYJCc1XvoH
3051 3PTzA7vH1HZZq7dvxa87PiSnkOLEsIAsI+4jpeMxpPlQRxUvHf1ZAf9rK3v3HMJ/
3052 2xVzwK24Oaj+g2O7D/fdqtLFGe5S5JobnTyp9xArDAhaZ/AKfDMYjUIKMP+bdNAf
3053 y8fQUtuawFltm1GInwQYAQIACQUCTo3C8AIbDAAKCRC/z7qg+FujnDzYA/9EU6Pv
3054 Ci1+DCtxjnq7IOvOjqExhFNGvN9Dw17Tl8HcyW3if9v5RxeSWYKl0DhzVdzMQgH/
3055 78q4F4W1q2IkB7SCpXizHLIc3eh8iZkbWZE+CGPvTpqyF03Yi16qhxpAbkGs2Yhq
3056 jTx5oJ4CL5fybBOZLg+BTlK4HIee6xEcbNoq+A==
3057 =ZKBW
3058 -----END PGP PRIVATE KEY BLOCK-----
3059 """
3060
3061 ownertrust = """
3062 723762CD5A5FECB76DC72DF85ADCFD5631C38741:6:
3063 2940C247A1FBAD508A1AF24BBFCFBAA0F85BA39C:6:
3064 """
3065
3066 class MailgwPGPTestCase(MailgwTestAbstractBase):
3067 pgphome = 'pgp-test-home'
3068 def setUp(self):
3069 MailgwTestAbstractBase.setUp(self)
3070 self.db.security.addRole (name = 'pgp', description = 'PGP Role')
3071 self.instance.config['PGP_HOMEDIR'] = self.pgphome
3072 self.instance.config['PGP_ROLES'] = 'pgp'
3073 self.instance.config['PGP_ENABLE'] = True
3074 self.db.user.set(self.john_id, roles='User,pgp')
3075 os.mkdir(self.pgphome)
3076 os.environ['GNUPGHOME'] = self.pgphome
3077 ctx = pyme.core.Context()
3078 key = pyme.core.Data(pgp_test_key)
3079 ctx.op_import(key)
3080 key = pyme.core.Data(john_doe_key)
3081 ctx.op_import(key)
3082 # trust-modelling with pyme isn't working in 0.8.1
3083 # based on libgpgme11 1.2.0, also tried in C -- same thing.
3084 otrust = os.popen ('gpg --import-ownertrust 2> /dev/null', 'w')
3085 otrust.write(ownertrust)
3086 otrust.close()
3087
3088 def tearDown(self):
3089 MailgwTestAbstractBase.tearDown(self)
3090 if os.path.exists(self.pgphome):
3091 shutil.rmtree(self.pgphome)
3092
3093 def testUnsignedMessage(self):
3094 self.assertRaises(MailUsageError, self._handle_mail,
3095 '''Content-Type: text/plain;
3096 charset="iso-8859-1"
3097 From: John Doe <john@test.test>
3098 To: issue_tracker@your.tracker.email.domain.example
3099 Message-Id: <dummy_test_message_id>
3100 Subject: [issue] Testing non-signed message...
3101
3102 This is no pgp signed message.
3103 ''')
3104
3105 def testSignedMessage(self):
3106 nodeid = self._handle_mail('''Content-Disposition: inline
3107 From: John Doe <john@test.test>
3108 To: issue_tracker@your.tracker.email.domain.example
3109 Subject: [issue] Testing signed message...
3110 Content-Type: multipart/signed; micalg=pgp-sha1;
3111 protocol="application/pgp-signature"; boundary="cWoXeonUoKmBZSoM"
3112
3113
3114 --cWoXeonUoKmBZSoM
3115 Content-Type: text/plain; charset=us-ascii
3116 Content-Disposition: inline
3117
3118 This is a pgp signed message.
3119
3120 --cWoXeonUoKmBZSoM
3121 Content-Type: application/pgp-signature; name="signature.asc"
3122 Content-Description: Digital signature
3123 Content-Disposition: inline
3124
3125 -----BEGIN PGP SIGNATURE-----
3126 Version: GnuPG v1.4.10 (GNU/Linux)
3127
3128 iJwEAQECAAYFAk6N4A4ACgkQv8+6oPhbo5x5nAP/d7R7SxTvLoVESI+1r7eDXp1J
3129 LvBVU2EF3YFYKBHMLcWmjG92fNjnHX6NENTEhTeBynba5IPEwUfITC+7PmgPmQkA
3130 VXnFZnwraHxsYgyFsVFN1kkTSbwRUlWl9+nTEsr0yBLTpZN0QSIDcwu+i/xVcg+t
3131 ZQ4K6R3m3AOw7BLdvZs=
3132 =wpYk
3133 -----END PGP SIGNATURE-----
3134
3135 --cWoXeonUoKmBZSoM--
3136 ''')
3137 m = self.db.issue.get (nodeid, 'messages') [0]
3138 self.assertEqual(self.db.msg.get(m, 'content'),
3139 'This is a pgp signed message.')
3140
2953 def test_suite(): 3141 def test_suite():
2954 suite = unittest.TestSuite() 3142 suite = unittest.TestSuite()
2955 suite.addTest(unittest.makeSuite(MailgwTestCase)) 3143 suite.addTest(unittest.makeSuite(MailgwTestCase))
3144 if pyme is not None:
3145 suite.addTest(unittest.makeSuite(MailgwPGPTestCase))
3146 else:
3147 print "Skipping PGP tests"
2956 return suite 3148 return suite
2957 3149
2958 if __name__ == '__main__': 3150 if __name__ == '__main__':
2959 runner = unittest.TextTestRunner() 3151 runner = unittest.TextTestRunner()
2960 unittest.main(testRunner=runner) 3152 unittest.main(testRunner=runner)
2961 3153
2962 # vim: set filetype=python sts=4 sw=4 et si : 3154 # vim: set filetype=python sts=4 sw=4 et si :
2963
2964
2965
2966

Roundup Issue Tracker: http://roundup-tracker.org/