From 3fc250018d6db529bbb8cd5aa066dea8482642a4 Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Thu, 13 May 2021 16:13:19 -0700 Subject: [PATCH 1/8] basic implementation of random suffix --- app/config.py | 2 ++ app/dashboard/views/custom_alias.py | 19 ++++++++++++++++--- app/models.py | 5 +++++ app/utils.py | 5 ++++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/config.py b/app/config.py index 4dc11beb..bd501953 100644 --- a/app/config.py +++ b/app/config.py @@ -374,3 +374,5 @@ except Exception: ALIAS_LIMIT = os.environ.get("ALIAS_LIMIT") or "100/day;50/hour;5/minute" ENABLE_SPAM_ASSASSIN = "ENABLE_SPAM_ASSASSIN" in os.environ + +ALIAS_RAND_SUFFIX_LENGTH = int(os.environ.get("ALIAS_RAND_SUFFIX_LENGTH", 5)) \ No newline at end of file diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index b17ac447..5a080a19 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -10,6 +10,7 @@ from app.config import ( DISABLE_ALIAS_SUFFIX, CUSTOM_ALIAS_SECRET, ALIAS_LIMIT, + ALIAS_RAND_SUFFIX_LENGTH, ) from app.dashboard.base import dashboard_bp from app.extensions import db, limiter @@ -23,7 +24,7 @@ from app.models import ( AliasMailbox, DomainDeletedAlias, ) -from app.utils import random_word, word_exist +from app.utils import random_word, word_exist, random_string signer = TimestampSigner(CUSTOM_ALIAS_SECRET) @@ -54,7 +55,7 @@ def get_available_suffixes(user: User) -> [SuffixInfo]: # for each user domain, generate both the domain and a random suffix version for custom_domain in user_custom_domains: if custom_domain.random_prefix_generation: - suffix = "." + random_word() + "@" + custom_domain.domain + suffix = "." + get_suffix(user) + "@" + custom_domain.domain suffix_info = SuffixInfo(True, suffix, signer.sign(suffix).decode(), False) if user.default_alias_custom_domain_id == custom_domain.id: suffixes.insert(0, suffix_info) @@ -77,7 +78,7 @@ def get_available_suffixes(user: User) -> [SuffixInfo]: # then SimpleLogin domain for sl_domain in user.get_sl_domains(): suffix = ( - ("" if DISABLE_ALIAS_SUFFIX else "." + random_word()) + ("" if DISABLE_ALIAS_SUFFIX else "." + get_suffix(user)) + "@" + sl_domain.domain ) @@ -249,6 +250,18 @@ def custom_alias(): mailboxes=mailboxes, ) +def get_suffix(user: User) -> str: + """Get random suffix for an alias based on user's preference. + + Args: + user (User): the user who is trying to create an alias + + Returns: + str: the random suffix generated + """ + if user.random_alias_suffix: + return random_string(ALIAS_RAND_SUFFIX_LENGTH, include_digits = True) + return random_word() def verify_prefix_suffix(user: User, alias_prefix, alias_suffix) -> bool: """verify if user could create an alias with the given prefix and suffix""" diff --git a/app/models.py b/app/models.py index e71ddca5..6ef39f94 100644 --- a/app/models.py +++ b/app/models.py @@ -287,6 +287,11 @@ class User(db.Model, ModelMixin, UserMixin): db.Boolean, default=False, nullable=False, server_default="0" ) + # whether to use random string or random word as suffix + random_alias_suffix = db.Column( + db.Boolean, default=True, nullable=False, server_default="1" + ) + @classmethod def create(cls, email, name="", password=None, **kwargs): user: User = super(User, cls).create(email=email, name=name, **kwargs) diff --git a/app/utils.py b/app/utils.py index 6b9f8312..ee91dd88 100644 --- a/app/utils.py +++ b/app/utils.py @@ -27,9 +27,12 @@ def random_words(): return "_".join([random.choice(_words) for i in range(nb_words)]) -def random_string(length=10): +def random_string(length=10, include_digits=False): """Generate a random string of fixed length """ letters = string.ascii_lowercase + if include_digits: + letters += string.digits + return "".join(random.choice(letters) for _ in range(length)) From 178ce34399c376c1eb1f014683e0ec2b4ab2653a Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Thu, 13 May 2021 16:53:01 -0700 Subject: [PATCH 2/8] Enum, setting --- app/dashboard/templates/dashboard/setting.html | 16 ++++++++++++++++ app/dashboard/views/custom_alias.py | 3 ++- app/dashboard/views/setting.py | 12 +++++++++++- app/models.py | 9 ++++++++- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/dashboard/templates/dashboard/setting.html b/app/dashboard/templates/dashboard/setting.html index 16322884..233915c6 100644 --- a/app/dashboard/templates/dashboard/setting.html +++ b/app/dashboard/templates/dashboard/setting.html @@ -247,6 +247,22 @@ + +
Select the default suffix generator for aliases.
+
+ + + +
+ diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index 5a080a19..d96b7f05 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -23,6 +23,7 @@ from app.models import ( User, AliasMailbox, DomainDeletedAlias, + AliasSuffixEnum, ) from app.utils import random_word, word_exist, random_string @@ -259,7 +260,7 @@ def get_suffix(user: User) -> str: Returns: str: the random suffix generated """ - if user.random_alias_suffix: + if user.random_alias_suffix == AliasSuffixEnum.rnd_string.value: return random_string(ALIAS_RAND_SUFFIX_LENGTH, include_digits = True) return random_word() diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index b4b837d8..3c1f906a 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -15,7 +15,7 @@ from wtforms import StringField, validators from wtforms.fields.html5 import EmailField from app import s3, email_utils -from app.config import URL, FIRST_ALIAS_DOMAIN, JOB_DELETE_ACCOUNT +from app.config import URL, FIRST_ALIAS_DOMAIN, JOB_DELETE_ACCOUNT, ALIAS_RAND_SUFFIX_LENGTH from app.dashboard.base import dashboard_bp from app.email_utils import ( email_can_be_used_as_mailbox, @@ -32,6 +32,7 @@ from app.models import ( Alias, CustomDomain, AliasGeneratorEnum, + AliasSuffixEnum, ManualSubscription, SenderFormatEnum, SLDomain, @@ -240,6 +241,14 @@ def setting(): flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) + elif request.form.get("form-name") == "random-alias-suffix": + scheme = int(request.form.get("random-alias-suffix-generator")) + if AliasSuffixEnum.has_value(scheme): + current_user.random_alias_suffix = scheme + db.session.commit() + flash("Your preference has been updated", "success") + return redirect(url_for("dashboard.setting")) + elif request.form.get("form-name") == "change-sender-format": sender_format = int(request.form.get("sender-format")) if SenderFormatEnum.has_value(sender_format): @@ -292,6 +301,7 @@ def setting(): apple_sub=apple_sub, coinbase_sub=coinbase_sub, FIRST_ALIAS_DOMAIN=FIRST_ALIAS_DOMAIN, + ALIAS_RAND_SUFFIX_LENGTH=ALIAS_RAND_SUFFIX_LENGTH, ) diff --git a/app/models.py b/app/models.py index 6ef39f94..d1fb71f5 100644 --- a/app/models.py +++ b/app/models.py @@ -161,6 +161,9 @@ class AliasGeneratorEnum(EnumE): word = 1 # aliases are generated based on random words uuid = 2 # aliases are generated based on uuid +class AliasSuffixEnum(EnumE): + word = 0 # Random word from dictionary file + rnd_string = 1 # Completely random string class Fido(db.Model, ModelMixin): __tablename__ = "fido" @@ -288,8 +291,12 @@ class User(db.Model, ModelMixin, UserMixin): ) # whether to use random string or random word as suffix + # Random word from dictionary file -> 0 + # Completely random string -> 1 random_alias_suffix = db.Column( - db.Boolean, default=True, nullable=False, server_default="1" + db.Integer, nullable=False, + default=AliasSuffixEnum.rnd_string.value, + server_default=str(AliasSuffixEnum.rnd_string.value), ) @classmethod From 5c74ad2dc02a8563e2364d7b82b8871db5f6dfc8 Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Thu, 13 May 2021 16:55:46 -0700 Subject: [PATCH 3/8] :warning: Remove word list check --- app/dashboard/views/custom_alias.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index d96b7f05..77aab019 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -295,14 +295,6 @@ def verify_prefix_suffix(user: User, alias_prefix, alias_suffix) -> bool: LOG.exception("User %s submits a wrong alias suffix %s", user, alias_suffix) return False - random_word_part = alias_domain_prefix[1:] - if not word_exist(random_word_part): - LOG.exception( - "alias suffix %s needs to start with a random word, user %s", - alias_suffix, - user, - ) - return False else: if alias_domain not in user_custom_domains: if not DISABLE_ALIAS_SUFFIX: From 30183ac8c3f705cac7d834dfe811b96b56ff81bc Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Thu, 13 May 2021 19:29:26 -0700 Subject: [PATCH 4/8] :bug: fix style --- app/config.py | 2 +- app/dashboard/views/custom_alias.py | 6 ++++-- app/dashboard/views/setting.py | 7 ++++++- app/models.py | 5 ++++- app/utils.py | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/config.py b/app/config.py index bd501953..aedffe76 100644 --- a/app/config.py +++ b/app/config.py @@ -375,4 +375,4 @@ ALIAS_LIMIT = os.environ.get("ALIAS_LIMIT") or "100/day;50/hour;5/minute" ENABLE_SPAM_ASSASSIN = "ENABLE_SPAM_ASSASSIN" in os.environ -ALIAS_RAND_SUFFIX_LENGTH = int(os.environ.get("ALIAS_RAND_SUFFIX_LENGTH", 5)) \ No newline at end of file +ALIAS_RAND_SUFFIX_LENGTH = int(os.environ.get("ALIAS_RAND_SUFFIX_LENGTH", 5)) diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index 77aab019..9f737aec 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -25,7 +25,7 @@ from app.models import ( DomainDeletedAlias, AliasSuffixEnum, ) -from app.utils import random_word, word_exist, random_string +from app.utils import random_word, random_string signer = TimestampSigner(CUSTOM_ALIAS_SECRET) @@ -251,6 +251,7 @@ def custom_alias(): mailboxes=mailboxes, ) + def get_suffix(user: User) -> str: """Get random suffix for an alias based on user's preference. @@ -261,9 +262,10 @@ def get_suffix(user: User) -> str: str: the random suffix generated """ if user.random_alias_suffix == AliasSuffixEnum.rnd_string.value: - return random_string(ALIAS_RAND_SUFFIX_LENGTH, include_digits = True) + return random_string(ALIAS_RAND_SUFFIX_LENGTH, include_digits=True) return random_word() + def verify_prefix_suffix(user: User, alias_prefix, alias_suffix) -> bool: """verify if user could create an alias with the given prefix and suffix""" if not alias_prefix or not alias_suffix: # should be caught on frontend diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index 3c1f906a..cfc96d6d 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -15,7 +15,12 @@ from wtforms import StringField, validators from wtforms.fields.html5 import EmailField from app import s3, email_utils -from app.config import URL, FIRST_ALIAS_DOMAIN, JOB_DELETE_ACCOUNT, ALIAS_RAND_SUFFIX_LENGTH +from app.config import ( + URL, + FIRST_ALIAS_DOMAIN, + JOB_DELETE_ACCOUNT, + ALIAS_RAND_SUFFIX_LENGTH, +) from app.dashboard.base import dashboard_bp from app.email_utils import ( email_can_be_used_as_mailbox, diff --git a/app/models.py b/app/models.py index d1fb71f5..d15a523a 100644 --- a/app/models.py +++ b/app/models.py @@ -161,10 +161,12 @@ class AliasGeneratorEnum(EnumE): word = 1 # aliases are generated based on random words uuid = 2 # aliases are generated based on uuid + class AliasSuffixEnum(EnumE): word = 0 # Random word from dictionary file rnd_string = 1 # Completely random string + class Fido(db.Model, ModelMixin): __tablename__ = "fido" credential_id = db.Column(db.String(), nullable=False, unique=True, index=True) @@ -294,7 +296,8 @@ class User(db.Model, ModelMixin, UserMixin): # Random word from dictionary file -> 0 # Completely random string -> 1 random_alias_suffix = db.Column( - db.Integer, nullable=False, + db.Integer, + nullable=False, default=AliasSuffixEnum.rnd_string.value, server_default=str(AliasSuffixEnum.rnd_string.value), ) diff --git a/app/utils.py b/app/utils.py index ee91dd88..d6bcd8d1 100644 --- a/app/utils.py +++ b/app/utils.py @@ -32,7 +32,7 @@ def random_string(length=10, include_digits=False): letters = string.ascii_lowercase if include_digits: letters += string.digits - + return "".join(random.choice(letters) for _ in range(length)) From 4a0fc8380fdcf46f7a1bec3be2f46de0d1d9484b Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Fri, 14 May 2021 11:03:16 -0700 Subject: [PATCH 5/8] variable naming --- app/config.py | 2 +- app/dashboard/templates/dashboard/setting.html | 2 +- app/dashboard/views/custom_alias.py | 6 +++--- app/dashboard/views/setting.py | 4 ++-- app/models.py | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/config.py b/app/config.py index aedffe76..d7eda033 100644 --- a/app/config.py +++ b/app/config.py @@ -375,4 +375,4 @@ ALIAS_LIMIT = os.environ.get("ALIAS_LIMIT") or "100/day;50/hour;5/minute" ENABLE_SPAM_ASSASSIN = "ENABLE_SPAM_ASSASSIN" in os.environ -ALIAS_RAND_SUFFIX_LENGTH = int(os.environ.get("ALIAS_RAND_SUFFIX_LENGTH", 5)) +ALIAS_RANDOM_SUFFIX_LENGTH = int(os.environ.get("ALIAS_RAND_SUFFIX_LENGTH", 5)) diff --git a/app/dashboard/templates/dashboard/setting.html b/app/dashboard/templates/dashboard/setting.html index 233915c6..410bf7ef 100644 --- a/app/dashboard/templates/dashboard/setting.html +++ b/app/dashboard/templates/dashboard/setting.html @@ -248,7 +248,7 @@ -
Select the default suffix generator for aliases.
+
Select the default suffix generator for aliases.