Esempio n. 1
0
def block_contact(contact_id):
    contact = Contact.get(contact_id)
    if not contact:
        flash("Incorrect link. Redirect you to the home page", "warning")
        return redirect(url_for("dashboard.index"))

    if contact.user_id != current_user.id:
        flash(
            "You don't have access to this page. Redirect you to the home page",
            "warning",
        )
        return redirect(url_for("dashboard.index"))

    # automatic unsubscribe, according to https://tools.ietf.org/html/rfc8058
    if request.method == "POST":
        contact.block_forward = True
        flash(f"Emails sent from {contact.website_email} are now blocked",
              "success")
        Session.commit()

        return redirect(
            url_for(
                "dashboard.alias_contact_manager",
                alias_id=contact.alias_id,
                highlight_contact_id=contact.id,
            ))
    else:  # ask user confirmation
        return render_template("dashboard/block_contact.html", contact=contact)
Esempio n. 2
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)
Esempio n. 3
0
def contact_detail_route(contact_id):
    contact = Contact.get(contact_id)
    if not contact or contact.user_id != current_user.id:
        flash("You cannot see this page", "warning")
        return redirect(url_for("dashboard.index"))

    alias = contact.alias

    if request.method == "POST":
        if request.form.get("form-name") == "pgp":
            if request.form.get("action") == "save":
                if not current_user.is_premium():
                    flash("Only premium plan can add PGP Key", "warning")
                    return redirect(
                        url_for("dashboard.contact_detail_route",
                                contact_id=contact_id))

                contact.pgp_public_key = request.form.get("pgp")
                try:
                    contact.pgp_finger_print = load_public_key_and_check(
                        contact.pgp_public_key)
                except PGPException:
                    flash("Cannot add the public key, please verify it",
                          "error")
                else:
                    db.session.commit()
                    flash(
                        f"PGP public key for {contact.email} is saved successfully",
                        "success",
                    )
                    return redirect(
                        url_for("dashboard.contact_detail_route",
                                contact_id=contact_id))
            elif request.form.get("action") == "remove":
                # Free user can decide to remove contact PGP key
                contact.pgp_public_key = None
                contact.pgp_finger_print = None
                db.session.commit()
                flash(f"PGP public key for {contact.email} is removed",
                      "success")
                return redirect(
                    url_for("dashboard.contact_detail_route",
                            contact_id=contact_id))

    return render_template("dashboard/contact_detail.html",
                           contact=contact,
                           alias=alias)
Esempio n. 4
0
def delete_contact(contact_id):
    """
    Delete contact
    Input:
        contact_id: in url
    Output:
        200
    """
    user = g.user
    contact = Contact.get(contact_id)

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

    Contact.delete(contact_id)
    db.session.commit()

    return jsonify(deleted=True), 200
Esempio n. 5
0
def toggle_contact(contact_id):
    """
    Block/Unblock contact
    Input:
        contact_id: in url
    Output:
        200
    """
    user = g.user
    contact = Contact.get(contact_id)

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

    contact.block_forward = not contact.block_forward
    Session.commit()

    return jsonify(block_forward=contact.block_forward), 200
Esempio n. 6
0
def toggle_contact(contact_id):
    """
    Block/Unblock contact
    """
    contact = Contact.get(contact_id)

    if not contact or contact.alias.user_id != current_user.id:
        return "Forbidden", 403

    contact.block_forward = not contact.block_forward
    Session.commit()

    if contact.block_forward:
        toast_msg = f"{contact.website_email} can no longer send emails to {contact.alias.email}"
    else:
        toast_msg = (
            f"{contact.website_email} can now send emails to {contact.alias.email}"
        )

    return render_template("partials/toggle_contact.html",
                           contact=contact,
                           toast_msg=toast_msg)
