From c969e6919a61d4fbca472ececb299b21b6ae4cd8 Mon Sep 17 00:00:00 2001 From: Son NK Date: Wed, 22 Jan 2020 00:03:25 +0100 Subject: [PATCH] Use the same design as on extension for custom alias: domains are presented in a dropdown list --- .../templates/dashboard/custom_alias.html | 97 ++++------- app/dashboard/views/custom_alias.py | 157 +++++++++--------- 2 files changed, 109 insertions(+), 145 deletions(-) diff --git a/app/dashboard/templates/dashboard/custom_alias.html b/app/dashboard/templates/dashboard/custom_alias.html index a3dd7126..9c3e80e6 100644 --- a/app/dashboard/templates/dashboard/custom_alias.html +++ b/app/dashboard/templates/dashboard/custom_alias.html @@ -9,82 +9,47 @@ {% block default_content %}
-

New Email Alias

- {% if error %} -
{{ error }}
+

New Email Alias

+ + {% if user_custom_domains|length == 0 %} + {% endif %}
- - -
- {% if custom_domains %} -
-
With SimpleLogin domain
-
- {% endif %} - -
-
- -
-
- -

- {{ email_suffix }}@{{ EMAIL_DOMAIN }} -

-
+
+
+
-
-
- Hint - You can use the name of the website that you plan to use the alias on here.
- This way you can remember where the alias is used. -
+
+ {% if suffixes|length > 1 %} + + {% else %} + {{ suffixes[0] }} + {% endif %}
+
-
- -
- +
+
- - {% if custom_domains %} -
-

Or with your custom domains

