From e52f2ca6deab2f4d07c049b40cac0c9daab91a72 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Sun, 3 May 2020 16:50:39 +0200 Subject: [PATCH] Support multiple mailboxes in custom alias page --- .../templates/dashboard/custom_alias.html | 28 ++++++++++--- app/dashboard/views/custom_alias.py | 34 +++++++++++---- tests/dashboard/test_custom_alias.py | 41 +++++++++++++++++-- 3 files changed, 86 insertions(+), 17 deletions(-) diff --git a/app/dashboard/templates/dashboard/custom_alias.html b/app/dashboard/templates/dashboard/custom_alias.html index edb7d9af..a4fed99a 100644 --- a/app/dashboard/templates/dashboard/custom_alias.html +++ b/app/dashboard/templates/dashboard/custom_alias.html @@ -56,15 +56,16 @@
- {% for mailbox in mailboxes %} - {% endfor %}
- The mailbox that owns this alias. + The mailbox(es) that owns this alias.
@@ -81,7 +82,7 @@
- + Create
@@ -89,3 +90,20 @@ {% endblock %} +{% block script %} + +{% endblock %} + diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index f9dc55a1..2828a23f 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -11,7 +11,7 @@ from app.dashboard.base import dashboard_bp from app.email_utils import email_belongs_to_alias_domains from app.extensions import db from app.log import LOG -from app.models import Alias, CustomDomain, DeletedAlias, Mailbox, User +from app.models import Alias, CustomDomain, DeletedAlias, Mailbox, User, AliasMailbox from app.utils import convert_to_id, random_word, word_exist signer = TimestampSigner(CUSTOM_ALIAS_SECRET) @@ -54,20 +54,30 @@ def custom_alias(): # List of (is_custom_domain, alias-suffix, time-signed alias-suffix) suffixes = available_suffixes(current_user) - mailboxes = [mb.email for mb in current_user.mailboxes()] + mailboxes = current_user.mailboxes() if request.method == "POST": alias_prefix = request.form.get("prefix") signed_suffix = request.form.get("suffix") - mailbox_email = request.form.get("mailbox") + mailbox_ids = request.form.getlist("mailboxes") alias_note = request.form.get("note") # check if mailbox is not tempered with - if mailbox_email != current_user.email: - mailbox = Mailbox.get_by(email=mailbox_email, user_id=current_user.id) - if not mailbox or mailbox.user_id != current_user.id: + mailboxes = [] + for mailbox_id in mailbox_ids: + mailbox = Mailbox.get(mailbox_id) + if ( + not mailbox + or mailbox.user_id != current_user.id + or not mailbox.verified + ): flash("Something went wrong, please retry", "warning") return redirect(url_for("dashboard.custom_alias")) + mailboxes.append(mailbox) + + if not mailboxes: + flash("At least one mailbox must be selected", "error") + return redirect(url_for("dashboard.custom_alias")) # hypothesis: user will click on the button in the 600 secs try: @@ -91,14 +101,20 @@ def custom_alias(): "warning", ) else: - mailbox = Mailbox.get_by(email=mailbox_email, user_id=current_user.id) - alias = Alias.create( user_id=current_user.id, email=full_alias, note=alias_note, - mailbox_id=mailbox.id, + mailbox_id=mailboxes[0].id, ) + db.session.flush() + + for i in range(1, len(mailboxes)): + AliasMailbox.create( + user_id=alias.user_id, + alias_id=alias.id, + mailbox_id=mailboxes[i].id, + ) # get the custom_domain_id if alias is created with a custom domain if alias_suffix.startswith("@"): diff --git a/tests/dashboard/test_custom_alias.py b/tests/dashboard/test_custom_alias.py index 3e189c3b..1708c9d7 100644 --- a/tests/dashboard/test_custom_alias.py +++ b/tests/dashboard/test_custom_alias.py @@ -7,7 +7,7 @@ from app.dashboard.views.custom_alias import ( available_suffixes, ) from app.extensions import db -from app.models import Mailbox, CustomDomain +from app.models import Mailbox, CustomDomain, Alias from app.utils import random_word from tests.utils import login @@ -20,15 +20,50 @@ def test_add_alias_success(flask_client): suffix = f".{word}@{EMAIL_DOMAIN}" suffix = signer.sign(suffix).decode() + # create with a single mailbox r = flask_client.post( url_for("dashboard.custom_alias"), - data={"prefix": "prefix", "suffix": suffix, "mailbox": user.email,}, + data={ + "prefix": "prefix", + "suffix": suffix, + "mailboxes": [user.default_mailbox_id], + }, follow_redirects=True, ) - assert r.status_code == 200 assert f"Alias prefix.{word}@{EMAIL_DOMAIN} has been created" in str(r.data) + alias = Alias.query.order_by(Alias.created_at.desc()).first() + assert not alias._mailboxes + + +def test_add_alias_multiple_mailboxes(flask_client): + user = login(flask_client) + db.session.commit() + + word = random_word() + suffix = f".{word}@{EMAIL_DOMAIN}" + suffix = signer.sign(suffix).decode() + + # create with a multiple mailboxes + mb1 = Mailbox.create(user_id=user.id, email="m1@example.com", verified=True) + db.session.commit() + + r = flask_client.post( + url_for("dashboard.custom_alias"), + data={ + "prefix": "prefix", + "suffix": suffix, + "mailboxes": [user.default_mailbox_id, mb1.id], + }, + follow_redirects=True, + ) + assert r.status_code == 200 + assert f"Alias prefix.{word}@{EMAIL_DOMAIN} has been created" in str(r.data) + + alias = Alias.query.order_by(Alias.created_at.desc()).first() + assert alias._mailboxes + def test_not_show_unverified_mailbox(flask_client): """make sure user unverified mailbox is not shown to user"""