Пример #1
0
def test_update_alias_name(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()

    alias = Alias.create_new_random(user)
    db.session.commit()

    r = flask_client.put(
        url_for("api.update_alias", alias_id=alias.id),
        headers={"Authentication": api_key.code},
        json={"name": "Test Name"},
    )

    assert r.status_code == 200
    alias = Alias.get(alias.id)
    assert alias.name == "Test Name"
Пример #2
0
def test_alias_contacts(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()

    alias = Alias.create_new_random(user)
    db.session.commit()

    # create some alias log
    for i in range(PAGE_LIMIT + 1):
        contact = Contact.create(
            website_email=f"marketing-{i}@example.com",
            reply_email=f"reply-{i}@a.b",
            alias_id=alias.id,
            user_id=alias.user_id,
        )
        db.session.commit()

        EmailLog.create(contact_id=contact.id,
                        is_reply=True,
                        user_id=contact.user_id)
        db.session.commit()

    r = flask_client.get(
        url_for("api.get_alias_contacts_route", alias_id=alias.id, page_id=0),
        headers={"Authentication": api_key.code},
    )

    assert r.status_code == 200
    assert len(r.json["contacts"]) == PAGE_LIMIT
    for ac in r.json["contacts"]:
        assert ac["creation_date"]
        assert ac["creation_timestamp"]
        assert ac["last_email_sent_date"]
        assert ac["last_email_sent_timestamp"]
        assert ac["contact"]
        assert ac["reverse_alias"]

    # second page, should return 1 result only
    r = flask_client.get(
        url_for("api.get_alias_contacts_route", alias_id=alias.id, page_id=1),
        headers={"Authentication": api_key.code},
    )
    assert len(r.json["contacts"]) == 1
Пример #3
0
def create_contact_route(alias_id):
    """
    Create contact for an alias
    Input:
        alias_id: in url
        contact: in body
    Output:
        201 if success
        409 if contact already added


    """
    data = request.get_json()
    if not data:
        return jsonify(error="request body cannot be empty"), 400

    user = g.user
    alias: Alias = Alias.get(alias_id)

    if alias.user_id != user.id:
        return jsonify(error="Forbidden"), 403

    contact_addr = data.get("contact")

    # generate a reply_email, make sure it is unique
    # not use while to avoid infinite loop
    reply_email = f"ra+{random_string(25)}@{EMAIL_DOMAIN}"
    for _ in range(1000):
        reply_email = f"ra+{random_string(25)}@{EMAIL_DOMAIN}"
        if not Contact.get_by(reply_email=reply_email):
            break

    contact_name, contact_email = parseaddr_unicode(contact_addr)

    # already been added
    if Contact.get_by(alias_id=alias.id, website_email=contact_email):
        return jsonify(error="Contact already added"), 409

    contact = Contact.create(
        user_id=alias.user_id,
        alias_id=alias.id,
        website_email=contact_email,
        name=contact_name,
        reply_email=reply_email,
    )

    LOG.d("create reverse-alias for %s %s", contact_addr, alias)
    db.session.commit()

    return jsonify(**serialize_contact(contact)), 201
Пример #4
0
def test_add_contact_success(flask_client):
    login(flask_client)
    alias = Alias.first()

    assert Contact.query.count() == 0

    # <<< Create a new contact >>>
    flask_client.post(
        url_for("dashboard.alias_contact_manager", alias_id=alias.id),
        data={
            "form-name": "create",
            "email": "*****@*****.**",
        },
        follow_redirects=True,
    )
    # a new contact is added
    assert Contact.query.count() == 1
    contact = Contact.first()
    assert contact.website_email == "*****@*****.**"

    # <<< Create a new contact using a full email format >>>
    flask_client.post(
        url_for("dashboard.alias_contact_manager", alias_id=alias.id),
        data={
            "form-name": "create",
            "email": "First Last <*****@*****.**>",
        },
        follow_redirects=True,
    )
    # a new contact is added
    assert Contact.query.count() == 2
    contact = Contact.get(2)
    assert contact.website_email == "*****@*****.**"
    assert contact.name == "First Last"

    # <<< Create a new contact with invalid email address >>>
    r = flask_client.post(
        url_for("dashboard.alias_contact_manager", alias_id=alias.id),
        data={
            "form-name": "create",
            "email": "with [email protected]",
        },
        follow_redirects=True,
    )

    # no new contact is added
    assert Contact.query.count() == 2
    assert "Invalid email format. Email must be either [email protected]" in str(
        r.data)
Пример #5
0
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
Пример #6
0
def test_alias_activities(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()

    alias = Alias.create_new_random(user)
    db.session.commit()

    # create some alias log
    contact = Contact.create(
        website_email="*****@*****.**",
        reply_email="[email protected]",
        alias_id=alias.id,
        user_id=alias.user_id,
    )
    db.session.commit()

    for _ in range(int(PAGE_LIMIT / 2)):
        EmailLog.create(contact_id=contact.id, is_reply=True, user_id=contact.user_id)

    for _ in range(int(PAGE_LIMIT / 2) + 2):
        EmailLog.create(contact_id=contact.id, blocked=True, user_id=contact.user_id)

    r = flask_client.get(
        url_for("api.get_alias_activities", alias_id=alias.id, page_id=0),
        headers={"Authentication": api_key.code},
    )

    assert r.status_code == 200
    assert len(r.json["activities"]) == PAGE_LIMIT
    for ac in r.json["activities"]:
        assert ac["from"]
        assert ac["to"]
        assert ac["timestamp"]
        assert ac["action"]
        assert ac["reverse_alias"]
        assert ac["reverse_alias_address"]

    # second page, should return 1 or 2 results only
    r = flask_client.get(
        url_for("api.get_alias_activities", alias_id=alias.id, page_id=1),
        headers={"Authentication": api_key.code},
    )
    assert len(r.json["activities"]) < 3
Пример #7
0
def test_rate_limited_forward_phase_for_mailbox(flask_client):
    user = User.create(email="[email protected]",
                       password="******",
                       name="Test User",
                       activated=True)
    db.session.commit()

    alias = Alias.create_new_random(user)
    db.session.commit()

    contact = Contact.create(
        user_id=user.id,
        alias_id=alias.id,
        website_email="*****@*****.**",
        reply_email="*****@*****.**",
    )
    db.session.commit()
    for _ in range(MAX_ACTIVITY_DURING_MINUTE_PER_MAILBOX + 1):
        EmailLog.create(
            user_id=user.id,
            contact_id=contact.id,
            alias_id=contact.alias_id,
        )
        db.session.commit()

    EmailLog.create(
        user_id=user.id,
        contact_id=contact.id,
        alias_id=contact.alias_id,
    )

    # Create another alias with the same mailbox
    # will be rate limited as there's a previous activity on mailbox
    alias2 = Alias.create_new_random(user)
    db.session.commit()
    assert rate_limited_for_mailbox(alias2)
Пример #8
0
def test_add_already_existed_alias(flask_client):
    user = login(flask_client)
    db.session.commit()

    another_user = User.create(
        email="[email protected]",
        password="******",
        name="Test User",
        activated=True,
        commit=True,
    )

    word = random_word()
    suffix = f".{word}@{EMAIL_DOMAIN}"
    signed_suffix = signer.sign(suffix).decode()

    # alias already exist
    Alias.create(
        user_id=another_user.id,
        email=f"prefix{suffix}",
        mailbox_id=another_user.default_mailbox_id,
        commit=True,
    )

    # create the same alias, should return error
    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 f"prefix{suffix} cannot be used" in r.get_data(True)
Пример #9
0
def test_mailbox_delete(flask_client):
    user = User.create(
        email="[email protected]",
        password="******",
        name="Test User",
        activated=True,
        commit=True,
    )

    m1 = Mailbox.create(user_id=user.id,
                        email="*****@*****.**",
                        verified=True,
                        commit=True)
    m2 = Mailbox.create(user_id=user.id,
                        email="*****@*****.**",
                        verified=True,
                        commit=True)
    m3 = Mailbox.create(user_id=user.id,
                        email="*****@*****.**",
                        verified=True,
                        commit=True)

    # alias has 2 mailboxes
    alias = Alias.create_new(user, "prefix", mailbox_id=m1.id)
    Session.commit()

    alias._mailboxes.append(m2)
    alias._mailboxes.append(m3)
    Session.commit()

    assert len(alias.mailboxes) == 3

    # delete m1, should not delete alias
    Mailbox.delete(m1.id)
    alias = Alias.get(alias.id)
    assert len(alias.mailboxes) == 2
Пример #10
0
def test_suggested_emails_for_user_who_cannot_create_new_alias(flask_client):
    # make sure user is not in trial
    user = User.create(
        email="[email protected]",
        password="******",
        name="Test User",
        activated=True,
        trial_end=None,
        commit=True,
    )

    # make sure user runs out of quota to create new email
    for _ in range(MAX_NB_EMAIL_FREE_PLAN):
        Alias.create_new(user=user, prefix="test")
    Session.commit()

    suggested_email, other_emails = user.suggested_emails(website_name="test")

    # the suggested email is chosen from existing Alias
    assert Alias.get_by(email=suggested_email)

    # all other emails are generated emails
    for email in other_emails:
        assert Alias.get_by(email=email)
Пример #11
0
def sanitize_alias_address_name():
    count = 0
    # using Alias.all() will take all the memory
    for alias in Alias.yield_per_query():
        if count % 1000 == 0:
            LOG.d("process %s", count)

        count += 1
        if sanitize_email(alias.email) != alias.email:
            LOG.e("Alias %s email not sanitized", alias)

        if alias.name and "\n" in alias.name:
            alias.name = alias.name.replace("\n", "")
            Session.commit()
            LOG.e("Alias %s name contains linebreak %s", alias, alias.name)
Пример #12
0
def test_update_alias_mailboxes(flask_client):
    user = User.create(email="[email protected]",
                       password="******",
                       name="Test User",
                       activated=True)
    db.session.commit()

    mb1 = Mailbox.create(user_id=user.id, email="*****@*****.**", verified=True)
    mb2 = Mailbox.create(user_id=user.id, email="*****@*****.**", verified=True)

    # create api_key
    api_key = ApiKey.create(user.id, "for test")
    db.session.commit()

    alias = Alias.create_new_random(user)
    db.session.commit()

    r = flask_client.put(
        url_for("api.update_alias", alias_id=alias.id),
        headers={"Authentication": api_key.code},
        json={"mailbox_ids": [mb1.id, mb2.id]},
    )

    assert r.status_code == 200
    alias = Alias.get(alias.id)

    assert alias.mailbox
    assert len(alias._mailboxes) == 1

    # fail when update with empty mailboxes
    r = flask_client.put(
        url_for("api.update_alias", alias_id=alias.id),
        headers={"Authentication": api_key.code},
        json={"mailbox_ids": []},
    )
    assert r.status_code == 400
Пример #13
0
def test_should_disable(flask_client):
    user = User.create(
        email="[email protected]",
        password="******",
        name="Test User",
        activated=True,
        include_sender_in_reverse_alias=True,
    )
    alias = Alias.create_new_random(user)
    Session.commit()

    assert not should_disable(alias)

    # create a lot of bounce on this alias
    contact = Contact.create(
        user_id=user.id,
        alias_id=alias.id,
        website_email="*****@*****.**",
        reply_email="*****@*****.**",
        commit=True,
    )
    for _ in range(20):
        EmailLog.create(
            user_id=user.id,
            contact_id=contact.id,
            alias_id=contact.alias_id,
            commit=True,
            bounced=True,
        )

    assert should_disable(alias)

    # should not affect another alias
    alias2 = Alias.create_new_random(user)
    Session.commit()
    assert not should_disable(alias2)
Пример #14
0
async def check_hibp():
    """
    Check all aliases on the HIBP (Have I Been Pwned) API
    """
    LOG.d("Checking HIBP API for aliases in breaches")

    if len(HIBP_API_KEYS) == 0:
        LOG.e("No HIBP API keys")
        return

    LOG.d("Updating list of known breaches")
    r = requests.get("https://haveibeenpwned.com/api/v3/breaches")
    for entry in r.json():
        hibp_entry = Hibp.get_or_create(name=entry["Name"])
        hibp_entry.date = arrow.get(entry["BreachDate"])
        hibp_entry.description = entry["Description"]

    Session.commit()
    LOG.d("Updated list of known breaches")

    LOG.d("Preparing list of aliases to check")
    queue = asyncio.Queue()
    max_date = arrow.now().shift(days=-HIBP_SCAN_INTERVAL_DAYS)
    for alias in (Alias.filter(
            or_(Alias.hibp_last_check.is_(None),
                Alias.hibp_last_check < max_date)).filter(
                    Alias.enabled).order_by(
                        Alias.hibp_last_check.asc()).all()):
        await queue.put(alias.id)

    LOG.d("Need to check about %s aliases", queue.qsize())

    # Start one checking process per API key
    # Each checking process will take one alias from the queue, get the info
    # and then sleep for 1.5 seconds (due to HIBP API request limits)
    checkers = []
    for i in range(len(HIBP_API_KEYS)):
        checker = asyncio.create_task(_hibp_check(
            HIBP_API_KEYS[i],
            queue,
        ))
        checkers.append(checker)

    # Wait until all checking processes are done
    for checker in checkers:
        await checker

    LOG.d("Done checking HIBP API for aliases in breaches")
Пример #15
0
def try_auto_create_catch_all_domain(address: str) -> Optional[Alias]:
    """Try to create an alias with catch-all domain"""

    # try to create alias on-the-fly with custom-domain catch-all feature
    # check if alias is custom-domain alias and if the custom-domain has catch-all enabled
    alias_domain = get_email_domain_part(address)
    custom_domain: CustomDomain = CustomDomain.get_by(domain=alias_domain)

    if not custom_domain:
        return None

    # custom_domain exists
    if not custom_domain.catch_all:
        return None

    # custom_domain has catch-all enabled
    domain_user: User = custom_domain.user

    if not domain_user.can_create_new_alias():
        send_cannot_create_domain_alias(domain_user, address, alias_domain)
        return None

    try:
        LOG.d("create alias %s for domain %s", address, custom_domain)
        mailboxes = custom_domain.mailboxes
        alias = Alias.create(
            email=address,
            user_id=custom_domain.user_id,
            custom_domain_id=custom_domain.id,
            automatic_creation=True,
            mailbox_id=mailboxes[0].id,
        )
        db.session.flush()
        for i in range(1, len(mailboxes)):
            AliasMailbox.create(
                alias_id=alias.id,
                mailbox_id=mailboxes[i].id,
            )
        db.session.commit()
        return alias
    except AliasInTrashError:
        LOG.warning(
            "Alias %s was deleted before, cannot auto-create using domain catch-all %s, user %s",
            address,
            custom_domain,
            domain_user,
        )
        return None
Пример #16
0
def test_get_alias_infos_with_pagination_v3_query_alias_note(flask_client):
    """test the query on the alias note"""
    user = User.create(
        email="[email protected]",
        password="******",
        name="Test User",
        activated=True,
        commit=True,
    )

    alias = Alias.first()
    alias.note = "test note"
    Session.commit()

    alias_infos = get_alias_infos_with_pagination_v3(user, query="test note")
    assert len(alias_infos) == 1
Пример #17
0
def test_new_addr_at_only_sender_format(flask_client):
    user = login(flask_client)
    user.sender_format = SenderFormatEnum.AT_ONLY.value
    Session.commit()
    alias = Alias.first()

    contact = Contact.create(
        user_id=user.id,
        alias_id=alias.id,
        website_email="*****@*****.**",
        reply_email="rep@SL",
        name="First Last",
        commit=True,
    )

    assert contact.new_addr() == '"abcd at example.com" <rep@SL>'
Пример #18
0
def get_alias(alias_id):
    """
    Get alias
    Input:
        alias_id: in url
    Output:
        Alias info, same as in get_aliases

    """
    user = g.user
    alias: Alias = Alias.get(alias_id)

    if alias.user_id != user.id:
        return jsonify(error="Forbidden"), 403

    return jsonify(**serialize_alias_info_v2(get_alias_info_v2(alias))), 200
Пример #19
0
def rate_limited_forward_phase(alias_address: str) -> bool:
    alias = Alias.get_by(email=alias_address)

    if alias:
        return rate_limited_for_alias(alias) or rate_limited_for_mailbox(alias)

    else:
        LOG.d(
            "alias %s not exist. Try to see if it can be created on the fly",
            alias_address,
        )
        alias = try_auto_create(alias_address)
        if alias:
            return rate_limited_for_mailbox(alias)

    return False
Пример #20
0
def create_contact_route(alias_id):
    """
    Create contact for an alias
    Input:
        alias_id: in url
        contact: in body
    Output:
        201 if success
        409 if contact already added


    """
    data = request.get_json()
    if not data:
        return jsonify(error="request body cannot be empty"), 400

    user = g.user
    alias: Alias = Alias.get(alias_id)

    if alias.user_id != user.id:
        return jsonify(error="Forbidden"), 403

    contact_addr = data.get("contact")

    if not contact_addr:
        return jsonify(error="Contact cannot be empty"), 400

    contact_name, contact_email = parseaddr_unicode(contact_addr)
    if not is_valid_email(contact_email):
        return jsonify(error=f"invalid contact email {contact_email}"), 400

    # already been added
    if Contact.get_by(alias_id=alias.id, website_email=contact_email):
        return jsonify(error="Contact already added"), 409

    contact = Contact.create(
        user_id=alias.user_id,
        alias_id=alias.id,
        website_email=contact_email,
        name=contact_name,
        reply_email=generate_reply_email(contact_email),
    )

    LOG.d("create reverse-alias for %s %s", contact_addr, alias)
    db.session.commit()

    return jsonify(**serialize_contact(contact)), 201
Пример #21
0
def test_different_scenarios(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()

    # <<< without hostname >>>
    r = flask_client.get(
        url_for("api.options"), headers={"Authentication": api_key.code}
    )

    # {
    #     "can_create_custom": True,
    #     "custom": {"suffixes": ["*****@*****.**"], "suggestion": ""},
    #     "existing": ["*****@*****.**"],
    # }
    assert r.status_code == 200
    assert r.json["can_create_custom"]
    assert len(r.json["existing"]) == 1
    assert len(r.json["custom"]["suffixes"]) == 4

    assert r.json["custom"]["suggestion"] == ""  # no hostname => no suggestion

    # <<< with hostname >>>
    r = flask_client.get(
        url_for("api.options", hostname="www.test.com"),
        headers={"Authentication": api_key.code},
    )

    assert r.json["custom"]["suggestion"] == "test"

    # <<< with recommendation >>>
    alias = Alias.create_new(user, prefix="test")
    db.session.commit()
    AliasUsedOn.create(alias_id=alias.id, hostname="www.test.com", user_id=user.id)
    db.session.commit()

    r = flask_client.get(
        url_for("api.options", hostname="www.test.com"),
        headers={"Authentication": api_key.code},
    )
    assert r.json["recommendation"]["alias"] == alias.email
    assert r.json["recommendation"]["hostname"] == "www.test.com"
Пример #22
0
def new_random_alias():
    """
    Create a new random alias
    Input:
        (Optional) note
    Output:
        201 if success

    """
    user = g.user
    if not user.can_create_new_alias():
        LOG.d("user %s cannot create new random alias", user)
        return (
            jsonify(
                error=f"You have reached the limitation of a free account with the maximum of "
                f"{MAX_NB_EMAIL_FREE_PLAN} aliases, please upgrade your plan to create more aliases"
            ),
            400,
        )

    note = None
    data = request.get_json(silent=True)
    if data:
        note = data.get("note")

    scheme = user.alias_generator
    mode = request.args.get("mode")
    if mode:
        if mode == "word":
            scheme = AliasGeneratorEnum.word.value
        elif mode == "uuid":
            scheme = AliasGeneratorEnum.uuid.value
        else:
            return jsonify(error=f"{mode} must be either word or alias"), 400

    alias = Alias.create_new_random(user=user, scheme=scheme, note=note)
    db.session.commit()

    hostname = request.args.get("hostname")
    if hostname:
        AliasUsedOn.create(alias_id=alias.id, hostname=hostname, user_id=alias.user_id)
        db.session.commit()

    return (
        jsonify(alias=alias.email, **serialize_alias_info_v2(get_alias_info_v2(alias))),
        201,
    )
Пример #23
0
def domain_detail(custom_domain_id):
    custom_domain = CustomDomain.get(custom_domain_id)
    if not custom_domain or custom_domain.user_id != current_user.id:
        flash("You cannot see this page", "warning")
        return redirect(url_for("dashboard.index"))

    if request.method == "POST":
        if request.form.get("form-name") == "switch-catch-all":
            custom_domain.catch_all = not custom_domain.catch_all
            db.session.commit()

            if custom_domain.catch_all:
                flash(
                    f"The catch-all has been enabled for {custom_domain.domain}",
                    "success",
                )
            else:
                flash(
                    f"The catch-all has been disabled for {custom_domain.domain}",
                    "warning",
                )
            return redirect(
                url_for("dashboard.domain_detail",
                        custom_domain_id=custom_domain.id))
        elif request.form.get("form-name") == "set-name":
            custom_domain.name = request.form.get("alias-name")
            db.session.commit()
            flash(
                f"Default alias name for Domain {custom_domain.domain} has been set",
                "success",
            )

            return redirect(
                url_for("dashboard.domain_detail",
                        custom_domain_id=custom_domain.id))
        elif request.form.get("form-name") == "delete":
            name = custom_domain.domain
            CustomDomain.delete(custom_domain_id)
            db.session.commit()
            flash(f"Domain {name} has been deleted", "success")

            return redirect(url_for("dashboard.custom_domain"))

    nb_alias = Alias.filter_by(custom_domain_id=custom_domain.id).count()

    return render_template("dashboard/domain_detail/info.html", **locals())
Пример #24
0
def test_block_contact(flask_client):
    user = login(flask_client)
    alias = Alias.first()
    contact = Contact.create(
        user_id=user.id,
        alias_id=alias.id,
        website_email="*****@*****.**",
        reply_email="re1@SL",
        commit=True,
    )

    assert not contact.block_forward
    flask_client.post(f"/dashboard/block_contact/{contact.id}")
    assert contact.block_forward

    # make sure the page loads
    flask_client.get(f"/dashboard/block_contact/{contact.id}")
Пример #25
0
def test_get_pinned_aliases_v2(flask_client):
    user = login(flask_client)

    a0 = Alias.create_new(user, "prefix0")
    a0.pinned = True
    Session.commit()

    r = flask_client.get("/api/v2/aliases?page_id=0")
    assert r.status_code == 200
    # the default alias (created when user is created) and a0 are returned
    assert len(r.json["aliases"]) == 2

    r = flask_client.get("/api/v2/aliases?page_id=0&pinned=true")
    assert r.status_code == 200
    # only a0 is returned
    assert len(r.json["aliases"]) == 1
    assert r.json["aliases"][0]["id"] == a0.id
Пример #26
0
def alias_transfer_receive_route():
    """
    URL has ?alias_id=signed_alias_id
    """
    token = request.args.get("token")
    alias = Alias.get_by(transfer_token=token)

    if not alias:
        flash("Invalid link", "error")
        return redirect(url_for("dashboard.index"))

    # alias already belongs to this user
    if alias.user_id == current_user.id:
        flash("You already own this alias", "warning")
        return redirect(url_for("dashboard.index"))

    mailboxes = current_user.mailboxes()

    if request.method == "POST":
        mailbox_ids = request.form.getlist("mailbox_ids")
        # check if mailbox is not tempered with
        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(request.url)
            mailboxes.append(mailbox)

        if not mailboxes:
            flash("You must select at least 1 mailbox", "warning")
            return redirect(request.url)

        LOG.d("transfer alias from %s to %s with %s", alias.user, current_user,
              mailboxes)
        transfer(alias, current_user, mailboxes)
        flash(f"You are now owner of {alias.email}", "success")
        return redirect(url_for("dashboard.index",
                                highlight_alias_id=alias.id))

    return render_template(
        "dashboard/alias_transfer_receive.html",
        alias=alias,
        mailboxes=mailboxes,
    )
def test_different_scenarios_v4(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()

    # <<< without hostname >>>
    r = flask_client.get(
        url_for("api.options_v4"), headers={"Authentication": api_key.code}
    )

    assert r.status_code == 200

    assert r.json["can_create"]
    assert r.json["suffixes"]
    assert r.json["prefix_suggestion"] == ""  # no hostname => no suggestion

    for (suffix, signed_suffix) in r.json["suffixes"]:
        assert signed_suffix.startswith(suffix)

    # <<< with hostname >>>
    r = flask_client.get(
        url_for("api.options_v4", hostname="www.test.com"),
        headers={"Authentication": api_key.code},
    )

    assert r.json["prefix_suggestion"] == "test"

    # <<< with recommendation >>>
    alias = Alias.create_new(user, prefix="test")
    db.session.commit()
    AliasUsedOn.create(
        alias_id=alias.id, hostname="www.test.com", user_id=alias.user_id
    )
    db.session.commit()

    r = flask_client.get(
        url_for("api.options_v4", hostname="www.test.com"),
        headers={"Authentication": api_key.code},
    )
    assert r.json["recommendation"]["alias"] == alias.email
    assert r.json["recommendation"]["hostname"] == "www.test.com"
Пример #28
0
def test_full_payload(flask_client):
    """Create alias with:
    - additional mailbox
    - note
    - name
    - hostname (in URL)
    """

    user = login(flask_client)

    # create another mailbox
    mb = Mailbox.create(user_id=user.id, email="*****@*****.**", verified=True)
    Session.commit()

    word = random_word()
    suffix = f".{word}@{EMAIL_DOMAIN}"
    signed_suffix = signer.sign(suffix).decode()

    assert AliasUsedOn.count() == 0

    r = flask_client.post(
        "/api/v3/alias/custom/new?hostname=example.com",
        json={
            "alias_prefix": "prefix",
            "signed_suffix": signed_suffix,
            "note": "test note",
            "mailbox_ids": [user.default_mailbox_id, mb.id],
            "name": "your name",
        },
    )

    assert r.status_code == 201
    assert r.json["alias"] == f"prefix.{word}@{EMAIL_DOMAIN}"

    # assert returned field
    res = r.json
    assert res["note"] == "test note"
    assert res["name"] == "your name"

    new_alias: Alias = Alias.get_by(email=r.json["alias"])
    assert new_alias.note == "test note"
    assert len(new_alias.mailboxes) == 2

    alias_used_on = AliasUsedOn.first()
    assert alias_used_on.alias_id == new_alias.id
    assert alias_used_on.hostname == "example.com"
Пример #29
0
def test_get_alias_infos_with_pagination_v3_query_alias_email(flask_client):
    """test the query on the alias email"""
    user = User.create(
        email="[email protected]",
        password="******",
        name="Test User",
        activated=True,
        commit=True,
    )

    alias = Alias.first()

    alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.email)
    assert len(alias_infos) == 1

    alias_infos = get_alias_infos_with_pagination_v3(user, query="no match")
    assert len(alias_infos) == 0
def test_different_scenarios_v2(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()

    # <<< without hostname >>>
    r = flask_client.get(
        url_for("api.options_v2"), headers={"Authentication": api_key.code}
    )

    assert r.status_code == 200
    # {'can_create': True, 'existing': ['*****@*****.**'], 'prefix_suggestion': '', 'suffixes': ['*****@*****.**']}

    assert r.json["can_create"]
    assert len(r.json["existing"]) == 1
    assert r.json["suffixes"]
    assert r.json["prefix_suggestion"] == ""  # no hostname => no suggestion

    # <<< with hostname >>>
    r = flask_client.get(
        url_for("api.options_v2", hostname="www.test.com"),
        headers={"Authentication": api_key.code},
    )

    assert r.json["prefix_suggestion"] == "test"

    # <<< with recommendation >>>
    alias = Alias.create_new(user, prefix="test")
    db.session.commit()
    AliasUsedOn.create(
        alias_id=alias.id, hostname="www.test.com", user_id=alias.user_id
    )
    db.session.commit()

    r = flask_client.get(
        url_for("api.options_v2", hostname="www.test.com"),
        headers={"Authentication": api_key.code},
    )
    assert r.json["recommendation"]["alias"] == alias.email
    assert r.json["recommendation"]["hostname"] == "www.test.com"