# Unittests for the mokeladmin mail application
# this is crazy stuff

import os
from django.test import TestCase
from django.conf import settings
from mail.models import Server, Account, Address, Domain
from mail.encryption import MokelGnuPG

class EncryptionTest(TestCase):
    def setUp(self):
        self.gpg = MokelGnuPG()
        self.gpg.options.homedir = '%s/test_gpg' % settings.BASE_DIR
        os.mkdir(self.gpg.options.homedir, 0700)
        self.cleartext = "This is a test message."
        self.fprs = {}
        self.secret_keys = {}
        self.public_keys = {}
        self.fprs['mail.c1.invalid'] = \
                "65AF961459D909F630B96D5B2409020F4A5E429D"
        self.fprs['mail.c2.invalid'] = \
                "0692AE1C51E0DE5F8F20FF7C276C245775BFB6E5"
        self.secret_keys['mail.c1.invalid'] = """
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.6 (GNU/Linux)

lQG7BEf2UtARBACxB84ulZl9F2y+X4Lhd773cnkp5iJoN15tDS8g2hpI8HcQPs4A
QRNitHaQulDAVPiU9LkAq6r9tP2Ur8UfcIEWwCi6GdJfBV/GPxFyGB61AXz52RAg
O9PFTV24Zl7hehspN/OTZwNUVSTJHcydcoDyOEUEaGYdquDzsf4UUJ6lvwCg0j2C
6nLdkjJ93dYXkK+0qmzkDHkD/0MGbUzKrs68vTnKxUdJPuPp244Nur6s34JKpixD
dwowBEPHI8PF0r7LOnIZDgDlfzGAt3Qe5Cn/ffKDV1DDm+hUOpDohH5X/fPfZant
8Fpi9uCUHs01MdsCiM36sX/B5QtBR0C5EM6UDrgyO4XdikFw7wjjPaIIw4tW0yu/
8efUBACJVV+2Q51JvjHApEYrMW/0aN8z6ko4rUkRteLFISqboxY/GIbVVDeQnS5L
zNjhiwKIZAN4L0+gL+JJXagdKqG8uSb2iD+PQsu9R8AHK6rGnpGeYiqHv6YIKFVN
wF1mlT/z9nNI3u+GBiGekIgg4wGsmNEEVhf8QSbYXmT+E07whQAAnRTnpw0T+2gX
4V3EppOQMHmy/waKCo60S25vYm9keSAoRG9uJ3QgZXZlciB1c2UgdGhpcyBrZXku
IEludGVybmFsIHB1cnBvc2VzIG9ubHkuKSA8bWFpbC5jMS5pbnZhbGlkPohmBBMR
AgAmBQJH9lLQAhsjBQkSzAMABgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQJAkC
D0peQp0FqwCfTdq7kjHsoFE83l1DlUrh04rTqcAAoLeEuHoyDcBQ1Gc6y901JReb
Qw0QnQEyBEf2UtEQBADRww3o/Zgx5WvutYnyHjnJBKIdK9VjoU2bnTJbbOwoNgQM
vf3myCE7LI0UkFMR8mssWjVviJ7Hx+VeHf+mO5TlH1xWuJMnkDlsv8xQC3TPh5su
8UWL4BTZmDfnL+8znpNV06fsAtQHcAooWy7o2TOMuFUvACgRKhM1nhNbzD2hEwAD
BQP+KvKcNR44pvjROY3v1O0KwvMFs/oU2weVFw0tp25eLZ6q4/yn0uS0S5riX4NL
yvWMFTHIf+x2WxqsJpQAzfMFxwaHuuOac+CNE9YiTfzbhhFq3xam1AqwYoJLitMk
WssKAbCucrg4d8p+zMyC7Twagj2eiQwsy9SWtxmWUVg6KGoAAPkBB09gshbGGyR7
iQnkpu4n1f0b3NuDfFzGiKMclYZuDA/KiE8EGBECAA8FAkf2UtECGwwFCRLMAwAA
CgkQJAkCD0peQp0ehwCfQa89ooYOQ4hM5dVLGY2XtA+b6/sAoKqWyvafLyP2jdOh
L+3voG3C+xMU
=sXh1
-----END PGP PRIVATE KEY BLOCK-----
"""
        self.public_keys['mail.c1.invalid'] = """
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.6 (GNU/Linux)

mQGiBEf2UtARBACxB84ulZl9F2y+X4Lhd773cnkp5iJoN15tDS8g2hpI8HcQPs4A
QRNitHaQulDAVPiU9LkAq6r9tP2Ur8UfcIEWwCi6GdJfBV/GPxFyGB61AXz52RAg
O9PFTV24Zl7hehspN/OTZwNUVSTJHcydcoDyOEUEaGYdquDzsf4UUJ6lvwCg0j2C
6nLdkjJ93dYXkK+0qmzkDHkD/0MGbUzKrs68vTnKxUdJPuPp244Nur6s34JKpixD
dwowBEPHI8PF0r7LOnIZDgDlfzGAt3Qe5Cn/ffKDV1DDm+hUOpDohH5X/fPfZant
8Fpi9uCUHs01MdsCiM36sX/B5QtBR0C5EM6UDrgyO4XdikFw7wjjPaIIw4tW0yu/
8efUBACJVV+2Q51JvjHApEYrMW/0aN8z6ko4rUkRteLFISqboxY/GIbVVDeQnS5L
zNjhiwKIZAN4L0+gL+JJXagdKqG8uSb2iD+PQsu9R8AHK6rGnpGeYiqHv6YIKFVN
wF1mlT/z9nNI3u+GBiGekIgg4wGsmNEEVhf8QSbYXmT+E07whbRLbm9ib2R5IChE
b24ndCBldmVyIHVzZSB0aGlzIGtleS4gSW50ZXJuYWwgcHVycG9zZXMgb25seS4p
IDxtYWlsLmMxLmludmFsaWQ+iGYEExECACYFAkf2UtACGyMFCRLMAwAGCwkIBwMC
BBUCCAMEFgIDAQIeAQIXgAAKCRAkCQIPSl5CnQWrAJ9N2ruSMeygUTzeXUOVSuHT
itOpwACgt4S4ejINwFDUZzrL3TUlF5tDDRC5AQ0ER/ZS0RAEANHDDej9mDHla+61
ifIeOckEoh0r1WOhTZudMlts7Cg2BAy9/ebIITssjRSQUxHyayxaNW+InsfH5V4d
/6Y7lOUfXFa4kyeQOWy/zFALdM+Hmy7xRYvgFNmYN+cv7zOek1XTp+wC1AdwCihb
LujZM4y4VS8AKBEqEzWeE1vMPaETAAMFA/4q8pw1Hjim+NE5je/U7QrC8wWz+hTb
B5UXDS2nbl4tnqrj/KfS5LRLmuJfg0vK9YwVMch/7HZbGqwmlADN8wXHBoe645pz
4I0T1iJN/NuGEWrfFqbUCrBigkuK0yRaywoBsK5yuDh3yn7MzILtPBqCPZ6JDCzL
1Ja3GZZRWDooaohPBBgRAgAPBQJH9lLRAhsMBQkSzAMAAAoJECQJAg9KXkKdHocA
niZNroe9Yhc6uOrMLp1ZXWncNU2RAJ46j2Fj9Fk9SJ3wJ6wOy4Cof9Q2DQ==
=HmeP
-----END PGP PUBLIC KEY BLOCK-----
"""
        self.secret_keys['mail.c2.invalid'] = """
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.6 (GNU/Linux)

lQG7BEf32ZoRBACbV2/bOd9+L16sRAWCi+6lWzw63BbZDt4BMWuy6o/we2vkCGWd
x/m65KQ2ggTQ+4PMfkRWUXRl2FAnivbM14aQl7GXTnyq9RDTWzWjH19li9iod++J
kPLObg/Zn2ldyjvXGACFzfHIXFrnbqQ3J4Ynzjm/ApHAJPN5DKOl+G3lvwCg3F4T
twWomjwKhwZIcyjlwnevYOMEAJP9wCeSnAD2ph98AM7hvqFzBVY3PR885lQxKsI7
uNSwG+zF5ojb9OlzIp2fvJowYBt6ZfvKSmWxv469hBWLVnX4cWpjgFARPSp2alBt
pQQsz3GkqXYMOAFdzw5oYF1iRYgqc/+XT6okuij3uM9Y3eBykio1taxRhzPhYv6V
gX68A/9a7jdWptetgJDXumK7nqQOVZWp02A+6fMFwS1jfk0oBi+F5tK+9we8t6Js
/rwwEzj8jMCJ+wPJZSw2psguHv/okQQ4996nssFJLkyY5NP2CV7Ja8dRw7Vzj99n
RtD+pcrMgnh8MaGoW4kcDWhAl8rZnjKbq7fnCP4EMyQMnkN1hwAAoKyj12sVq0pB
dAcchagulZogdKF/CVG0S25vYm9keSAoRG9uJ3QgZXZlciB1c2UgdGhpcyBrZXku
IEludGVybmFsIHB1cnBvc2VzIG9ubHkuKSA8bWFpbC5jMi5pbnZhbGlkPohmBBMR
AgAmBQJH99maAhsjBQkSzAMABgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQJ2wk
V3W/tuXCCwCfb5pdImz6hPrOWVK+iwpjyjoHMKcAn3bUQCJjfw5OudhMXatGpRZi
zuT2nQEyBEf32ZsQBACEuKTo5h8b4B5BcKGPcWQg5gr9/O1Jn9Lx009tRxdD+P35
gJIJqqUT6BrW9+p7sPHoE2xfQCXuGjGZ+a6GDq0NVKB+800nZ7D8lxYMf3PTRJKo
yKWcy4cpVWpAGV/873vwAj/gIvLniCOKp2eGvIIitUGEPHS2T9tbnBG4PcLiPwAE
CwP+N/LVsknAB6ANk0UwBLcGQo0S4k0BRsovKPu8gSU2cFjKqoL4+oUuhTvPE8+6
TlB/IllxJgM/f+2aSTm8O1GEMLUevAppASimypKelU92qlKpSa1aEfeUl8j/Km4I
Cn5CidncImaz9vcJ6gOE9qhNcGIWRM8lm/DLJP1d0GHWT/cAAPoCxapGU51RZRPx
PZ71lUNKzhRWTgEWN7jss/VkiMr8ThBtiE8EGBECAA8FAkf32ZsCGwwFCRLMAwAA
CgkQJ2wkV3W/tuWF9ACeLO7tQ27Qs5VMxUJC5LYmr1gqIZAAoLEbHkF1SlPZid8U
rsAr5z7YF8Iv
=saW/
-----END PGP PRIVATE KEY BLOCK-----
"""
        self.public_keys['mail.c2.invalid'] = """
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.6 (GNU/Linux)

mQGiBEf32ZoRBACbV2/bOd9+L16sRAWCi+6lWzw63BbZDt4BMWuy6o/we2vkCGWd
x/m65KQ2ggTQ+4PMfkRWUXRl2FAnivbM14aQl7GXTnyq9RDTWzWjH19li9iod++J
kPLObg/Zn2ldyjvXGACFzfHIXFrnbqQ3J4Ynzjm/ApHAJPN5DKOl+G3lvwCg3F4T
twWomjwKhwZIcyjlwnevYOMEAJP9wCeSnAD2ph98AM7hvqFzBVY3PR885lQxKsI7
uNSwG+zF5ojb9OlzIp2fvJowYBt6ZfvKSmWxv469hBWLVnX4cWpjgFARPSp2alBt
pQQsz3GkqXYMOAFdzw5oYF1iRYgqc/+XT6okuij3uM9Y3eBykio1taxRhzPhYv6V
gX68A/9a7jdWptetgJDXumK7nqQOVZWp02A+6fMFwS1jfk0oBi+F5tK+9we8t6Js
/rwwEzj8jMCJ+wPJZSw2psguHv/okQQ4996nssFJLkyY5NP2CV7Ja8dRw7Vzj99n
RtD+pcrMgnh8MaGoW4kcDWhAl8rZnjKbq7fnCP4EMyQMnkN1h7RLbm9ib2R5IChE
b24ndCBldmVyIHVzZSB0aGlzIGtleS4gSW50ZXJuYWwgcHVycG9zZXMgb25seS4p
IDxtYWlsLmMyLmludmFsaWQ+iGYEExECACYFAkf32ZoCGyMFCRLMAwAGCwkIBwMC
BBUCCAMEFgIDAQIeAQIXgAAKCRAnbCRXdb+25cILAJ9vml0ibPqE+s5ZUr6LCmPK
OgcwpwCfdtRAImN/Dk652Exdq0alFmLO5Pa5AQ0ER/fZmxAEAIS4pOjmHxvgHkFw
oY9xZCDmCv387Umf0vHTT21HF0P4/fmAkgmqpRPoGtb36nuw8egTbF9AJe4aMZn5
roYOrQ1UoH7zTSdnsPyXFgx/c9NEkqjIpZzLhylVakAZX/zve/ACP+Ai8ueII4qn
Z4a8giK1QYQ8dLZP21ucEbg9wuI/AAQLA/438tWyScAHoA2TRTAEtwZCjRLiTQFG
yi8o+7yBJTZwWMqqgvj6hS6FO88Tz7pOUH8iWXEmAz9/7ZpJObw7UYQwtR68CmkB
KKbKkp6VT3aqUqlJrVoR95SXyP8qbggKfkKJ2dwiZrP29wnqA4T2qE1wYhZEzyWb
8Msk/V3QYdZP94hPBBgRAgAPBQJH99mbAhsMBQkSzAMAAAoJECdsJFd1v7blhfQA
oMIO9PG/z7NV2+ifKgMfZqgbjDZlAKDQCfdGQHZx8aBlQMsTOdbtLRx5iw==
=TtK6
-----END PGP PUBLIC KEY BLOCK-----
"""

    def tearDown(self):
        cmd = 'rm -r %s' % self.gpg.options.homedir
        os.system(cmd)

    def testEncryption(self):
        for key in self.fprs.keys():
            output, log, status = \
                self.gpg.import_keys(self.secret_keys[key])
            self.assertTrue(status.splitlines()[2].endswith('IMPORT_OK 1 %s' %
                self.fprs[key]))
        print self.gpg.encrypt_string('lalala', '0692AE1C51E0DE5F8F20FF7C276C245775BFB6E5')

