diff --git a/app/auth/views/facebook.py b/app/auth/views/facebook.py index c552cba6..7e5e03a0 100644 --- a/app/auth/views/facebook.py +++ b/app/auth/views/facebook.py @@ -11,6 +11,7 @@ from app.extensions import db from app.log import LOG from app.models import User from .login_utils import after_login +from ...email_utils import can_be_used_as_personal_email _authorization_base_url = "https://www.facebook.com/dialog/oauth" _token_url = "https://graph.facebook.com/oauth/access_token" @@ -102,6 +103,12 @@ def facebook_callback(): # create user else: + if not can_be_used_as_personal_email(email): + flash( + f"You cannot use {email} as your personal inbox.", "error", + ) + return redirect(url_for("auth.login")) + LOG.d("create facebook user with %s", facebook_user_data) user = User.create( email=email.lower(), name=facebook_user_data["name"], activated=True diff --git a/app/auth/views/github.py b/app/auth/views/github.py index 51bf0763..85b663c1 100644 --- a/app/auth/views/github.py +++ b/app/auth/views/github.py @@ -1,4 +1,4 @@ -from flask import request, session, redirect, flash +from flask import request, session, redirect, flash, url_for from flask_login import login_user from requests_oauthlib import OAuth2Session @@ -6,6 +6,7 @@ from app import email_utils from app.auth.base import auth_bp from app.auth.views.login_utils import after_login from app.config import GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, URL +from app.email_utils import can_be_used_as_personal_email from app.extensions import db from app.log import LOG from app.models import User @@ -84,6 +85,12 @@ def github_callback(): # create user if not user: + if not can_be_used_as_personal_email(email): + flash( + f"You cannot use {email} as your personal inbox.", "error", + ) + return redirect(url_for("auth.login")) + LOG.d("create github user") user = User.create( email=email.lower(), name=github_user_data.get("name") or "", activated=True diff --git a/app/auth/views/google.py b/app/auth/views/google.py index 69dc9196..523278cd 100644 --- a/app/auth/views/google.py +++ b/app/auth/views/google.py @@ -1,4 +1,4 @@ -from flask import request, session, redirect, flash +from flask import request, session, redirect, flash, url_for from flask_login import login_user from requests_oauthlib import OAuth2Session @@ -10,6 +10,7 @@ from app.log import LOG from app.models import User, File from app.utils import random_string from .login_utils import after_login +from ...email_utils import can_be_used_as_personal_email _authorization_base_url = "https://accounts.google.com/o/oauth2/v2/auth" _token_url = "https://www.googleapis.com/oauth2/v4/token" @@ -92,6 +93,12 @@ def google_callback(): db.session.commit() # create user else: + if not can_be_used_as_personal_email(email): + flash( + f"You cannot use {email} as your personal inbox.", "error", + ) + return redirect(url_for("auth.login")) + LOG.d("create google user with %s", google_user_data) user = User.create( email=email.lower(), name=google_user_data["name"], activated=True diff --git a/app/auth/views/register.py b/app/auth/views/register.py index 29f216f9..2681c63c 100644 --- a/app/auth/views/register.py +++ b/app/auth/views/register.py @@ -6,7 +6,7 @@ from wtforms import StringField, validators from app import email_utils from app.auth.base import auth_bp from app.config import URL -from app.email_utils import email_belongs_to_alias_domains +from app.email_utils import can_be_used_as_personal_email from app.extensions import db from app.log import LOG from app.models import User, ActivationCode @@ -32,26 +32,25 @@ def register(): if form.validate_on_submit(): email = form.email.data - if email_belongs_to_alias_domains(email): + if not can_be_used_as_personal_email(email): flash( - "You cannot use alias as your personal inbox. Nice try though 😉", - "error", + "You cannot use this email address as your personal inbox.", "error", ) - - user = User.filter_by(email=email).first() - - if user: - flash(f"Email {form.email.data} already exists", "warning") else: - LOG.debug("create user %s", form.email.data) - user = User.create( - email=form.email.data.lower(), name="", password=form.password.data, - ) - db.session.commit() + user = User.filter_by(email=email).first() - send_activation_email(user, next_url) + if user: + flash(f"Email {form.email.data} already exists", "warning") + else: + LOG.debug("create user %s", form.email.data) + user = User.create( + email=form.email.data.lower(), name="", password=form.password.data, + ) + db.session.commit() - return render_template("auth/register_waiting_activation.html") + send_activation_email(user, next_url) + + return render_template("auth/register_waiting_activation.html") return render_template("auth/register.html", form=form, next_url=next_url) diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index f70d2fb8..9c9ec225 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -11,7 +11,10 @@ from wtforms import StringField, validators from app import s3, email_utils from app.config import URL from app.dashboard.base import dashboard_bp -from app.email_utils import email_belongs_to_alias_domains +from app.email_utils import ( + email_belongs_to_alias_domains, + can_be_used_as_personal_email, +) from app.extensions import db from app.log import LOG from app.models import ( @@ -93,9 +96,9 @@ def setting(): or DeletedAlias.get_by(email=new_email) ): flash(f"Email {new_email} already used", "error") - elif email_belongs_to_alias_domains(new_email): + elif not can_be_used_as_personal_email(new_email): flash( - "You cannot use alias as your personal inbox. Nice try though 😉", + "You cannot use this email address as your personal inbox.", "error", ) else: diff --git a/app/email_utils.py b/app/email_utils.py index 0ae8a5ff..567c4256 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -288,3 +288,23 @@ def email_belongs_to_alias_domains(email: str) -> bool: return True return False + + +def can_be_used_as_personal_email(email: str) -> bool: + """return True if an email can be used as a personal email. Currently the only condition is email domain is not + - one of ALIAS_DOMAINS + - one of custom domains + """ + domain = get_email_domain_part(email) + if not domain: + return False + + if domain in ALIAS_DOMAINS: + return False + + from app.models import CustomDomain + + if CustomDomain.get_by(domain=domain, verified=True): + return False + + return True diff --git a/tests/test_email_utils.py b/tests/test_email_utils.py index 0b5aad55..561c2a71 100644 --- a/tests/test_email_utils.py +++ b/tests/test_email_utils.py @@ -4,7 +4,10 @@ from app.email_utils import ( get_email_local_part, get_email_domain_part, email_belongs_to_alias_domains, + can_be_used_as_personal_email, ) +from app.extensions import db +from app.models import User, CustomDomain def test_get_email_name(): @@ -36,3 +39,19 @@ def test_email_belongs_to_alias_domains(): assert email_belongs_to_alias_domains("hey@d1.test") assert not email_belongs_to_alias_domains("hey@d3.test") + + +def test_can_be_used_as_personal_email(flask_client): + # default alias domain + assert not can_be_used_as_personal_email("ab@sl.local") + assert not can_be_used_as_personal_email("hey@d1.test") + + assert can_be_used_as_personal_email("hey@ab.cd") + # custom domain + user = User.create( + email="a@b.c", password="password", name="Test User", activated=True + ) + db.session.commit() + CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) + db.session.commit() + assert not can_be_used_as_personal_email("hey@ab.cd")