def test_cannot_create_alias_in_trash(flask_client): user = login(flask_client) # create a custom domain CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) signed_suffix = signer.sign("@ab.cd").decode() r = flask_client.post( "/api/v3/alias/custom/new", json={ "alias_prefix": "prefix", "signed_suffix": signed_suffix, "mailbox_ids": [user.default_mailbox_id], }, ) assert r.status_code == 201 assert r.json["alias"] == f"*****@*****.**" # delete alias: it's going to be moved to ab.cd trash alias = Alias.get_by(email="*****@*****.**") assert alias.custom_domain_id delete_alias(alias, user) # try to create the same alias, will fail as the alias is in trash r = flask_client.post( "/api/v3/alias/custom/new", json={ "alias_prefix": "prefix", "signed_suffix": signed_suffix, "mailbox_ids": [user.default_mailbox_id], }, ) assert r.status_code == 409
def test_too_many_requests(flask_client): user = login(flask_client) # create a custom domain CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) # can't create more than 5 aliases in 1 minute for i in range(7): signed_suffix = signer.sign("@ab.cd").decode() r = flask_client.post( "/api/v3/alias/custom/new", json={ "alias_prefix": f"prefix{i}", "signed_suffix": signed_suffix, "mailbox_ids": [user.default_mailbox_id], }, ) # to make flask-limiter work with unit test # https://github.com/alisaifee/flask-limiter/issues/147#issuecomment-642683820 g._rate_limiting_complete = False else: # last request assert r.status_code == 429 assert r.json == {"error": "Rate limit exceeded"}
def test_create_subdomain_out_of_quota(flask_client): user = login(flask_client) sl_domain = setup_sl_domain() for i in range(MAX_NB_SUBDOMAIN): CustomDomain.create( domain=f"test{i}.{sl_domain.domain}", user_id=user.id, is_sl_subdomain=True, commit=True, ) assert CustomDomain.count() == MAX_NB_SUBDOMAIN flask_client.post( url_for("dashboard.subdomain_route"), data={ "form-name": "create", "subdomain": "test", "domain": sl_domain.domain }, follow_redirects=True, ) # no new subdomain is created assert CustomDomain.count() == MAX_NB_SUBDOMAIN
def test_get_custom_domains(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="test1.org", verified=True, commit=True) CustomDomain.create( user_id=user.id, domain="test2.org", verified=False, commit=True ) r = flask_client.get( "/api/custom_domains", ) assert r.status_code == 200 assert len(r.json["custom_domains"]) == 2 for domain in r.json["custom_domains"]: assert domain["domain_name"] assert domain["id"] assert domain["nb_alias"] == 0 assert "is_verified" in domain assert "catch_all" in domain assert "name" in domain assert "random_prefix_generation" in domain assert domain["creation_date"] assert domain["creation_timestamp"] assert domain["mailboxes"] for mailbox in domain["mailboxes"]: assert "id" in mailbox assert "email" in mailbox
def test_import_no_mailboxes(flask_client): # Create user user = login(flask_client) # Check start state assert len(Alias.filter_by(user_id=user.id).all()) == 1 # Onboarding alias # Create domain CustomDomain.create( user_id=user.id, domain="my-domain.com", ownership_verified=True ) Session.commit() alias_data = [ "alias,note", "[email protected],Used on eBay", '[email protected],"Used on Facebook, Instagram."', ] file = File.create(path="/test", commit=True) batch_import = BatchImport.create(user_id=user.id, file_id=file.id) import_from_csv(batch_import, user, alias_data) assert len(Alias.filter_by(user_id=user.id).all()) == 3 # +2
def test_too_many_requests(flask_client): user = login(flask_client) # create a custom domain CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) # can't create more than 5 aliases in 1 minute for i in range(7): signed_suffix = signer.sign("@ab.cd").decode() r = flask_client.post( url_for("dashboard.custom_alias"), data={ "prefix": f"prefix{i}", "suffix": signed_suffix, "mailboxes": [user.default_mailbox_id], }, follow_redirects=True, ) # to make flask-limiter work with unit test # https://github.com/alisaifee/flask-limiter/issues/147#issuecomment-642683820 g._rate_limiting_complete = False else: # last request assert r.status_code == 429 assert "Whoa, slow down there, pardner!" in str(r.data)
def test_get_custom_domains(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="test1.org", verified=True, commit=True) CustomDomain.create(user_id=user.id, domain="test2.org", verified=False, commit=True) r = flask_client.get("/api/custom_domains", ) assert r.status_code == 200 assert r.json == { "custom_domains": [ { "domain": "test1.org", "id": 1, "nb_alias": 0, "verified": True }, { "domain": "test2.org", "id": 2, "nb_alias": 0, "verified": False }, ] }
def test_get_setting_domains_v2(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) r = flask_client.get("/api/v2/setting/domains") assert r.status_code == 200 assert r.json == [ { "domain": "d1.test", "is_custom": False }, { "domain": "d2.test", "is_custom": False }, { "domain": "sl.local", "is_custom": False }, { "domain": "ab.cd", "is_custom": True }, ]
def test_can_be_used_as_personal_email(flask_client): # default alias domain assert not email_can_be_used_as_mailbox("*****@*****.**") assert not email_can_be_used_as_mailbox("*****@*****.**") # custom domain user = User.create( email="[email protected]", password="******", name="Test User", activated=True, commit=True, ) CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) assert not email_can_be_used_as_mailbox("*****@*****.**") # disposable domain assert not email_can_be_used_as_mailbox("*****@*****.**") assert not email_can_be_used_as_mailbox("*****@*****.**") # subdomain will not work assert not email_can_be_used_as_mailbox("*****@*****.**") # valid domains should not be affected assert email_can_be_used_as_mailbox("*****@*****.**") assert email_can_be_used_as_mailbox("*****@*****.**")
def test_import(flask_client): # Create user user = login(flask_client) # Check start state assert len(Alias.filter_by(user_id=user.id).all()) == 1 # Onboarding alias # Create domains CustomDomain.create( user_id=user.id, domain="my-domain.com", ownership_verified=True ) CustomDomain.create( user_id=user.id, domain="my-destination-domain.com", ownership_verified=True ) Session.commit() # Create mailboxes mailbox1 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True ) mailbox2 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True ) Session.commit() alias_data = [ "alias,note,mailboxes", "[email protected],Used on eBay,[email protected]", '[email protected],"Used on Facebook, Instagram.",[email protected] [email protected]', ] file = File.create(path="/test", commit=True) batch_import = BatchImport.create(user_id=user.id, file_id=file.id) import_from_csv(batch_import, user, alias_data) aliases = Alias.filter_by(user_id=user.id).order_by(Alias.id).all() assert len(aliases) == 3 # +2 # aliases[0] is the onboarding alias, skip it # eBay alias assert aliases[1].email == "*****@*****.**" assert len(aliases[1].mailboxes) == 1 # First one should be primary assert aliases[1].mailbox_id == mailbox1.id # Others are sorted assert aliases[1].mailboxes[0] == mailbox1 # Facebook alias assert aliases[2].email == "*****@*****.**" assert len(aliases[2].mailboxes) == 2 # First one should be primary assert aliases[2].mailbox_id == mailbox1.id # Others are sorted assert aliases[2].mailboxes[0] == mailbox2 assert aliases[2].mailboxes[1] == mailbox1
def test_get_setting_domains_v2(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) r = flask_client.get("/api/v2/setting/domains") assert r.status_code == 200
def test_available_suffixes(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="test.com", verified=True) assert len(get_available_suffixes(user)) > 0 # first suffix is custom domain first_suffix = get_available_suffixes(user)[0] assert first_suffix.is_custom assert first_suffix.suffix == "@test.com" assert first_suffix.signed_suffix.startswith("@test.com")
def test_verify_prefix_suffix(flask_client): user = login(flask_client) db.session.commit() CustomDomain.create(user_id=user.id, domain="test.com", verified=True) assert verify_prefix_suffix(user, "prefix", "@test.com") assert not verify_prefix_suffix(user, "prefix", "@abcd.com") word = random_word() suffix = f".{word}@{EMAIL_DOMAIN}" assert verify_prefix_suffix(user, "prefix", suffix)
def test_available_suffixes(flask_client): user = login(flask_client) db.session.commit() CustomDomain.create(user_id=user.id, domain="test.com", verified=True) assert len(available_suffixes(user)) > 0 # first suffix is custom domain first_suffix = available_suffixes(user)[0] assert first_suffix[0] assert first_suffix[1] == "@test.com" assert first_suffix[2].startswith("@test.com")
def test_can_be_used_as_personal_email(flask_client): # default alias domain assert not can_be_used_as_personal_email("*****@*****.**") assert not can_be_used_as_personal_email("*****@*****.**") assert can_be_used_as_personal_email("*****@*****.**") # custom domain user = User.create( email="[email protected]", 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("*****@*****.**")
def test_cannot_create_alias_in_trash(flask_client): user = User.create(email="[email protected]", password="******", name="Test User", activated=True) db.session.commit() # create api_key api_key = ApiKey.create(user.id, "for test") db.session.commit() # create a custom domain CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) db.session.commit() # create new alias with note suffix = "@ab.cd" suffix = signer.sign(suffix).decode() r = flask_client.post( url_for("api.new_custom_alias_v2", hostname="www.test.com"), headers={"Authentication": api_key.code}, json={ "alias_prefix": "prefix", "signed_suffix": suffix, "note": "test note", }, ) # assert alias creation is successful assert r.status_code == 201 assert r.json["alias"] == "*****@*****.**" # delete alias: it's going to be moved to ab.cd trash alias = Alias.get_by(email="*****@*****.**") assert alias.custom_domain_id delete_alias(alias, user) # try to create the same alias, will fail as the alias is in trash r = flask_client.post( url_for("api.new_custom_alias_v2", hostname="www.test.com"), headers={"Authentication": api_key.code}, json={ "alias_prefix": "prefix", "signed_suffix": suffix, "note": "test note", }, ) assert r.status_code == 409
def test_get_setting_domains(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) r = flask_client.get("/api/setting/domains") assert r.status_code == 200 assert r.json == [ [True, "d1.test"], [True, "d2.test"], [True, "sl.local"], [False, "ab.cd"], ]
def test_create_subdomain_in_trash(flask_client): user = login(flask_client) sl_domain = setup_sl_domain() subdomain = CustomDomain.create( domain=f"test.{sl_domain.domain}", user_id=user.id, is_sl_subdomain=True, commit=True, ) # delete the subdomain CustomDomain.delete(subdomain.id) assert CustomDomain.get_by(domain=f"test.{sl_domain.domain}") is None r = flask_client.post( url_for("dashboard.subdomain_route"), data={ "form-name": "create", "subdomain": "test", "domain": sl_domain.domain }, follow_redirects=True, ) assert r.status_code == 200 assert ( f"test.{sl_domain.domain} has been used before and cannot be reused" in r.data.decode())
def test_available_suffixes_default_domain(flask_client): user = login(flask_client) sl_domain = SLDomain.query.first() CustomDomain.create(user_id=user.id, domain="test.com", verified=True, commit=True) user.default_alias_public_domain_id = sl_domain.id # first suffix is SL Domain first_suffix = get_available_suffixes(user)[0] assert first_suffix.suffix.endswith(f"@{sl_domain.domain}") user.default_alias_public_domain_id = None # first suffix is custom domain first_suffix = get_available_suffixes(user)[0] assert first_suffix.suffix == "@test.com"
def test_delete_subdomain(flask_client): user = login(flask_client) sl_domain = setup_sl_domain() subdomain = CustomDomain.create( domain=f"test.{sl_domain.domain}", user_id=user.id, is_sl_subdomain=True, commit=True, ) nb_job = Job.count() r = flask_client.post( url_for("dashboard.domain_detail", custom_domain_id=subdomain.id), data={"form-name": "delete"}, follow_redirects=True, ) assert r.status_code == 200 assert f"test.{sl_domain.domain} scheduled for deletion." in r.data.decode( ) # a domain deletion job is scheduled assert Job.count() == nb_job + 1
def test_custom_domain_alias(flask_client): user = login(flask_client) # create a custom domain CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) signed_suffix = signer.sign("@ab.cd").decode() r = flask_client.post( "/api/v3/alias/custom/new", json={ "alias_prefix": "prefix", "signed_suffix": signed_suffix, "mailbox_ids": [user.default_mailbox_id], }, ) assert r.status_code == 201 assert r.json["alias"] == "*****@*****.**"
def test_available_suffixes_random_prefix_generation(flask_client): user = login(flask_client) CustomDomain.create(user_id=user.id, domain="test.com", verified=True, commit=True) cd2 = CustomDomain.create( user_id=user.id, domain="test2.com", verified=True, commit=True ) user.default_alias_custom_domain_id = cd2.id # first suffix is test2.com first_suffix = get_available_suffixes(user)[0] assert first_suffix.suffix == "@test2.com" cd2.random_prefix_generation = True # e.g. [email protected] first_suffix = get_available_suffixes(user)[0] assert first_suffix.suffix.endswith("@test2.com") assert first_suffix.suffix.startswith(".")
def test_update_custom_domains(flask_client): user = login(flask_client) d1 = CustomDomain.create( user_id=user.id, domain="test1.org", verified=True, commit=True ) # test update catch all assert d1.catch_all is False r = flask_client.patch(f"/api/custom_domains/{d1.id}", json={"catch_all": True}) assert r.status_code == 200 assert d1.catch_all is True # make sure the full domain json is returned cd_json = r.json["custom_domain"] assert cd_json["domain_name"] assert cd_json["id"] == d1.id assert cd_json["nb_alias"] == 0 assert "is_verified" in cd_json assert "catch_all" in cd_json assert "name" in cd_json assert "random_prefix_generation" in cd_json assert cd_json["creation_date"] assert cd_json["creation_timestamp"] assert cd_json["mailboxes"] for mailbox in cd_json["mailboxes"]: assert "id" in mailbox assert "email" in mailbox # test update random_prefix_generation assert d1.random_prefix_generation is False r = flask_client.patch( f"/api/custom_domains/{d1.id}", json={"random_prefix_generation": True} ) assert r.status_code == 200 assert d1.random_prefix_generation is True # test update name assert d1.name is None r = flask_client.patch(f"/api/custom_domains/{d1.id}", json={"name": "test name"}) assert r.status_code == 200 assert d1.name == "test name" # test update mailboxes assert d1.mailboxes == [user.default_mailbox] mb = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, commit=True ) r = flask_client.patch( f"/api/custom_domains/{d1.id}", json={"mailbox_ids": [mb.id]} ) assert r.status_code == 200 assert d1.mailboxes == [mb]
def custom_domain(): custom_domains = CustomDomain.query.filter_by( user_id=current_user.id).all() new_custom_domain_form = NewCustomDomainForm() errors = {} if request.method == "POST": if request.form.get("form-name") == "create": if not current_user.is_premium(): flash("Only premium plan can add custom domain", "warning") return redirect(url_for("dashboard.custom_domain")) if new_custom_domain_form.validate(): new_domain = new_custom_domain_form.domain.data.lower().strip() if new_domain.startswith("http://"): new_domain = new_domain[len("http://"):] if new_domain.startswith("https://"): new_domain = new_domain[len("https://"):] if CustomDomain.get_by(domain=new_domain): flash(f"{new_domain} already added", "warning") elif get_email_domain_part(current_user.email) == new_domain: flash( "You cannot add a domain that you are currently using for your personal email. " "Please change your personal email to your real email", "error", ) else: new_custom_domain = CustomDomain.create( domain=new_domain, user_id=current_user.id) db.session.commit() flash(f"New domain {new_custom_domain.domain} is created", "success") return redirect( url_for( "dashboard.domain_detail_dns", custom_domain_id=new_custom_domain.id, )) return render_template( "dashboard/custom_domain.html", custom_domains=custom_domains, new_custom_domain_form=new_custom_domain_form, EMAIL_SERVERS_WITH_PRIORITY=EMAIL_SERVERS_WITH_PRIORITY, errors=errors, )
def test_with_custom_domain(flask_client): user = login(flask_client) CustomDomain.create( user_id=user.id, domain="ab.cd", ownership_verified=True, commit=True ) r = flask_client.post( url_for("api.new_random_alias", hostname="www.test.com"), ) assert r.status_code == 201 assert r.json["alias"] == "*****@*****.**" assert Alias.count() == 2 # call the endpoint again, should return the same alias r = flask_client.post( url_for("api.new_random_alias", hostname="www.test.com"), ) assert r.status_code == 201 assert r.json["alias"] == "*****@*****.**" # no new alias is created assert Alias.count() == 2
def test_add_alias_in_custom_domain_trash(flask_client): user = login(flask_client) custom_domain = CustomDomain.create(user_id=user.id, domain="ab.cd", ownership_verified=True, commit=True) # delete a custom-domain alias: alias should go the DomainDeletedAlias alias = Alias.create( user_id=user.id, email="*****@*****.**", custom_domain_id=custom_domain.id, mailbox_id=user.default_mailbox_id, commit=True, ) assert DomainDeletedAlias.count() == 0 delete_alias(alias, user) assert DomainDeletedAlias.count() == 1 # create the same alias, should return error suffix = "@ab.cd" alias_suffix = AliasSuffix(is_custom=False, suffix=suffix, is_premium=False, domain=EMAIL_DOMAIN) signed_alias_suffix = signer.sign(alias_suffix.serialize()).decode() r = flask_client.post( url_for("dashboard.custom_alias"), data={ "prefix": "prefix", "signed-alias-suffix": signed_alias_suffix, "mailboxes": [user.default_mailbox_id], }, follow_redirects=True, ) assert r.status_code == 200 assert "You have deleted this alias before. You can restore it on" in r.get_data( True)
def custom_domain(): custom_domains = CustomDomain.query.filter_by(user_id=current_user.id).all() new_custom_domain_form = NewCustomDomainForm() errors = {} if request.method == "POST": if request.form.get("form-name") == "create": if not current_user.is_premium(): flash("Only premium plan can add custom domain", "warning") return redirect(url_for("dashboard.custom_domain")) if new_custom_domain_form.validate(): new_domain = new_custom_domain_form.domain.data.strip() if CustomDomain.get_by(domain=new_domain): flash(f"{new_domain} already added", "warning") else: new_custom_domain = CustomDomain.create( domain=new_domain, user_id=current_user.id ) db.session.commit() flash( f"New domain {new_custom_domain.domain} is created", "success" ) return redirect( url_for( "dashboard.domain_detail_dns", custom_domain_id=new_custom_domain.id, ) ) return render_template( "dashboard/custom_domain.html", custom_domains=custom_domains, new_custom_domain_form=new_custom_domain_form, EMAIL_SERVERS_WITH_PRIORITY=EMAIL_SERVERS_WITH_PRIORITY, errors=errors, )
def test_get_custom_domain_trash(flask_client): user = login(flask_client) cd = CustomDomain.create(user_id=user.id, domain="test1.org", verified=True, commit=True) alias = Alias.create( user_id=user.id, email="*****@*****.**", custom_domain_id=cd.id, mailbox_id=user.default_mailbox_id, commit=True, ) delete_alias(alias, user) r = flask_client.get(f"/api/custom_domains/{cd.id}/trash", ) for deleted_alias in r.json["aliases"]: assert deleted_alias["alias"] assert deleted_alias["creation_timestamp"] > 0
def test_add_alias_in_custom_domain_trash(flask_client): user = login(flask_client) db.session.commit() custom_domain = CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True) # delete a custom-domain alias: alias should go the DomainDeletedAlias alias = Alias.create( user_id=user.id, email=f"*****@*****.**", custom_domain_id=custom_domain.id, mailbox_id=user.default_mailbox_id, commit=True, ) assert DomainDeletedAlias.query.count() == 0 delete_alias(alias, user) assert DomainDeletedAlias.query.count() == 1 # create the same alias, should return error suffix = f"@ab.cd" signed_suffix = signer.sign(suffix).decode() r = flask_client.post( url_for("dashboard.custom_alias"), data={ "prefix": "prefix", "suffix": signed_suffix, "mailboxes": [user.default_mailbox_id], }, follow_redirects=True, ) assert r.status_code == 200 assert "You have deleted this alias before. You can restore it on" in r.get_data( True)
def test_update_custom_domains(flask_client): user = login(flask_client) d1 = CustomDomain.create( user_id=user.id, domain="test1.org", verified=True, commit=True ) # test update catch all assert d1.catch_all is False r = flask_client.patch(f"/api/custom_domains/{d1.id}", json={"catch_all": True}) assert r.status_code == 200 assert d1.catch_all is True # test update random_prefix_generation assert d1.random_prefix_generation is False r = flask_client.patch( f"/api/custom_domains/{d1.id}", json={"random_prefix_generation": True} ) assert r.status_code == 200 assert d1.random_prefix_generation is True # test update name assert d1.name is None r = flask_client.patch(f"/api/custom_domains/{d1.id}", json={"name": "test name"}) assert r.status_code == 200 assert d1.name == "test name" # test update mailboxes assert d1.mailboxes == [user.default_mailbox] mb = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, commit=True ) r = flask_client.patch( f"/api/custom_domains/{d1.id}", json={"mailbox_ids": [mb.id]} ) assert r.status_code == 200 assert d1.mailboxes == [mb]