class ServerTest(TestCase):
    fixtures = ['testdata.json']
    def setUp(self):
        self.servers = Server.objects
        self.accounts = Account.enabled_objects
        self.addresses = Address.enabled_objects
        self.domains = Domain.enabled_objects
        # beware: the order is fixed, the number is fixed. if you change this,
        # you change the tests, too.
        self.test_addresses = [
                'a1@d1.invalid', 
                'a2@d1.invalid',
                'a3@d1.invalid',
                'a1@d2.invalid',
                'a2@d2.invalid',
                'a3@d2.invalid',
                'a1@d1_0.invalid',
                'a2@d1_0.invalid',
                'a3@d1_0.invalid']
        self.test_servers = [
                'mail.c1.invalid',
                'mail.c2.invalid',
                'chat.c1.invalid',
                'chat.c2.invalid']
        self.test_accounts = [
                'acc1_c1',
                'acc2_c1',
                'acc1_c2',
                'acc2_c2',
                'acc1_c1_0',
                'acc2_c1_0']

    def testServername(self):
        for server in self.test_servers:
            self.assertEquals(self.servers.get(name=server).name, server)

    def testServerResponsibility(self):
        s = self.test_servers
        a = self.test_accounts
        true = [
                s[0],
                s[0],
                s[0],
                s[1],
                s[1],
                s[1],
                s[0],
                s[0],
                s[0]]
        false = [
                s[1],
                s[1],
                s[1],
                s[0],
                s[0],
                s[0],
                s[1],
                s[1],
                s[1]]
        for address, server in enumerate(true):
            ad = self.addresses.get_address(self.test_addresses[address])
            self.failUnless(
                    self.servers.get(name=server).responsible_for(ad))
        for address, server in enumerate(false):
            ad = self.addresses.get_address(self.test_addresses[address])
            self.failIf(
                    self.servers.get(name=server).responsible_for(ad))

        true = [[a[0], a[1], a[4], a[5]],
                [a[2], a[3]]]
        false = [[a[2], a[3]],
                [a[0], a[1], a[4], a[5]]]
        for server, accounts in enumerate(true):
            for account in accounts:
                self.failUnless(
                        self.servers.get(name=s[server]).responsible_for(
                            self.accounts.get(name=account)))
        for server, accounts in enumerate(false):
            for account in accounts:
                self.failIf(
                        self.servers.get(name=s[server]).responsible_for(
                            self.accounts.get(name=account)))

    def testAddressCounts(self):
        # <true_recipient_count>, <false_recipient_count>,
        # <true_account_count>, <false_account_count>
        tuples = [
                [2, 3, 0, 1],
                [0, 2, 1, 1],
                [0, 1, 1, 2],
                [2, 3, 0, 5],
                [0, 2, 1, 1],
                [0, 1, 1, 5],
                [2, 3, 0, 1],
                [0, 2, 1, 3],
                [0, 1, 1, 5]]
        for address, tuple in enumerate(tuples):
            self.assertEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).recipient_count,
                    tuple[0])
            self.assertNotEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).recipient_count,
                    tuple[1])
            self.assertEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).account_count,
                    tuple[2])
            self.assertNotEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).account_count,
                    tuple[3])

    def testUidGids(self):
        # <uid>, false, <gid>, false
        tuples = [
                [None, 5001, None, 5001],
                [5001, 5002, 5001, None],
                [5001, 5002, 5001, None],
                [None, 5001, None, 5001],
                [5002, None, 5002, 5003],
                [5002, None, 5002, 5003],
                [None, 5003, None, 5001],
                [5003, None, 5003, 5001],
                [5003, None, 5003, 5001]]
        for address, tuple in enumerate(tuples):
            self.assertEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).uid,
                    tuple[0])
            self.assertNotEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).uid,
                    tuple[1])
            self.assertEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).gid,
                    tuple[2])
            self.assertNotEqual(
                    self.addresses.get_address(
                        self.test_addresses[address]).uid,
                    tuple[3])

    def testAccounts(self):
        a = self.test_accounts
        s = self.test_servers
        # true false
        smtp = [
                [s[0], s[1]],
                [s[0], s[1]],
                [s[1], s[0]],
                [s[1], s[0]],
                [s[0], s[1]],
                [s[0], s[1]]]

        for acc, tuple in enumerate(smtp):
            self.assertEqual(
                    self.accounts.get(
                        name=self.test_accounts[acc]
                        ).smtp_server.name,
                    tuple[0])
            self.assertNotEqual(
                    self.accounts.get(
                        name=self.test_accounts[acc]
                        ).smtp_server.name,
                    tuple[1])
        passwords = [a[0], a[4], a[5]]
        no_passwords = [a[1], a[2], a[3]]

        for account in passwords:
            self.assertTrue(
                    self.accounts.get(name=account).check_password(account))
        for account in no_passwords:
            self.assertFalse(
                    self.accounts.get(name=account).check_password(account))

