diff --git a/seed/dovecot/applicationservice.yml b/seed/dovecot/applicationservice.yml index eddfd288..5f39c6dd 100644 --- a/seed/dovecot/applicationservice.yml +++ b/seed/dovecot/applicationservice.yml @@ -1,7 +1,7 @@ format: '0.1' description: Postfix et Dovecot depends: - - base-fedora-35 + - base-fedora-36 - relay-mail-client - ldap-client-fedora - oauth2-client diff --git a/seed/dovecot/dictionaries/26_dovecot.xml b/seed/dovecot/dictionaries/26_dovecot.xml index 696623de..084e5e43 100644 --- a/seed/dovecot/dictionaries/26_dovecot.xml +++ b/seed/dovecot/dictionaries/26_dovecot.xml @@ -47,6 +47,7 @@ /etc/pki/tls/private/dovecot.key external_imap_crt external_imap_key + /tests/imap.yml diff --git a/seed/dovecot/templates/imap.yml b/seed/dovecot/templates/imap.yml new file mode 100644 index 00000000..1836ec5e --- /dev/null +++ b/seed/dovecot/templates/imap.yml @@ -0,0 +1,10 @@ +%set %%username="rougail_test@silique.fr" +%set %%username_family="rougail_test@gnunux.info" +%set %%name_family="gnunux" +address: %%ip_eth0 +dns: %%domain_name_eth0 +username: %%username +password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True) +username_family: %%username_family +password_family: %%get_password(server_name=%%ldap_server_address, username=%%username_family, description="ldap family user", type="cleartext", hide=%%hide_secret, temporary=True) +name_family: %%name_family diff --git a/seed/dovecot/tests/test_imap.py b/seed/dovecot/tests/test_imap.py new file mode 100644 index 00000000..7fa666bb --- /dev/null +++ b/seed/dovecot/tests/test_imap.py @@ -0,0 +1,131 @@ +from yaml import load, SafeLoader +from os import environ +from os.path import isdir +import pytest + +from imaplib2 import IMAP4_SSL +from smtplib import SMTP, SMTPNotSupportedError, SMTPAuthenticationError + + + +conf_file = f'{environ["MACHINE_TEST_DIR"]}/imap.yml' +with open(conf_file) as yaml: + data = load(yaml, Loader=SafeLoader) +parameters = (('user', data['username'], data['password']), + ('family', data['username_family'], data['password_family']), + ) + + +def get_msg(username, msg='MESSAGE'): + return f'From: {username}\r\nTo: {username}\r\n\r\nSubject: TEST\r\n{msg}\r\n' + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_imap_wrong_password(typ, username, password): + imap = IMAP4_SSL(data['address']) + try: + imap.LOGIN(username, 'b') + except: + pass + else: + raise Exception('wrong login !') + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_imap_migration(typ, username, password): + if typ == 'family': + dirname = f'/var/lib/risotto/srv/{data["dns"]}/home/families/{data["name_family"]}/{username}' + else: + dirname = f'/var/lib/risotto/srv/{data["dns"]}/home/users/{username}' + msg = get_msg(username, 'MIGRATION') + if not isdir(dirname): + smtp = SMTP(data['address'], '587') + smtp.starttls() + smtp.login(username, password) + smtp.sendmail(username, username, msg) + smtp.quit() + imap = IMAP4_SSL(data['address']) + imap.LOGIN(username, password) + imap.SELECT(readonly=True) + typ, req = imap.SEARCH(None, 'ALL') + assert typ == 'OK' + assert len(req) == 1 + assert req[0] == b'1' + field = imap.FETCH('1', '(RFC822)') + assert field[0] == 'OK' + assert field[1][-2][-1].decode().endswith(msg) + imap.CLOSE() + imap.LOGOUT() + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_smtp_no_tls(typ, username, password): + smtp = SMTP(data['address'], '587') + try: + smtp.login(username, password) + raise Exception('no tls!') + except SMTPNotSupportedError: + pass + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_smtp_wrong_passwd(typ, username, password): + smtp = SMTP(data['address'], '587') + smtp.starttls() + try: + smtp.login(username, 'a') + raise Exception('wrong password!') + except SMTPAuthenticationError: + pass + smtp.quit() + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_smtp_login(typ, username, password): + smtp = SMTP(data['address'], '587') + smtp.starttls() + smtp.login(username, password) + smtp.quit() + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_smtp_sendmail(typ, username, password): + smtp = SMTP(data['address'], '587') + smtp.starttls() + smtp.login(username, password) + smtp.sendmail(username, username, get_msg(username)) + smtp.quit() + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_imap_read_mail(typ, username, password): + imap = IMAP4_SSL(data['address']) + imap.LOGIN(username, password) + imap.SELECT(readonly=True) + typ, req = imap.SEARCH(None, 'ALL') + assert typ == 'OK' + assert len(req) == 1 + msg = get_msg(username) + msg_no = req[0].split() + assert len(msg_no) == 2 + for num in msg_no[1:]: + field = imap.FETCH(num, '(RFC822)') + assert field[0] == 'OK' + assert field[1][-2][-1].decode().endswith(msg) + imap.CLOSE() + imap.LOGOUT() + + +@pytest.mark.parametrize('typ, username, password', parameters) +def test_imap_delete_mail(typ, username, password): + imap = IMAP4_SSL(data['address']) + imap.LOGIN(username, password) + imap.SELECT() + typ, req = imap.SEARCH(None, 'ALL') + msg_no = req[0].split() + for num in msg_no[1:]: + ret = imap.store(num, '+FLAGS', '\\Deleted') + assert ret[0] == 'OK', f'error when deleting mail: {ret}' + imap.expunge() + imap.CLOSE() + imap.LOGOUT()