app-MAIL-temp/app/dashboard/views/alias_contact_manager.py

172 lines
5.9 KiB
Python
Raw Normal View History

2019-12-15 16:17:37 +01:00
import re
from flask import render_template, request, redirect, url_for, flash
from flask_login import login_required, current_user
from flask_wtf import FlaskForm
from wtforms import StringField, validators, ValidationError
2020-05-23 22:34:46 +02:00
from app.config import EMAIL_DOMAIN, PAGE_LIMIT
2019-12-15 16:17:37 +01:00
from app.dashboard.base import dashboard_bp
from app.email_utils import parseaddr_unicode
2019-12-15 16:17:37 +01:00
from app.extensions import db
from app.log import LOG
from app.models import Alias, Contact
2019-12-15 16:17:37 +01:00
from app.utils import random_string
def email_validator():
"""validate email address. Handle both only email and email with name:
- ab@cd.com
- AB CD <ab@cd.com>
"""
message = "Invalid email format. Email must be either email@example.com or *First Last <email@example.com>*"
def _check(form, field):
email = field.data
2020-02-18 05:54:51 +01:00
email = email.strip()
2019-12-15 16:17:37 +01:00
email_part = email
if "<" in email and ">" in email:
if email.find("<") + 1 < email.find(">"):
email_part = email[email.find("<") + 1 : email.find(">")].strip()
if re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", email_part):
return
raise ValidationError(message)
return _check
class NewContactForm(FlaskForm):
email = StringField(
"Email", validators=[validators.DataRequired(), email_validator()]
)
@dashboard_bp.route("/alias_contact_manager/<alias_id>/", methods=["GET", "POST"])
2019-12-15 16:17:37 +01:00
@login_required
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)
2019-12-15 16:17:37 +01:00
2020-05-23 22:34:46 +02:00
page = 0
if request.args.get("page"):
page = int(request.args.get("page"))
2019-12-15 16:17:37 +01:00
# sanity check
if not alias:
2019-12-15 16:17:37 +01:00
flash("You do not have access to this page", "warning")
return redirect(url_for("dashboard.index"))
if alias.user_id != current_user.id:
2019-12-15 16:17:37 +01:00
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():
2020-06-11 23:35:24 +02:00
contact_addr = new_contact_form.email.data.strip().lower()
2019-12-15 16:17:37 +01:00
# generate a reply_email, make sure it is unique
# not use while to avoid infinite loop
2020-03-17 10:56:59 +01:00
reply_email = f"ra+{random_string(25)}@{EMAIL_DOMAIN}"
2019-12-15 16:17:37 +01:00
for _ in range(1000):
reply_email = f"ra+{random_string(25)}@{EMAIL_DOMAIN}"
2020-03-17 10:56:59 +01:00
if not Contact.get_by(reply_email=reply_email):
2019-12-15 16:17:37 +01:00
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,)
)
2020-04-05 12:19:17 +02:00
contact_email = contact_email.lower()
2019-12-15 16:17:37 +01:00
2020-04-05 12:19:17 +02:00
contact = Contact.get_by(alias_id=alias.id, website_email=contact_email)
2019-12-15 16:17:37 +01:00
# already been added
if contact:
2020-04-05 12:19:17 +02:00
flash(f"{contact_email} is already added", "error")
2019-12-15 16:17:37 +01:00
return redirect(
url_for(
"dashboard.alias_contact_manager",
alias_id=alias_id,
highlight_contact_id=contact.id,
)
2019-12-15 16:17:37 +01:00
)
2020-03-17 10:56:59 +01:00
contact = Contact.create(
user_id=alias.user_id,
2020-03-17 12:01:18 +01:00
alias_id=alias.id,
2020-04-05 12:19:17 +02:00
website_email=contact_email,
name=contact_name,
2019-12-15 16:17:37 +01:00
reply_email=reply_email,
)
2020-04-05 12:19:17 +02:00
LOG.d("create reverse-alias for %s", contact_addr)
2019-12-15 16:17:37 +01:00
db.session.commit()
2020-04-05 12:19:17 +02:00
flash(f"Reverse alias for {contact_addr} is created", "success")
2019-12-15 16:17:37 +01:00
return redirect(
url_for(
"dashboard.alias_contact_manager",
alias_id=alias_id,
highlight_contact_id=contact.id,
2019-12-15 16:17:37 +01:00
)
)
elif request.form.get("form-name") == "delete":
2020-03-17 10:56:59 +01:00
contact_id = request.form.get("contact-id")
contact = Contact.get(contact_id)
2019-12-15 16:17:37 +01:00
2020-03-17 10:56:59 +01:00
if not contact:
2019-12-15 16:17:37 +01:00
flash("Unknown error. Refresh the page", "warning")
return redirect(
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
)
2020-03-17 12:01:18 +01:00
elif contact.alias_id != alias.id:
2019-12-15 16:17:37 +01:00
flash("You cannot delete reverse-alias", "warning")
return redirect(
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
)
2019-12-15 16:17:37 +01:00
2020-04-05 15:39:48 +02:00
delete_contact_email = contact.website_email
2020-03-17 10:56:59 +01:00
Contact.delete(contact_id)
2019-12-15 16:17:37 +01:00
db.session.commit()
2020-04-05 15:39:48 +02:00
flash(
f"Reverse-alias for {delete_contact_email} has been deleted", "success"
)
2019-12-15 16:17:37 +01:00
return redirect(
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
)
2019-12-15 16:17:37 +01:00
2020-03-17 10:56:59 +01:00
# make sure highlighted contact is at array start
2020-05-23 22:34:46 +02:00
contacts = alias.get_contacts(page)
contact_ids = [contact.id for contact in contacts]
last_page = len(contacts) < PAGE_LIMIT
2019-12-15 16:17:37 +01:00
2020-05-23 22:34:46 +02:00
if highlight_contact_id not in contact_ids:
contact = Contact.get(highlight_contact_id)
if contact and contact.alias_id == alias.id:
contacts.insert(0, contact)
2019-12-15 16:17:37 +01:00
return render_template(
"dashboard/alias_contact_manager.html",
2020-03-17 10:56:59 +01:00
contacts=contacts,
alias=alias,
2019-12-15 16:17:37 +01:00
new_contact_form=new_contact_form,
highlight_contact_id=highlight_contact_id,
2020-05-23 22:34:46 +02:00
page=page,
last_page=last_page,
2019-12-15 16:17:37 +01:00
)