From 88ddca54c106a8a4185c8365adeea04cbf48fc08 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Sat, 25 Apr 2020 23:13:05 +0200 Subject: [PATCH 1/3] return mailbox in GET /api/v2/aliases --- README.md | 11 +++++++++++ app/api/serializer.py | 5 +++++ tests/api/test_alias.py | 41 ++++++++++++++++++++++++----------------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d0f13a5f..c0d2934f 100644 --- a/README.md +++ b/README.md @@ -852,6 +852,9 @@ If success, 200 with the list of aliases. Each alias has the following fields: - nb_block - nb_forward - nb_reply +- mailbox + - id + - email - (optional) latest_activity: - action: forward|reply|block|bounced - timestamp @@ -871,6 +874,10 @@ Here's an example: "email": "prefix1.cat@sl.local", "enabled": true, "id": 3, + "mailbox": { + "email": "a@b.c", + "id": 1 + }, "latest_activity": { "action": "forward", "contact": { @@ -891,6 +898,10 @@ Here's an example: "email": "prefix0.hey@sl.local", "enabled": true, "id": 2, + "mailbox": { + "email": "a@b.c", + "id": 1 + }, "latest_activity": { "action": "forward", "contact": { diff --git a/app/api/serializer.py b/app/api/serializer.py index f02c4dc8..104b8225 100644 --- a/app/api/serializer.py +++ b/app/api/serializer.py @@ -51,6 +51,11 @@ def serialize_alias_info_v2(alias_info: AliasInfo) -> dict: "nb_forward": alias_info.nb_forward, "nb_block": alias_info.nb_blocked, "nb_reply": alias_info.nb_reply, + # mailbox + "mailbox": { + "id": alias_info.mailbox.id, + "email": alias_info.mailbox.email + } } if alias_info.latest_email_log: email_log = alias_info.latest_email_log diff --git a/tests/api/test_alias.py b/tests/api/test_alias.py index 5ada525f..f8eab894 100644 --- a/tests/api/test_alias.py +++ b/tests/api/test_alias.py @@ -150,24 +150,28 @@ def test_get_aliases_v2(flask_client): r0 = r.json["aliases"][0] # r0 will have the following format # { - # "creation_date": "2020-04-06 17:52:47+00:00", - # "creation_timestamp": 1586195567, - # "email": "prefix1.hey@sl.local", - # "enabled": true, - # "id": 3, - # "latest_activity": { - # "action": "forward", - # "contact": { - # "email": "c1@example.com", - # "name": null, - # "reverse_alias": "\"c1 at example.com\" " + # "creation_date": "2020-04-25 21:10:01+00:00", + # "creation_timestamp": 1587849001, + # "email": "prefix1.yeah@sl.local", + # "enabled": true, + # "id": 3, + # "latest_activity": { + # "action": "forward", + # "contact": { + # "email": "c1@example.com", + # "name": null, + # "reverse_alias": "\"c1 at example.com\" " + # }, + # "timestamp": 1587849001 # }, - # "timestamp": 1586195567 - # }, - # "nb_block": 0, - # "nb_forward": 1, - # "nb_reply": 0, - # "note": null + # "mailbox": { + # "email": "a@b.c", + # "id": 1 + # }, + # "nb_block": 0, + # "nb_forward": 1, + # "nb_reply": 0, + # "note": null # } assert r0["email"].startswith("prefix1") assert r0["latest_activity"]["action"] == "forward" @@ -177,6 +181,9 @@ def test_get_aliases_v2(flask_client): assert "name" in r0["latest_activity"]["contact"] assert "reverse_alias" in r0["latest_activity"]["contact"] + assert "id" in r0["mailbox"] + assert "email" in r0["mailbox"] + def test_delete_alias(flask_client): user = User.create( From a422f3332389a62879f3c76a1fe0250f939dedf8 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Sat, 25 Apr 2020 23:40:40 +0200 Subject: [PATCH 2/3] Add GET /api/mailboxes --- README.md | 24 ++++++++++++++++++++++++ app/api/serializer.py | 5 +---- app/api/views/alias.py | 21 +++++++++++++++++++++ tests/api/test_alias.py | 25 +++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c0d2934f..601bbc91 100644 --- a/README.md +++ b/README.md @@ -831,6 +831,30 @@ Input: Output: always return 200, even if email doesn't exist. User need to enter correctly their email. +#### GET /api/mailboxes + +Get user verified mailboxes. + +Input: +- `Authentication` header that contains the api key + +Output: +List of mailboxes. Each mailbox has id, email field. + +```json +{ + "mailboxes": [ + { + "email": "a@b.c", + "id": 1 + }, + { + "email": "m1@example.com", + "id": 2 + } + ] +} +``` #### GET /api/v2/aliases diff --git a/app/api/serializer.py b/app/api/serializer.py index 104b8225..edd0dfc2 100644 --- a/app/api/serializer.py +++ b/app/api/serializer.py @@ -52,10 +52,7 @@ def serialize_alias_info_v2(alias_info: AliasInfo) -> dict: "nb_block": alias_info.nb_blocked, "nb_reply": alias_info.nb_reply, # mailbox - "mailbox": { - "id": alias_info.mailbox.id, - "email": alias_info.mailbox.email - } + "mailbox": {"id": alias_info.mailbox.id, "email": alias_info.mailbox.email}, } if alias_info.latest_email_log: email_log = alias_info.latest_email_log diff --git a/app/api/views/alias.py b/app/api/views/alias.py index e89b2895..b407d57d 100644 --- a/app/api/views/alias.py +++ b/app/api/views/alias.py @@ -117,6 +117,27 @@ def get_aliases_v2(): ) +@api_bp.route("/mailboxes", methods=["GET"]) +@cross_origin() +@require_api_auth +def get_mailboxes(): + """ + Get mailboxes + Output: + - mailboxes: list of alias: + - id + - email + """ + user = g.user + + return ( + jsonify( + mailboxes=[{"id": mb.id, "email": mb.email} for mb in user.mailboxes()] + ), + 200, + ) + + @api_bp.route("/aliases/", methods=["DELETE"]) @cross_origin() @require_api_auth diff --git a/tests/api/test_alias.py b/tests/api/test_alias.py index f8eab894..7229f301 100644 --- a/tests/api/test_alias.py +++ b/tests/api/test_alias.py @@ -480,3 +480,28 @@ def test_get_alias(flask_client): assert "nb_reply" in res assert "enabled" in res assert "note" in res + + +def test_get_mailboxes(flask_client): + user = User.create( + email="a@b.c", password="password", name="Test User", activated=True + ) + db.session.commit() + + # create api_key + api_key = ApiKey.create(user.id, "for test") + db.session.commit() + + Mailbox.create(user_id=user.id, email="m1@example.com", verified=True) + Mailbox.create(user_id=user.id, email="m2@example.com", verified=False) + db.session.commit() + + r = flask_client.get( + url_for("api.get_mailboxes"), headers={"Authentication": api_key.code}, + ) + assert r.status_code == 200 + # m2@example.com is not returned as it's not verified + assert r.json == { + "mailboxes": [{"email": "a@b.c", "id": 1}, {"email": "m1@example.com", "id": 2}] + } + print(json.dumps(r.json, indent=2)) From 182f01f775c35aed72f32cca94a8198c345ff679 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Sat, 25 Apr 2020 23:41:54 +0200 Subject: [PATCH 3/3] More diverse fake data --- server.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/server.py b/server.py index 736e155a..540d7ee4 100644 --- a/server.py +++ b/server.py @@ -51,6 +51,8 @@ from app.models import ( Directory, Mailbox, DeletedAlias, + Contact, + EmailLog, ) from app.monitor.base import monitor_bp from app.oauth.base import oauth_bp @@ -160,12 +162,25 @@ def fake_data(): m1 = Mailbox.create(user_id=user.id, email="m1@cd.ef", verified=True) db.session.commit() - Alias.create_new(user, "e1@", mailbox_id=m1.id) for i in range(30): if i % 2 == 0: - Alias.create_new(user, f"e{i}@", mailbox_id=m1.id) + a = Alias.create_new(user, f"e{i}@", mailbox_id=m1.id) else: - Alias.create_new(user, f"e{i}@") + a = Alias.create_new(user, f"e{i}@") + db.session.commit() + + # some aliases don't have any activity + if i % 3 != 0: + contact = Contact.create( + user_id=user.id, + alias_id=a.id, + website_email=f"contact{i}@example.com", + reply_email=f"rep{i}@sl.local", + ) + db.session.commit() + for _ in range(3): + EmailLog.create(user_id=user.id, contact_id=contact.id) + db.session.commit() CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create(