-
- {% for custom_domain in custom_domains %} -
- - - -
-
- -
- - @{{ custom_domain.domain }} - -
-
- -
- -
-
- - -
- {% endfor %} -
- {% endif %}
{% endblock %} diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index 8ea9cb73..1965e2f9 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -1,5 +1,7 @@ from flask import render_template, redirect, url_for, flash, request, session from flask_login import login_required, current_user +from flask_wtf import FlaskForm +from wtforms import StringField, validators, SelectField from app.config import EMAIL_DOMAIN, HIGHLIGHT_GEN_EMAIL_ID, DISABLE_ALIAS_SUFFIX from app.dashboard.base import dashboard_bp @@ -12,96 +14,93 @@ from app.utils import convert_to_id, random_word, word_exist @dashboard_bp.route("/custom_alias", methods=["GET", "POST"]) @login_required def custom_alias(): - # check if user has the right to create custom alias + # check if user has not exceeded the alias quota if not current_user.can_create_new_alias(): # notify admin LOG.error("user %s tries to create custom alias", current_user) flash("ony premium user can choose custom alias", "warning") return redirect(url_for("dashboard.index")) - error = "" + user_custom_domains = [cd.domain for cd in current_user.verified_custom_domains()] + suffixes = [] + + # put custom domain first + for alias_domain in user_custom_domains: + suffixes.append("@" + alias_domain) + + # then default domain + suffixes.append( + ("" if DISABLE_ALIAS_SUFFIX else ".") + random_word() + "@" + EMAIL_DOMAIN + ) if request.method == "POST": - if request.form.get("form-name") == "non-custom-domain-name": - email_prefix = request.form.get("email-prefix") - email_prefix = convert_to_id(email_prefix) - email_suffix = request.form.get("email-suffix") + alias_prefix = request.form.get("prefix") + alias_suffix = request.form.get("suffix") - # verify email_suffix: do not verify when DISABLE_ALIAS_SUFFIX is set - if not DISABLE_ALIAS_SUFFIX: - # email suffix must be in the format ".{word}" - if email_suffix[0] != "." or not word_exist(email_suffix[1:]): - flash( - "nice try :). The suffix is there so no one can take all the *nice* aliases though", - "warning", - ) - return redirect(url_for("dashboard.custom_alias")) - - if not email_prefix: - error = "alias prefix cannot be empty" - else: - full_email = f"{email_prefix}{email_suffix}@{EMAIL_DOMAIN}" - # check if email already exists - if GenEmail.get_by(email=full_email) or DeletedAlias.get_by( - email=full_email - ): - error = "email already chosen, please choose another one" - else: - # create the new alias - LOG.d( - "create custom alias %s for user %s", full_email, current_user - ) - gen_email = GenEmail.create( - email=full_email, user_id=current_user.id - ) - db.session.commit() - - flash(f"Alias {full_email} has been created", "success") - session[HIGHLIGHT_GEN_EMAIL_ID] = gen_email.id - - return redirect(url_for("dashboard.index")) - elif request.form.get("form-name") == "custom-domain-name": - custom_domain_id = request.form.get("custom-domain-id") - email = request.form.get("email").lower() - - custom_domain = CustomDomain.get(custom_domain_id) - - if not custom_domain: - flash("Unknown error. Refresh the page", "warning") - return redirect(url_for("dashboard.custom_alias")) - elif custom_domain.user_id != current_user.id: - flash("Unknown error. Refresh the page", "warning") - return redirect(url_for("dashboard.custom_alias")) - elif not custom_domain.verified: - flash("Unknown error. Refresh the page", "warning") - return redirect(url_for("dashboard.custom_alias")) - - full_email = f"{email}@{custom_domain.domain}" - - if GenEmail.get_by(email=full_email): - error = f"{full_email} already exist, please choose another one" - else: - LOG.d( - "create custom alias %s for custom domain %s", - full_email, - custom_domain.domain, - ) - gen_email = GenEmail.create( - email=full_email, - user_id=current_user.id, - custom_domain_id=custom_domain.id, + if verify_prefix_suffix( + current_user, alias_prefix, alias_suffix, user_custom_domains + ): + full_alias = alias_prefix + alias_suffix + if GenEmail.get_by(email=full_alias): + LOG.d("full alias already used %s", full_alias) + flash( + f"Alias {full_alias} already exists, please choose another one", + "warning", ) + else: + gen_email = GenEmail.create(user_id=current_user.id, email=full_alias) db.session.commit() - flash(f"Alias {full_email} has been created", "success") + flash(f"Alias {full_alias} has been created", "success") session[HIGHLIGHT_GEN_EMAIL_ID] = gen_email.id - return redirect(url_for("dashboard.index")) - email_suffix = "" if DISABLE_ALIAS_SUFFIX else "." + random_word() - return render_template( - "dashboard/custom_alias.html", - error=error, - email_suffix=email_suffix, - EMAIL_DOMAIN=EMAIL_DOMAIN, - custom_domains=current_user.verified_custom_domains(), - ) + return redirect(url_for("dashboard.index")) + # only happen if the request has been "hacked" + else: + flash("something went wrong", "warning") + + return render_template("dashboard/custom_alias.html", **locals()) + + +def verify_prefix_suffix(user, alias_prefix, alias_suffix, user_custom_domains) -> bool: + """verify if user could create an alias with the given prefix and suffix""" + alias_prefix = alias_prefix.strip() + alias_prefix = convert_to_id(alias_prefix) + if not alias_prefix: # should be caught on frontend + return False + + # make sure alias_suffix is either .random_word@simplelogin.co or @my-domain.com + alias_suffix = alias_suffix.strip() + if alias_suffix.startswith("@"): + alias_domain = alias_suffix[1:] + # alias_domain can be either custom_domain or if DISABLE_ALIAS_SUFFIX, EMAIL_DOMAIN + if DISABLE_ALIAS_SUFFIX: + if alias_domain not in user_custom_domains and alias_domain != EMAIL_DOMAIN: + LOG.error("wrong alias suffix %s, user %s", alias_suffix, user) + return False + else: + if alias_domain not in user_custom_domains: + LOG.error("wrong alias suffix %s, user %s", alias_suffix, user) + return False + else: + if not alias_suffix.startswith("."): + LOG.error("User %s submits a wrong alias suffix %s", user, alias_suffix) + return False + if not alias_suffix.endswith(EMAIL_DOMAIN): + LOG.error( + "Alias suffix should end with default alias domain %s", + user, + alias_suffix, + ) + return False + + random_word_part = alias_suffix[1 : alias_suffix.find("@")] + if not word_exist(random_word_part): + LOG.error( + "alias suffix %s needs to start with a random word, user %s", + alias_suffix, + user, + ) + return False + + return True