Skip to content

Commit

Permalink
Improved testing on mailbox, fix various bugs in POST/GET mailbox
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Bayart committed Jul 4, 2024
1 parent 2708249 commit d909d46
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 18 deletions.
3 changes: 1 addition & 2 deletions src/routes/mailboxes/get_mailboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ async def get_mailboxes(
ox_cluster = oxcli.OxCluster()
ctx = ox_cluster.get_context_by_domain(domain_name)
if ctx is None:
log.error(f"Le domaine {domain_name} est inconnu du cluster OX")
raise Exception("Le domaine est connu de la base API, mais pas de OX")
log.info(f"Le domaine {domain_name} est inconnu du cluster OX")

ox_users = []
if ctx:
Expand Down
29 changes: 16 additions & 13 deletions src/routes/mailboxes/post_mailbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import fastapi

from ... import auth, oxcli, sql_dovecot, web_models
from ... import auth, oxcli, sql_api, sql_dovecot, web_models
from .. import dependencies, routers


Expand All @@ -17,6 +17,7 @@ async def post_mailbox(
mailbox: web_models.CreateMailbox,
user: auth.DependsTokenUser,
db: dependencies.DependsDovecotDb,
db_api: dependencies.DependsApiDb,
user_name: str,
domain_name: str,
) -> web_models.NewMailbox:
Expand All @@ -27,18 +28,20 @@ async def post_mailbox(
log.info(f"Cet utilisateur ne peut pas traiter le domaine {domain_name}")
raise fastapi.HTTPException(status_code=403, detail="Permisison denied")

ox_cluster = oxcli.OxCluster()
ctx = ox_cluster.get_context_by_domain(domain_name)
if ctx is None:
log.info(f"Le domaine {domain_name} est inconnu du cluster OX")
raise Exception("Le domaine est connu de la base API, mais pas de OX")

ctx.create_user(
givenName=mailbox.givenName,
surName=mailbox.surName,
username=user_name,
domain=domain_name,
)
domain = sql_api.get_domain(db_api, domain_name)
if domain.has_feature(web_models.Feature.Webmail):
ox_cluster = oxcli.OxCluster()
ctx = ox_cluster.get_context_by_domain(domain_name)
if ctx is None:
log.error(f"Le domaine {domain_name} est inconnu du cluster OX")
raise Exception("Le domaine est connu de la base API, mais pas de OX")

ctx.create_user(
givenName=mailbox.givenName,
surName=mailbox.surName,
username=user_name,
domain=domain_name,
)

password = secrets.token_urlsafe(12)
imap_user = sql_dovecot.create_user(db, user_name, domain_name, password)
Expand Down
91 changes: 88 additions & 3 deletions src/routes/test_mailbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from .. import sql_dovecot


# Dans la première serie de tests, on travaille sur un domaine avec le webmail.

@pytest.mark.parametrize(
"normal_user",
["bidibule:toto"],
Expand All @@ -14,7 +16,7 @@
["tutu.net:dimail"],
indirect=True,
)
def test_create_mailbox(client, normal_user, domain_web, db_dovecot_session):
def test_with_webmail(client, normal_user, domain_web, db_dovecot_session):
token = normal_user["token"]
domain_name = domain_web["name"]

Expand Down Expand Up @@ -53,11 +55,11 @@ def test_create_mailbox(client, normal_user, domain_web, db_dovecot_session):
# les tests. On a aussi besoin de définir ce que c'est que l'uuid d'une
# mailbox, parce que ce n'est pas clair pour l'instant...
got = response.json()
assert got["email"] == "address@tutu.net"
assert got["email"] == f"address@{domain_name}"
# assert got["uuid"] == something smart here :)

# Check the password is properly encoded in dovecot database
imap_user = sql_dovecot.get_user(db_dovecot_session, "address", "tutu.net")
imap_user = sql_dovecot.get_user(db_dovecot_session, "address", domain_name)
assert isinstance(imap_user, sql_dovecot.ImapUser)
assert imap_user.check_password(got["password"])

Expand Down Expand Up @@ -88,3 +90,86 @@ def test_create_mailbox(client, normal_user, domain_web, db_dovecot_session):
emails = [ json[0]["email"], json[1]["email"] ]
assert f"address@{domain_name}" in emails



@pytest.mark.parametrize(
"normal_user",
["bidibule:toto"],
indirect=True,
)
@pytest.mark.parametrize(
"domain_mail",
["tutu.org"],
indirect=True,
)
def test_without_webmail(client, normal_user, domain_mail, db_dovecot_session):
token = normal_user["token"]
domain_name = domain_mail["name"]

# On obtient un 404 sur une mailbox qui n'existe pas
response = client.get(
f"/domains/{domain_name}/mailboxes/address",
headers={"Authorization": f"Bearer {token}"},
)
assert response.status_code == fastapi.status.HTTP_404_NOT_FOUND

# On get toutes les boites du domaine, on doit remonter une liste vide
# (pas de webmail, donc pas de boite oxadmin, puisque pas de ox)
response = client.get(
f"/domains/{domain_name}/mailboxes/",
headers={"Authorization": f"Bearer {token}"},
)
assert response.status_code == fastapi.status.HTTP_200_OK
json = response.json()
assert len(json) == 0

# On crée la mailbox qui n'existait pas à la ligne précédente
response = client.post(
f"/domains/{domain_name}/mailboxes/address",
json={
"givenName": "",
"surName": "",
"displayName": "",
},
headers={"Authorization": f"Bearer {token}"},
)
assert response.status_code == fastapi.status.HTTP_201_CREATED
# FIXME On a besoin de rendre prédictible les uuid qu'on génère pendant
# les tests. On a aussi besoin de définir ce que c'est que l'uuid d'une
# mailbox, parce que ce n'est pas clair pour l'instant...
got = response.json()
assert got["email"] == f"address@{domain_name}"
# assert got["uuid"] == something smart here :)

# Check the password is properly encoded in dovecot database
imap_user = sql_dovecot.get_user(db_dovecot_session, "address", domain_name)
assert isinstance(imap_user, sql_dovecot.ImapUser)
assert imap_user.check_password(got["password"])

# On refait un GET sur la boîte qu'on vient de créer
response = client.get(
f"/domains/{domain_name}/mailboxes/address",
headers={"Authorization": f"Bearer {token}"},
)
assert response.status_code == fastapi.status.HTTP_200_OK
assert response.json() == {
"type": "mailbox",
"status": "broken",
"email": f"address@{domain_name}",
"surName": None,
"givenName": None,
"displayName": None,
}

# On get toutes les boites du domaine, on doit remonter notre
# boite neuve
response = client.get(
f"/domains/{domain_name}/mailboxes/",
headers={"Authorization": f"Bearer {token}"},
)
assert response.status_code == fastapi.status.HTTP_200_OK
json = response.json()
assert len(json) == 1
assert json[0]["email"] == f"address@{domain_name}"


3 changes: 3 additions & 0 deletions src/sql_api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class DBDomain(Api):
secondary="allowed", back_populates="domains"
)

def has_feature(self, feature: str) -> bool:
return feature in self.features


class DBAllowed(Api):
__tablename__ = "allowed"
Expand Down

0 comments on commit d909d46

Please sign in to comment.