diff --git a/seed/dovecot/applicationservice.yml b/seed/dovecot/applicationservice.yml
index eddfd28..5f39c6d 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 696623d..084e5e4 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 0000000..1836ec5
--- /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 0000000..7fa666b
--- /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()