2023-04-09 13:52:55 +00:00
|
|
|
from canaille.app import obj_to_b64
|
|
|
|
from canaille.app.flask import permissions_needed
|
2023-07-21 12:50:04 +00:00
|
|
|
from canaille.app.forms import Form
|
2023-07-20 16:43:28 +00:00
|
|
|
from canaille.core.mails import build_hash
|
2023-04-09 11:34:38 +00:00
|
|
|
from canaille.core.mails import send_test_mail
|
2021-12-20 22:57:27 +00:00
|
|
|
from flask import Blueprint
|
|
|
|
from flask import current_app
|
2021-12-23 18:21:29 +00:00
|
|
|
from flask import flash
|
|
|
|
from flask import request
|
2021-12-20 22:57:27 +00:00
|
|
|
from flask import url_for
|
|
|
|
from flask_babel import gettext as _
|
|
|
|
from flask_themer import render_template
|
2021-12-23 18:21:29 +00:00
|
|
|
from wtforms import StringField
|
|
|
|
from wtforms.validators import DataRequired
|
|
|
|
from wtforms.validators import Email
|
2020-10-29 11:00:19 +00:00
|
|
|
|
|
|
|
|
2022-01-11 20:11:54 +00:00
|
|
|
bp = Blueprint("admin", __name__, url_prefix="/admin")
|
2020-10-29 11:00:19 +00:00
|
|
|
|
|
|
|
|
2023-07-21 12:50:04 +00:00
|
|
|
class MailTestForm(Form):
|
2023-02-05 17:57:18 +00:00
|
|
|
email = StringField(
|
2021-12-23 18:21:29 +00:00
|
|
|
_("Email"),
|
|
|
|
validators=[
|
|
|
|
DataRequired(),
|
|
|
|
Email(),
|
|
|
|
],
|
|
|
|
render_kw={
|
|
|
|
"placeholder": _("jane@doe.com"),
|
|
|
|
"spellcheck": "false",
|
|
|
|
"autocorrect": "off",
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-01-11 20:11:54 +00:00
|
|
|
@bp.route("/mail", methods=["GET", "POST"])
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2021-12-02 11:05:24 +00:00
|
|
|
def mail_index(user):
|
2021-12-23 18:21:29 +00:00
|
|
|
form = MailTestForm(request.form or None)
|
|
|
|
if request.form and form.validate():
|
2023-02-05 17:57:18 +00:00
|
|
|
if send_test_mail(form.email.data):
|
2021-12-23 18:21:29 +00:00
|
|
|
flash(_("The test invitation mail has been sent correctly"), "success")
|
|
|
|
else:
|
2022-12-04 16:15:48 +00:00
|
|
|
flash(_("The test invitation mail has not been sent correctly"), "error")
|
2021-12-23 18:21:29 +00:00
|
|
|
|
2022-02-25 12:58:35 +00:00
|
|
|
return render_template("mail/admin.html", form=form, menuitem="admin")
|
2021-12-02 11:05:24 +00:00
|
|
|
|
|
|
|
|
2023-01-22 11:48:15 +00:00
|
|
|
@bp.route("/mail/test.html")
|
|
|
|
@permissions_needed("manage_oidc")
|
|
|
|
def test_html(user):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2023-01-22 11:48:15 +00:00
|
|
|
return render_template(
|
|
|
|
"mail/test.html",
|
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
|
|
|
site_url=base_url,
|
|
|
|
logo=current_app.config.get("LOGO"),
|
2023-07-01 17:56:13 +00:00
|
|
|
title=_("Test email from {website_name}").format(
|
|
|
|
website_name=current_app.config.get("NAME", "Canaille"),
|
|
|
|
),
|
2023-01-22 11:48:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@bp.route("/mail/test.txt")
|
|
|
|
@permissions_needed("manage_oidc")
|
|
|
|
def test_txt(user):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2023-01-22 11:48:15 +00:00
|
|
|
return render_template(
|
|
|
|
"mail/test.txt",
|
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
|
|
|
site_url=current_app.config.get("SERVER_NAME", base_url),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-01-11 20:11:54 +00:00
|
|
|
@bp.route("/mail/password-init.html")
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2021-12-02 11:05:24 +00:00
|
|
|
def password_init_html(user):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2021-12-02 11:05:24 +00:00
|
|
|
reset_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.reset",
|
2023-06-28 15:56:49 +00:00
|
|
|
user=user,
|
2023-07-20 16:43:28 +00:00
|
|
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
2023-07-01 17:56:13 +00:00
|
|
|
title=_("Password initialization on {website_name}").format(
|
|
|
|
website_name=current_app.config.get("NAME", "Canaille")
|
|
|
|
),
|
2021-12-02 11:05:24 +00:00
|
|
|
_external=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/firstlogin.html",
|
2023-07-01 18:02:53 +00:00
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
2021-12-02 11:05:24 +00:00
|
|
|
site_url=base_url,
|
|
|
|
reset_url=reset_url,
|
|
|
|
logo=current_app.config.get("LOGO"),
|
|
|
|
title=_("Password initialization on {website_name}").format(
|
2023-07-01 17:56:13 +00:00
|
|
|
website_name=current_app.config.get("NAME", "Canaille")
|
2021-12-02 11:05:24 +00:00
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-01-11 20:11:54 +00:00
|
|
|
@bp.route("/mail/password-init.txt")
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2021-12-02 11:05:24 +00:00
|
|
|
def password_init_txt(user):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2021-12-02 11:05:24 +00:00
|
|
|
reset_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.reset",
|
2023-06-28 15:56:49 +00:00
|
|
|
user=user,
|
2023-07-20 16:43:28 +00:00
|
|
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
2021-12-02 11:05:24 +00:00
|
|
|
_external=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/firstlogin.txt",
|
2023-07-01 17:56:13 +00:00
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
2021-12-02 11:05:24 +00:00
|
|
|
site_url=current_app.config.get("SERVER_NAME", base_url),
|
|
|
|
reset_url=reset_url,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-01-11 20:11:54 +00:00
|
|
|
@bp.route("/mail/reset.html")
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2021-12-02 11:05:24 +00:00
|
|
|
def password_reset_html(user):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2020-10-29 12:20:27 +00:00
|
|
|
reset_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.reset",
|
2023-06-28 15:56:49 +00:00
|
|
|
user=user,
|
2023-07-20 16:43:28 +00:00
|
|
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
2023-07-01 17:56:13 +00:00
|
|
|
title=_("Password reset on {website_name}").format(
|
2023-07-01 18:02:53 +00:00
|
|
|
website_name=current_app.config.get("NAME", "Canaille")
|
2023-07-01 17:56:13 +00:00
|
|
|
),
|
2020-10-29 12:20:27 +00:00
|
|
|
_external=True,
|
|
|
|
)
|
2020-10-29 11:00:19 +00:00
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/reset.html",
|
2023-07-01 18:02:53 +00:00
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
2020-10-29 12:20:27 +00:00
|
|
|
site_url=base_url,
|
2020-10-29 11:00:19 +00:00
|
|
|
reset_url=reset_url,
|
2020-12-10 16:42:58 +00:00
|
|
|
logo=current_app.config.get("LOGO"),
|
2020-12-10 15:34:46 +00:00
|
|
|
title=_("Password reset on {website_name}").format(
|
2023-07-01 18:02:53 +00:00
|
|
|
website_name=current_app.config.get("NAME", "Canaille")
|
2020-12-10 15:34:46 +00:00
|
|
|
),
|
2020-10-29 11:00:19 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-01-11 20:11:54 +00:00
|
|
|
@bp.route("/mail/reset.txt")
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2021-12-02 11:05:24 +00:00
|
|
|
def password_reset_txt(user):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2020-10-29 12:20:27 +00:00
|
|
|
reset_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.reset",
|
2023-06-28 15:56:49 +00:00
|
|
|
user=user,
|
2023-07-20 16:43:28 +00:00
|
|
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
2020-10-29 12:20:27 +00:00
|
|
|
_external=True,
|
|
|
|
)
|
2020-10-29 11:00:19 +00:00
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/reset.txt",
|
2023-07-01 18:02:53 +00:00
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
2020-10-29 12:20:27 +00:00
|
|
|
site_url=current_app.config.get("SERVER_NAME", base_url),
|
2020-10-29 11:00:19 +00:00
|
|
|
reset_url=reset_url,
|
|
|
|
)
|
2021-12-01 11:19:28 +00:00
|
|
|
|
|
|
|
|
2023-06-27 15:41:00 +00:00
|
|
|
@bp.route("/mail/<identifier>/<email>/invitation.html")
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2023-06-27 15:41:00 +00:00
|
|
|
def invitation_html(user, identifier, email):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2021-12-01 11:19:28 +00:00
|
|
|
registration_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.registration",
|
2023-06-27 15:41:00 +00:00
|
|
|
data=obj_to_b64([identifier, email]),
|
2023-07-20 16:43:28 +00:00
|
|
|
hash=build_hash(identifier, email),
|
2021-12-01 11:19:28 +00:00
|
|
|
_external=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/invitation.html",
|
2023-07-01 18:02:53 +00:00
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
2021-12-01 11:19:28 +00:00
|
|
|
site_url=base_url,
|
|
|
|
registration_url=registration_url,
|
|
|
|
logo=current_app.config.get("LOGO"),
|
|
|
|
title=_("Invitation on {website_name}").format(
|
2023-07-01 18:02:53 +00:00
|
|
|
website_name=current_app.config.get("NAME", "Canaille")
|
2021-12-01 11:19:28 +00:00
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-06-27 15:41:00 +00:00
|
|
|
@bp.route("/mail/<identifier>/<email>/invitation.txt")
|
2021-12-02 17:23:14 +00:00
|
|
|
@permissions_needed("manage_oidc")
|
2023-06-27 15:41:00 +00:00
|
|
|
def invitation_txt(user, identifier, email):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2021-12-01 11:19:28 +00:00
|
|
|
registration_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.registration",
|
2023-06-27 15:41:00 +00:00
|
|
|
data=obj_to_b64([identifier, email]),
|
2023-07-20 16:43:28 +00:00
|
|
|
hash=build_hash(identifier, email),
|
2021-12-01 11:19:28 +00:00
|
|
|
_external=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/invitation.txt",
|
2023-07-01 18:02:53 +00:00
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
2021-12-01 11:19:28 +00:00
|
|
|
site_url=base_url,
|
|
|
|
registration_url=registration_url,
|
|
|
|
)
|
2023-07-20 16:43:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
@bp.route("/mail/<identifier>/<email>/email-confirmation.html")
|
|
|
|
@permissions_needed("manage_oidc")
|
|
|
|
def email_confirmation_html(user, identifier, email):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2023-07-20 16:43:28 +00:00
|
|
|
email_confirmation_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.email_confirmation",
|
2023-07-20 16:43:28 +00:00
|
|
|
data=obj_to_b64([identifier, email]),
|
|
|
|
hash=build_hash(identifier, email),
|
|
|
|
_external=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/email-confirmation.html",
|
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
|
|
|
site_url=base_url,
|
|
|
|
confirmation_url=email_confirmation_url,
|
|
|
|
logo=current_app.config.get("LOGO"),
|
|
|
|
title=_("Email confirmation on {website_name}").format(
|
|
|
|
website_name=current_app.config.get("NAME", "Canaille")
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@bp.route("/mail/<identifier>/<email>/email-confirmation.txt")
|
|
|
|
@permissions_needed("manage_oidc")
|
|
|
|
def email_confirmation_txt(user, identifier, email):
|
2023-08-14 11:52:24 +00:00
|
|
|
base_url = url_for("core.account.index", _external=True)
|
2023-07-20 16:43:28 +00:00
|
|
|
email_confirmation_url = url_for(
|
2023-08-14 11:52:24 +00:00
|
|
|
"core.account.email_confirmation",
|
2023-07-20 16:43:28 +00:00
|
|
|
data=obj_to_b64([identifier, email]),
|
|
|
|
hash=build_hash(identifier, email),
|
|
|
|
_external=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
"mail/email-confirmation.txt",
|
|
|
|
site_name=current_app.config.get("NAME", "Canaille"),
|
|
|
|
site_url=base_url,
|
|
|
|
confirmation_url=email_confirmation_url,
|
|
|
|
)
|