Esempio n. 7
0
def alias_contact_manager(alias_id):
    highlight_contact_id = None
    if request.args.get("highlight_contact_id"):
        highlight_contact_id = int(request.args.get("highlight_contact_id"))

    alias = Alias.get(alias_id)

    page = 0
    if request.args.get("page"):
        page = int(request.args.get("page"))

    query = request.args.get("query") or ""

    # sanity check
    if not alias:
        flash("You do not have access to this page", "warning")
        return redirect(url_for("dashboard.index"))

    if alias.user_id != current_user.id:
        flash("You do not have access to this page", "warning")
        return redirect(url_for("dashboard.index"))

    new_contact_form = NewContactForm()

    if request.method == "POST":
        if request.form.get("form-name") == "create":
            if new_contact_form.validate():
                contact_addr = new_contact_form.email.data.strip()

                try:
                    contact_name, contact_email = parseaddr_unicode(
                        contact_addr)
                    contact_email = sanitize_email(contact_email)
                except Exception:
                    flash(f"{contact_addr} is invalid", "error")
                    return redirect(
                        url_for(
                            "dashboard.alias_contact_manager",
                            alias_id=alias_id,
                        ))

                if not is_valid_email(contact_email):
                    flash(f"{contact_email} is invalid", "error")
                    return redirect(
                        url_for(
                            "dashboard.alias_contact_manager",
                            alias_id=alias_id,
                        ))

                contact = Contact.get_by(alias_id=alias.id,
                                         website_email=contact_email)
                # already been added
                if contact:
                    flash(f"{contact_email} is already added", "error")
                    return redirect(
                        url_for(
                            "dashboard.alias_contact_manager",
                            alias_id=alias_id,
                            highlight_contact_id=contact.id,
                        ))

                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,
                                                     current_user),
                )

                LOG.d("create reverse-alias for %s", contact_addr)
                db.session.commit()
                flash(f"Reverse alias for {contact_addr} is created",
                      "success")

                return redirect(
                    url_for(
                        "dashboard.alias_contact_manager",
                        alias_id=alias_id,
                        highlight_contact_id=contact.id,
                    ))
        elif request.form.get("form-name") == "delete":
            contact_id = request.form.get("contact-id")
            contact = Contact.get(contact_id)

            if not contact:
                flash("Unknown error. Refresh the page", "warning")
                return redirect(
                    url_for("dashboard.alias_contact_manager",
                            alias_id=alias_id))
            elif contact.alias_id != alias.id:
                flash("You cannot delete reverse-alias", "warning")
                return redirect(
                    url_for("dashboard.alias_contact_manager",
                            alias_id=alias_id))

            delete_contact_email = contact.website_email
            Contact.delete(contact_id)
            db.session.commit()

            flash(f"Reverse-alias for {delete_contact_email} has been deleted",
                  "success")

            return redirect(
                url_for("dashboard.alias_contact_manager", alias_id=alias_id))

        elif request.form.get("form-name") == "search":
            query = request.form.get("query")
            return redirect(
                url_for(
                    "dashboard.alias_contact_manager",
                    alias_id=alias_id,
                    query=query,
                    highlight_contact_id=highlight_contact_id,
                ))

    contact_infos = get_contact_infos(alias, page, query=query)
    last_page = len(contact_infos) < PAGE_LIMIT

    # if highlighted contact isn't included, fetch it
    # make sure highlighted contact is at array start
    contact_ids = [contact_info.contact.id for contact_info in contact_infos]
    if highlight_contact_id and highlight_contact_id not in contact_ids:
        contact_infos = (get_contact_infos(
            alias, contact_id=highlight_contact_id, query=query) +
                         contact_infos)

    return render_template(
        "dashboard/alias_contact_manager.html",
        contact_infos=contact_infos,
        alias=alias,
        new_contact_form=new_contact_form,
        highlight_contact_id=highlight_contact_id,
        page=page,
        last_page=last_page,
        query=query,
    )
Esempio n. 8
0
def alias_contact_manager(alias_id):
    highlight_contact_id = None
    if request.args.get("highlight_contact_id"):
        highlight_contact_id = int(request.args.get("highlight_contact_id"))

    alias = Alias.get(alias_id)

    # sanity check
    if not alias:
        flash("You do not have access to this page", "warning")
        return redirect(url_for("dashboard.index"))

    if alias.user_id != current_user.id:
        flash("You do not have access to this page", "warning")
        return redirect(url_for("dashboard.index"))

    new_contact_form = NewContactForm()

    if request.method == "POST":
        if request.form.get("form-name") == "create":
            if new_contact_form.validate():
                contact_addr = new_contact_form.email.data.strip()

                # 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

                try:
                    contact_name, contact_email = parseaddr_unicode(
                        contact_addr)
                except Exception:
                    flash(f"{contact_addr} is invalid", "error")
                    return redirect(
                        url_for(
                            "dashboard.alias_contact_manager",
                            alias_id=alias_id,
                        ))
                contact_email = contact_email.lower()

                contact = Contact.get_by(alias_id=alias.id,
                                         website_email=contact_email)
                # already been added
                if contact:
                    flash(f"{contact_email} is already added", "error")
                    return redirect(
                        url_for(
                            "dashboard.alias_contact_manager",
                            alias_id=alias_id,
                            highlight_contact_id=contact.id,
                        ))

                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", contact_addr)
                db.session.commit()
                flash(f"Reverse alias for {contact_addr} is created",
                      "success")

                return redirect(
                    url_for(
                        "dashboard.alias_contact_manager",
                        alias_id=alias_id,
                        highlight_contact_id=contact.id,
                    ))
        elif request.form.get("form-name") == "delete":
            contact_id = request.form.get("contact-id")
            contact = Contact.get(contact_id)

            if not contact:
                flash("Unknown error. Refresh the page", "warning")
                return redirect(
                    url_for("dashboard.alias_contact_manager",
                            alias_id=alias_id))
            elif contact.alias_id != alias.id:
                flash("You cannot delete reverse-alias", "warning")
                return redirect(
                    url_for("dashboard.alias_contact_manager",
                            alias_id=alias_id))

            delete_contact_email = contact.website_email
            Contact.delete(contact_id)
            db.session.commit()

            flash(f"Reverse-alias for {delete_contact_email} has been deleted",
                  "success")

            return redirect(
                url_for("dashboard.alias_contact_manager", alias_id=alias_id))

    # make sure highlighted contact is at array start
    contacts = alias.contacts

    if highlight_contact_id:
        contacts = sorted(contacts,
                          key=lambda fe: fe.id == highlight_contact_id,
                          reverse=True)

    return render_template(
        "dashboard/alias_contact_manager.html",
        contacts=contacts,
        alias=alias,
        new_contact_form=new_contact_form,
        highlight_contact_id=highlight_contact_id,
    )