forked from Github-Mirrors/canaille
refactor: the core module has its own main blueprint
This commit is contained in:
parent
c6a543535c
commit
d27aab8651
40 changed files with 166 additions and 151 deletions
|
@ -84,16 +84,12 @@ def setup_themer(app):
|
||||||
|
|
||||||
|
|
||||||
def setup_blueprints(app):
|
def setup_blueprints(app):
|
||||||
import canaille.core.account
|
import canaille.core.blueprints
|
||||||
import canaille.core.admin
|
|
||||||
import canaille.core.groups
|
|
||||||
import canaille.oidc.blueprints
|
import canaille.oidc.blueprints
|
||||||
|
|
||||||
app.url_map.strict_slashes = False
|
app.url_map.strict_slashes = False
|
||||||
|
|
||||||
app.register_blueprint(canaille.core.account.bp)
|
app.register_blueprint(canaille.core.blueprints.bp)
|
||||||
app.register_blueprint(canaille.core.admin.bp)
|
|
||||||
app.register_blueprint(canaille.core.groups.bp)
|
|
||||||
app.register_blueprint(canaille.oidc.blueprints.bp)
|
app.register_blueprint(canaille.oidc.blueprints.bp)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ WRITE = [
|
||||||
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||||
# LOCALE = "{{ user.preferred_language }}"
|
# LOCALE = "{{ user.preferred_language }}"
|
||||||
# ADDRESS = "{{ user.formatted_address[0] }}"
|
# ADDRESS = "{{ user.formatted_address[0] }}"
|
||||||
# PICTURE = "{% if user.photo %}{{ url_for('account.photo', user=user, field='photo', _external=True) }}{% endif %}"
|
# PICTURE = "{% if user.photo %}{{ url_for('core.account.photo', user=user, field='photo', _external=True) }}{% endif %}"
|
||||||
# WEBSITE = "{{ user.profile_url[0] }}"
|
# WEBSITE = "{{ user.profile_url[0] }}"
|
||||||
|
|
||||||
# The SMTP server options. If not set, mail related features such as
|
# The SMTP server options. If not set, mail related features such as
|
||||||
|
|
|
@ -62,15 +62,15 @@ def index():
|
||||||
user = current_user()
|
user = current_user()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
return redirect(url_for("account.login"))
|
return redirect(url_for("core.account.login"))
|
||||||
|
|
||||||
if user.can_edit_self or user.can_manage_users:
|
if user.can_edit_self or user.can_manage_users:
|
||||||
return redirect(url_for("account.profile_edition", edited_user=user))
|
return redirect(url_for("core.account.profile_edition", edited_user=user))
|
||||||
|
|
||||||
if user.can_use_oidc:
|
if user.can_use_oidc:
|
||||||
return redirect(url_for("oidc.consents.consents"))
|
return redirect(url_for("oidc.consents.consents"))
|
||||||
|
|
||||||
return redirect(url_for("account.about"))
|
return redirect(url_for("core.account.about"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/about")
|
@bp.route("/about")
|
||||||
|
@ -85,7 +85,9 @@ def about():
|
||||||
@bp.route("/login", methods=("GET", "POST"))
|
@bp.route("/login", methods=("GET", "POST"))
|
||||||
def login():
|
def login():
|
||||||
if current_user():
|
if current_user():
|
||||||
return redirect(url_for("account.profile_edition", edited_user=current_user()))
|
return redirect(
|
||||||
|
url_for("core.account.profile_edition", edited_user=current_user())
|
||||||
|
)
|
||||||
|
|
||||||
form = LoginForm(request.form or None)
|
form = LoginForm(request.form or None)
|
||||||
form.render_field_macro_file = "partial/login_field.html"
|
form.render_field_macro_file = "partial/login_field.html"
|
||||||
|
@ -96,7 +98,7 @@ def login():
|
||||||
|
|
||||||
user = models.User.get_from_login(form.login.data)
|
user = models.User.get_from_login(form.login.data)
|
||||||
if user and not user.has_password():
|
if user and not user.has_password():
|
||||||
return redirect(url_for("account.firstlogin", user=user))
|
return redirect(url_for("core.account.firstlogin", user=user))
|
||||||
|
|
||||||
if not form.validate():
|
if not form.validate():
|
||||||
models.User.logout()
|
models.User.logout()
|
||||||
|
@ -104,13 +106,13 @@ def login():
|
||||||
return render_template("login.html", form=form)
|
return render_template("login.html", form=form)
|
||||||
|
|
||||||
session["attempt_login"] = form.login.data
|
session["attempt_login"] = form.login.data
|
||||||
return redirect(url_for("account.password"))
|
return redirect(url_for("core.account.password"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/password", methods=("GET", "POST"))
|
@bp.route("/password", methods=("GET", "POST"))
|
||||||
def password():
|
def password():
|
||||||
if "attempt_login" not in session:
|
if "attempt_login" not in session:
|
||||||
return redirect(url_for("account.login"))
|
return redirect(url_for("core.account.login"))
|
||||||
|
|
||||||
form = PasswordForm(request.form or None)
|
form = PasswordForm(request.form or None)
|
||||||
form.render_field_macro_file = "partial/login_field.html"
|
form.render_field_macro_file = "partial/login_field.html"
|
||||||
|
@ -122,7 +124,7 @@ def password():
|
||||||
|
|
||||||
user = models.User.get_from_login(session["attempt_login"])
|
user = models.User.get_from_login(session["attempt_login"])
|
||||||
if user and not user.has_password():
|
if user and not user.has_password():
|
||||||
return redirect(url_for("account.firstlogin", user=user))
|
return redirect(url_for("core.account.firstlogin", user=user))
|
||||||
|
|
||||||
if not form.validate() or not user:
|
if not form.validate() or not user:
|
||||||
models.User.logout()
|
models.User.logout()
|
||||||
|
@ -145,7 +147,7 @@ def password():
|
||||||
_("Connection successful. Welcome %(user)s", user=user.formatted_name[0]),
|
_("Connection successful. Welcome %(user)s", user=user.formatted_name[0]),
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/logout")
|
@bp.route("/logout")
|
||||||
|
@ -266,7 +268,7 @@ def user_invitation(user):
|
||||||
form.groups.data,
|
form.groups.data,
|
||||||
)
|
)
|
||||||
registration_url = url_for(
|
registration_url = url_for(
|
||||||
"account.registration",
|
"core.account.registration",
|
||||||
data=invitation.b64(),
|
data=invitation.b64(),
|
||||||
hash=invitation.build_hash(),
|
hash=invitation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -294,35 +296,35 @@ def registration(data, hash):
|
||||||
_("The invitation link that brought you here was invalid."),
|
_("The invitation link that brought you here was invalid."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if invitation.has_expired():
|
if invitation.has_expired():
|
||||||
flash(
|
flash(
|
||||||
_("The invitation link that brought you here has expired."),
|
_("The invitation link that brought you here has expired."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if models.User.get_from_login(invitation.user_name):
|
if models.User.get_from_login(invitation.user_name):
|
||||||
flash(
|
flash(
|
||||||
_("Your account has already been created."),
|
_("Your account has already been created."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if current_user():
|
if current_user():
|
||||||
flash(
|
flash(
|
||||||
_("You are already logged in, you cannot create an account."),
|
_("You are already logged in, you cannot create an account."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if hash != invitation.build_hash():
|
if hash != invitation.build_hash():
|
||||||
flash(
|
flash(
|
||||||
_("The invitation link that brought you here was invalid."),
|
_("The invitation link that brought you here was invalid."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"user_name": invitation.user_name,
|
"user_name": invitation.user_name,
|
||||||
|
@ -383,7 +385,7 @@ def registration(data, hash):
|
||||||
user = profile_create(current_app, form)
|
user = profile_create(current_app, form)
|
||||||
user.login()
|
user.login()
|
||||||
flash(_("Your account has been created successfully."), "success")
|
flash(_("Your account has been created successfully."), "success")
|
||||||
return redirect(url_for("account.profile_edition", edited_user=user))
|
return redirect(url_for("core.account.profile_edition", edited_user=user))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/email-confirmation/<data>/<hash>")
|
@bp.route("/email-confirmation/<data>/<hash>")
|
||||||
|
@ -395,21 +397,21 @@ def email_confirmation(data, hash):
|
||||||
_("The email confirmation link that brought you here is invalid."),
|
_("The email confirmation link that brought you here is invalid."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if confirmation_obj.has_expired():
|
if confirmation_obj.has_expired():
|
||||||
flash(
|
flash(
|
||||||
_("The email confirmation link that brought you here has expired."),
|
_("The email confirmation link that brought you here has expired."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if hash != confirmation_obj.build_hash():
|
if hash != confirmation_obj.build_hash():
|
||||||
flash(
|
flash(
|
||||||
_("The invitation link that brought you here was invalid."),
|
_("The invitation link that brought you here was invalid."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
user = models.User.get(confirmation_obj.identifier)
|
user = models.User.get(confirmation_obj.identifier)
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -417,26 +419,26 @@ def email_confirmation(data, hash):
|
||||||
_("The email confirmation link that brought you here is invalid."),
|
_("The email confirmation link that brought you here is invalid."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if confirmation_obj.email in user.emails:
|
if confirmation_obj.email in user.emails:
|
||||||
flash(
|
flash(
|
||||||
_("This address email have already been confirmed."),
|
_("This address email have already been confirmed."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if models.User.query(emails=confirmation_obj.email):
|
if models.User.query(emails=confirmation_obj.email):
|
||||||
flash(
|
flash(
|
||||||
_("This address email is already associated with another account."),
|
_("This address email is already associated with another account."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
user.emails = user.emails + [confirmation_obj.email]
|
user.emails = user.emails + [confirmation_obj.email]
|
||||||
user.save()
|
user.save()
|
||||||
flash(_("Your email address have been confirmed."), "success")
|
flash(_("Your email address have been confirmed."), "success")
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/profile", methods=("GET", "POST"))
|
@bp.route("/profile", methods=("GET", "POST"))
|
||||||
|
@ -469,7 +471,7 @@ def profile_creation(user):
|
||||||
)
|
)
|
||||||
|
|
||||||
user = profile_create(current_app, form)
|
user = profile_create(current_app, form)
|
||||||
return redirect(url_for("account.profile_edition", edited_user=user))
|
return redirect(url_for("core.account.profile_edition", edited_user=user))
|
||||||
|
|
||||||
|
|
||||||
def profile_create(current_app, form):
|
def profile_create(current_app, form):
|
||||||
|
@ -589,7 +591,7 @@ def profile_edition_add_email(user, edited_user, emails_form):
|
||||||
emails_form.new_email.data,
|
emails_form.new_email.data,
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash=email_confirmation.build_hash(),
|
hash=email_confirmation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -651,7 +653,9 @@ def profile_edition(user, edited_user):
|
||||||
|
|
||||||
profile_edition_main_form_validation(user, edited_user, profile_form)
|
profile_edition_main_form_validation(user, edited_user, profile_form)
|
||||||
flash(_("Profile updated successfully."), "success")
|
flash(_("Profile updated successfully."), "success")
|
||||||
return redirect(url_for("account.profile_edition", edited_user=edited_user))
|
return redirect(
|
||||||
|
url_for("core.account.profile_edition", edited_user=edited_user)
|
||||||
|
)
|
||||||
|
|
||||||
if request.form.get("action") == "add_email":
|
if request.form.get("action") == "add_email":
|
||||||
if not emails_form.validate():
|
if not emails_form.validate():
|
||||||
|
@ -669,7 +673,9 @@ def profile_edition(user, edited_user):
|
||||||
else:
|
else:
|
||||||
flash(_("Could not send the verification email"), "error")
|
flash(_("Could not send the verification email"), "error")
|
||||||
|
|
||||||
return redirect(url_for("account.profile_edition", edited_user=edited_user))
|
return redirect(
|
||||||
|
url_for("core.account.profile_edition", edited_user=edited_user)
|
||||||
|
)
|
||||||
|
|
||||||
if request.form.get("email_remove"):
|
if request.form.get("email_remove"):
|
||||||
if not profile_edition_remove_email(
|
if not profile_edition_remove_email(
|
||||||
|
@ -679,7 +685,9 @@ def profile_edition(user, edited_user):
|
||||||
return render_template("profile_edit.html", **render_context)
|
return render_template("profile_edit.html", **render_context)
|
||||||
|
|
||||||
flash(_("The email have been successfully deleted."), "success")
|
flash(_("The email have been successfully deleted."), "success")
|
||||||
return redirect(url_for("account.profile_edition", edited_user=edited_user))
|
return redirect(
|
||||||
|
url_for("core.account.profile_edition", edited_user=edited_user)
|
||||||
|
)
|
||||||
|
|
||||||
abort(400, f"bad form action: {request.form.get('action')}")
|
abort(400, f"bad form action: {request.form.get('action')}")
|
||||||
|
|
||||||
|
@ -819,7 +827,7 @@ def profile_settings_edit(editor, edited_user):
|
||||||
edited_user.save()
|
edited_user.save()
|
||||||
flash(_("Profile updated successfully."), "success")
|
flash(_("Profile updated successfully."), "success")
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for("account.profile_settings", edited_user=edited_user)
|
url_for("core.account.profile_settings", edited_user=edited_user)
|
||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
|
@ -846,8 +854,8 @@ def profile_delete(user, edited_user):
|
||||||
edited_user.delete()
|
edited_user.delete()
|
||||||
|
|
||||||
if self_deletion:
|
if self_deletion:
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
return redirect(url_for("account.users"))
|
return redirect(url_for("core.account.users"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/impersonate/<user:puppet>")
|
@bp.route("/impersonate/<user:puppet>")
|
||||||
|
@ -858,7 +866,7 @@ def impersonate(user, puppet):
|
||||||
_("Connection successful. Welcome %(user)s", user=puppet.formatted_name),
|
_("Connection successful. Welcome %(user)s", user=puppet.formatted_name),
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/reset", methods=["GET", "POST"])
|
@bp.route("/reset", methods=["GET", "POST"])
|
||||||
|
@ -929,14 +937,14 @@ def reset(user, hash):
|
||||||
_("The password reset link that brought you here was invalid."),
|
_("The password reset link that brought you here was invalid."),
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
if request.form and form.validate():
|
if request.form and form.validate():
|
||||||
user.set_password(form.password.data)
|
user.set_password(form.password.data)
|
||||||
user.login()
|
user.login()
|
||||||
|
|
||||||
flash(_("Your password has been updated successfully"), "success")
|
flash(_("Your password has been updated successfully"), "success")
|
||||||
return redirect(url_for("account.profile_edition", edited_user=user))
|
return redirect(url_for("core.account.profile_edition", edited_user=user))
|
||||||
|
|
||||||
return render_template("reset-password.html", form=form, user=user, hash=hash)
|
return render_template("reset-password.html", form=form, user=user, hash=hash)
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ def mail_index(user):
|
||||||
@bp.route("/mail/test.html")
|
@bp.route("/mail/test.html")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def test_html(user):
|
def test_html(user):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
return render_template(
|
return render_template(
|
||||||
"mail/test.html",
|
"mail/test.html",
|
||||||
site_name=current_app.config.get("NAME", "Canaille"),
|
site_name=current_app.config.get("NAME", "Canaille"),
|
||||||
|
@ -64,7 +64,7 @@ def test_html(user):
|
||||||
@bp.route("/mail/test.txt")
|
@bp.route("/mail/test.txt")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def test_txt(user):
|
def test_txt(user):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
return render_template(
|
return render_template(
|
||||||
"mail/test.txt",
|
"mail/test.txt",
|
||||||
site_name=current_app.config.get("NAME", "Canaille"),
|
site_name=current_app.config.get("NAME", "Canaille"),
|
||||||
|
@ -75,9 +75,9 @@ def test_txt(user):
|
||||||
@bp.route("/mail/password-init.html")
|
@bp.route("/mail/password-init.html")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def password_init_html(user):
|
def password_init_html(user):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
reset_url = url_for(
|
reset_url = url_for(
|
||||||
"account.reset",
|
"core.account.reset",
|
||||||
user=user,
|
user=user,
|
||||||
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
||||||
title=_("Password initialization on {website_name}").format(
|
title=_("Password initialization on {website_name}").format(
|
||||||
|
@ -101,9 +101,9 @@ def password_init_html(user):
|
||||||
@bp.route("/mail/password-init.txt")
|
@bp.route("/mail/password-init.txt")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def password_init_txt(user):
|
def password_init_txt(user):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
reset_url = url_for(
|
reset_url = url_for(
|
||||||
"account.reset",
|
"core.account.reset",
|
||||||
user=user,
|
user=user,
|
||||||
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -120,9 +120,9 @@ def password_init_txt(user):
|
||||||
@bp.route("/mail/reset.html")
|
@bp.route("/mail/reset.html")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def password_reset_html(user):
|
def password_reset_html(user):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
reset_url = url_for(
|
reset_url = url_for(
|
||||||
"account.reset",
|
"core.account.reset",
|
||||||
user=user,
|
user=user,
|
||||||
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
||||||
title=_("Password reset on {website_name}").format(
|
title=_("Password reset on {website_name}").format(
|
||||||
|
@ -146,9 +146,9 @@ def password_reset_html(user):
|
||||||
@bp.route("/mail/reset.txt")
|
@bp.route("/mail/reset.txt")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def password_reset_txt(user):
|
def password_reset_txt(user):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
reset_url = url_for(
|
reset_url = url_for(
|
||||||
"account.reset",
|
"core.account.reset",
|
||||||
user=user,
|
user=user,
|
||||||
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
hash=build_hash(user.identifier, user.preferred_email, user.password[0]),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -165,9 +165,9 @@ def password_reset_txt(user):
|
||||||
@bp.route("/mail/<identifier>/<email>/invitation.html")
|
@bp.route("/mail/<identifier>/<email>/invitation.html")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def invitation_html(user, identifier, email):
|
def invitation_html(user, identifier, email):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
registration_url = url_for(
|
registration_url = url_for(
|
||||||
"account.registration",
|
"core.account.registration",
|
||||||
data=obj_to_b64([identifier, email]),
|
data=obj_to_b64([identifier, email]),
|
||||||
hash=build_hash(identifier, email),
|
hash=build_hash(identifier, email),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -188,9 +188,9 @@ def invitation_html(user, identifier, email):
|
||||||
@bp.route("/mail/<identifier>/<email>/invitation.txt")
|
@bp.route("/mail/<identifier>/<email>/invitation.txt")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def invitation_txt(user, identifier, email):
|
def invitation_txt(user, identifier, email):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
registration_url = url_for(
|
registration_url = url_for(
|
||||||
"account.registration",
|
"core.account.registration",
|
||||||
data=obj_to_b64([identifier, email]),
|
data=obj_to_b64([identifier, email]),
|
||||||
hash=build_hash(identifier, email),
|
hash=build_hash(identifier, email),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -207,9 +207,9 @@ def invitation_txt(user, identifier, email):
|
||||||
@bp.route("/mail/<identifier>/<email>/email-confirmation.html")
|
@bp.route("/mail/<identifier>/<email>/email-confirmation.html")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def email_confirmation_html(user, identifier, email):
|
def email_confirmation_html(user, identifier, email):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=obj_to_b64([identifier, email]),
|
data=obj_to_b64([identifier, email]),
|
||||||
hash=build_hash(identifier, email),
|
hash=build_hash(identifier, email),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -230,9 +230,9 @@ def email_confirmation_html(user, identifier, email):
|
||||||
@bp.route("/mail/<identifier>/<email>/email-confirmation.txt")
|
@bp.route("/mail/<identifier>/<email>/email-confirmation.txt")
|
||||||
@permissions_needed("manage_oidc")
|
@permissions_needed("manage_oidc")
|
||||||
def email_confirmation_txt(user, identifier, email):
|
def email_confirmation_txt(user, identifier, email):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=obj_to_b64([identifier, email]),
|
data=obj_to_b64([identifier, email]),
|
||||||
hash=build_hash(identifier, email),
|
hash=build_hash(identifier, email),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
|
11
canaille/core/blueprints.py
Normal file
11
canaille/core/blueprints.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from flask import Blueprint
|
||||||
|
|
||||||
|
from . import account
|
||||||
|
from . import admin
|
||||||
|
from . import groups
|
||||||
|
|
||||||
|
bp = Blueprint("core", __name__)
|
||||||
|
|
||||||
|
bp.register_blueprint(account.bp)
|
||||||
|
bp.register_blueprint(admin.bp)
|
||||||
|
bp.register_blueprint(groups.bp)
|
|
@ -48,7 +48,7 @@ def create_group(user):
|
||||||
),
|
),
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
return redirect(url_for("groups.group", group=group))
|
return redirect(url_for("core.groups.group", group=group))
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"group.html", menuitem="groups", form=form, edited_group=None, members=None
|
"group.html", menuitem="groups", form=form, edited_group=None, members=None
|
||||||
|
@ -98,7 +98,7 @@ def edit_group(group):
|
||||||
),
|
),
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
return redirect(url_for("groups.group", group=group))
|
return redirect(url_for("core.groups.group", group=group))
|
||||||
else:
|
else:
|
||||||
flash(_("Group edition failed."), "error")
|
flash(_("Group edition failed."), "error")
|
||||||
|
|
||||||
|
@ -118,4 +118,4 @@ def delete_group(group):
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
group.delete()
|
group.delete()
|
||||||
return redirect(url_for("groups.groups"))
|
return redirect(url_for("core.groups.groups"))
|
||||||
|
|
|
@ -8,7 +8,7 @@ from flask_themer import render_template
|
||||||
|
|
||||||
|
|
||||||
def send_test_mail(email):
|
def send_test_mail(email):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
logo_cid, logo_filename, logo_raw = logo()
|
logo_cid, logo_filename, logo_raw = logo()
|
||||||
|
|
||||||
subject = _("Test email from {website_name}").format(
|
subject = _("Test email from {website_name}").format(
|
||||||
|
@ -37,9 +37,9 @@ def send_test_mail(email):
|
||||||
|
|
||||||
|
|
||||||
def send_password_reset_mail(user, mail):
|
def send_password_reset_mail(user, mail):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
reset_url = url_for(
|
reset_url = url_for(
|
||||||
"account.reset",
|
"core.account.reset",
|
||||||
user=user,
|
user=user,
|
||||||
hash=build_hash(
|
hash=build_hash(
|
||||||
user.identifier,
|
user.identifier,
|
||||||
|
@ -78,9 +78,9 @@ def send_password_reset_mail(user, mail):
|
||||||
|
|
||||||
|
|
||||||
def send_password_initialization_mail(user, email):
|
def send_password_initialization_mail(user, email):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
reset_url = url_for(
|
reset_url = url_for(
|
||||||
"account.reset",
|
"core.account.reset",
|
||||||
user=user,
|
user=user,
|
||||||
hash=build_hash(
|
hash=build_hash(
|
||||||
user.identifier,
|
user.identifier,
|
||||||
|
@ -119,7 +119,7 @@ def send_password_initialization_mail(user, email):
|
||||||
|
|
||||||
|
|
||||||
def send_invitation_mail(email, registration_url):
|
def send_invitation_mail(email, registration_url):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
logo_cid, logo_filename, logo_raw = logo()
|
logo_cid, logo_filename, logo_raw = logo()
|
||||||
|
|
||||||
subject = _("You have been invited to create an account on {website_name}").format(
|
subject = _("You have been invited to create an account on {website_name}").format(
|
||||||
|
@ -150,7 +150,7 @@ def send_invitation_mail(email, registration_url):
|
||||||
|
|
||||||
|
|
||||||
def send_confirmation_email(email, confirmation_url):
|
def send_confirmation_email(email, confirmation_url):
|
||||||
base_url = url_for("account.index", _external=True)
|
base_url = url_for("core.account.index", _external=True)
|
||||||
logo_cid, logo_filename, logo_raw = logo()
|
logo_cid, logo_filename, logo_raw = logo()
|
||||||
|
|
||||||
subject = _("Confirm your address email on {website_name}").format(
|
subject = _("Confirm your address email on {website_name}").format(
|
||||||
|
|
|
@ -265,7 +265,7 @@ def end_session():
|
||||||
user = current_user()
|
user = current_user()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
form = LogoutForm(request.form)
|
form = LogoutForm(request.form)
|
||||||
form.action = url_for("oidc.endpoints.end_session_submit")
|
form.action = url_for("oidc.endpoints.end_session_submit")
|
||||||
|
@ -345,7 +345,7 @@ def end_session():
|
||||||
return redirect(url)
|
return redirect(url)
|
||||||
|
|
||||||
flash(_("You have been disconnected"), "success")
|
flash(_("You have been disconnected"), "success")
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/end_session_confirm", methods=["POST"])
|
@bp.route("/end_session_confirm", methods=["POST"])
|
||||||
|
@ -363,4 +363,4 @@ def end_session_submit():
|
||||||
|
|
||||||
flash(_("You have not been disconnected"), "info")
|
flash(_("You have not been disconnected"), "info")
|
||||||
|
|
||||||
return redirect(url_for("account.index"))
|
return redirect(url_for("core.account.index"))
|
||||||
|
|
|
@ -45,7 +45,7 @@ DEFAULT_JWT_MAPPING = {
|
||||||
"PREFERRED_USERNAME": "{% if user.display_name %}{{ user.display_name }}{% endif %}",
|
"PREFERRED_USERNAME": "{% if user.display_name %}{{ user.display_name }}{% endif %}",
|
||||||
"LOCALE": "{% if user.preferred_language %}{{ user.preferred_language }}{% endif %}",
|
"LOCALE": "{% if user.preferred_language %}{{ user.preferred_language }}{% endif %}",
|
||||||
"ADDRESS": "{% if user.formatted_address %}{{ user.formatted_address[0] }}{% endif %}",
|
"ADDRESS": "{% if user.formatted_address %}{{ user.formatted_address[0] }}{% endif %}",
|
||||||
"PICTURE": "{% if user.photo %}{{ url_for('account.photo', user=user, field='photo', _external=True) }}{% endif %}",
|
"PICTURE": "{% if user.photo %}{{ url_for('core.account.photo', user=user, field='photo', _external=True) }}{% endif %}",
|
||||||
"WEBSITE": "{% if user.profile_url %}{{ user.profile_url[0] }}{% endif %}",
|
"WEBSITE": "{% if user.profile_url %}{{ user.profile_url[0] }}{% endif %}",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="ui clearing segment">
|
<div class="ui clearing segment">
|
||||||
<a href="{{ url_for('account.index') }}">
|
<a href="{{ url_for('core.account.index') }}">
|
||||||
<img class="ui tiny centered image" src="/static/img/canaille-head.png" alt="{{ website_name }}">
|
<img class="ui tiny centered image" src="/static/img/canaille-head.png" alt="{{ website_name }}">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<div class="ui right aligned container">
|
<div class="ui right aligned container">
|
||||||
<div class="ui stackable buttons">
|
<div class="ui stackable buttons">
|
||||||
|
|
||||||
<a type="button" class="ui right floated button" href="{{ url_for('account.login') }}">{{ _("Login page") }}</a>
|
<a type="button" class="ui right floated button" href="{{ url_for('core.account.login') }}">{{ _("Login page") }}</a>
|
||||||
<button type="submit" name="action" value="sendmail" class="ui right floated primary button">{{ _("Send the initialization email") }}</button>
|
<button type="submit" name="action" value="sendmail" class="ui right floated primary button">{{ _("Send the initialization email") }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
<div class="ui right aligned container">
|
<div class="ui right aligned container">
|
||||||
<div class="ui stackable buttons">
|
<div class="ui stackable buttons">
|
||||||
<a type="button" class="ui right floated button" href="{{ url_for('account.login') }}">{{ _("Login page") }}</a>
|
<a type="button" class="ui right floated button" href="{{ url_for('core.account.login') }}">{{ _("Login page") }}</a>
|
||||||
<button type="submit" class="ui right floated {% if request.method != "POST" or form.errors %}primary {% endif %}button">
|
<button type="submit" class="ui right floated {% if request.method != "POST" or form.errors %}primary {% endif %}button">
|
||||||
{% if request.method == "POST" %}
|
{% if request.method == "POST" %}
|
||||||
{{ _("Send again") }}
|
{{ _("Send again") }}
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached two item borderless menu">
|
<nav class="ui bottom attached two item borderless menu">
|
||||||
<a class="{% if edited_group %}active {% endif %}item" href="{{ url_for('groups.groups') }}">
|
<a class="{% if edited_group %}active {% endif %}item" href="{{ url_for('core.groups.groups') }}">
|
||||||
<i class="th list icon"></i>
|
<i class="th list icon"></i>
|
||||||
{% trans %}View{% endtrans %}
|
{% trans %}View{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="{% if not edited_group %}active {% endif %}item" href="{{ url_for('groups.create_group') }}">
|
<a class="{% if not edited_group %}active {% endif %}item" href="{{ url_for('core.groups.create_group') }}">
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
{% trans %}Add{% endtrans %}
|
{% trans %}Add{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached two item borderless menu">
|
<nav class="ui bottom attached two item borderless menu">
|
||||||
<a class="active item" href="{{ url_for('groups.groups') }}">
|
<a class="active item" href="{{ url_for('core.groups.groups') }}">
|
||||||
<i class="th list icon"></i>
|
<i class="th list icon"></i>
|
||||||
{% trans %}View{% endtrans %}
|
{% trans %}View{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="item" href="{{ url_for('groups.create_group') }}">
|
<a class="item" href="{{ url_for('core.groups.create_group') }}">
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
{% trans %}Add{% endtrans %}
|
{% trans %}Add{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -11,15 +11,15 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached three item borderless menu">
|
<nav class="ui bottom attached three item borderless menu">
|
||||||
<a class="item" href="{{ url_for('account.users') }}">
|
<a class="item" href="{{ url_for('core.account.users') }}">
|
||||||
<i class="th list icon"></i>
|
<i class="th list icon"></i>
|
||||||
{% trans %}View{% endtrans %}
|
{% trans %}View{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="item" href="{{ url_for('account.profile_creation') }}">
|
<a class="item" href="{{ url_for('core.account.profile_creation') }}">
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
{% trans %}Add{% endtrans %}
|
{% trans %}Add{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="active item" href="{{ url_for('account.user_invitation') }}">
|
<a class="active item" href="{{ url_for('core.account.user_invitation') }}">
|
||||||
<i class="paper plane icon"></i>
|
<i class="paper plane icon"></i>
|
||||||
{% trans %}Invite{% endtrans %}
|
{% trans %}Invite{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -79,11 +79,11 @@
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<div class="ui stackable buttons">
|
<div class="ui stackable buttons">
|
||||||
<a class="ui right floated button" href="{{ url_for("account.profile_creation") }}">
|
<a class="ui right floated button" href="{{ url_for("core.account.profile_creation") }}">
|
||||||
{{ _("Create a user") }}
|
{{ _("Create a user") }}
|
||||||
</a>
|
</a>
|
||||||
{% if request.form["action"] == "generate" or email_sent %}
|
{% if request.form["action"] == "generate" or email_sent %}
|
||||||
<a href="{{ url_for('account.user_invitation') }}" class="ui right floated button" name="action" value="invite" id="invite">
|
<a href="{{ url_for('core.account.user_invitation') }}" class="ui right floated button" name="action" value="invite" id="invite">
|
||||||
{{ _("Invite another user") }}
|
{{ _("Invite another user") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
|
|
||||||
<div class="ui right aligned container">
|
<div class="ui right aligned container">
|
||||||
<div class="ui stackable buttons">
|
<div class="ui stackable buttons">
|
||||||
<a class="ui right floated button" href="{{ url_for("account.profile_creation") }}">
|
<a class="ui right floated button" href="{{ url_for("core.account.profile_creation") }}">
|
||||||
{{ _("Create a user") }}
|
{{ _("Create a user") }}
|
||||||
</a>
|
</a>
|
||||||
<button type="submit" name="action" value="generate" class="ui right floated primary button">
|
<button type="submit" name="action" value="generate" class="ui right floated primary button">
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="ui clearing segment">
|
<div class="ui clearing segment">
|
||||||
{% if logo_url %}
|
{% if logo_url %}
|
||||||
<a href="{{ url_for('account.index') }}">
|
<a href="{{ url_for('core.account.index') }}">
|
||||||
<img class="ui tiny centered image" src="{{ logo_url }}" alt="{{ website_name }}">
|
<img class="ui tiny centered image" src="{{ logo_url }}" alt="{{ website_name }}">
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
<div class="ui right aligned container">
|
<div class="ui right aligned container">
|
||||||
<div class="ui stackable buttons">
|
<div class="ui stackable buttons">
|
||||||
{% if has_smtp and has_password_recovery %}
|
{% if has_smtp and has_password_recovery %}
|
||||||
<a type="button" class="ui right floated button" href="{{ url_for('account.forgotten') }}">{{ _("Forgotten password") }}</a>
|
<a type="button" class="ui right floated button" href="{{ url_for('core.account.forgotten') }}">{{ _("Forgotten password") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button type="submit" name="answer" class="ui right floated primary button" hx-boost="false">{{ _("Continue") }}</button>
|
<button type="submit" name="answer" class="ui right floated primary button" hx-boost="false">{{ _("Continue") }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="active item" href="{{ url_for('admin.mail_index') }}">
|
<a class="active item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="right floated content">
|
<div class="right floated content">
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<a class="ui button primary" href="{{ url_for("admin.test_txt") }}">TXT</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.test_txt") }}">TXT</a>
|
||||||
<a class="ui button primary" href="{{ url_for("admin.test_html") }}">HTML</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.test_html") }}">HTML</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="middle aligned content">
|
<div class="middle aligned content">
|
||||||
|
@ -77,8 +77,8 @@
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="right floated content">
|
<div class="right floated content">
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<a class="ui button primary" href="{{ url_for("admin.password_init_txt") }}">TXT</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.password_init_txt") }}">TXT</a>
|
||||||
<a class="ui button primary" href="{{ url_for("admin.password_init_html") }}">HTML</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.password_init_html") }}">HTML</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="middle aligned content">
|
<div class="middle aligned content">
|
||||||
|
@ -89,8 +89,8 @@
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="right floated content">
|
<div class="right floated content">
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<a class="ui button primary" href="{{ url_for("admin.password_reset_txt") }}">TXT</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.password_reset_txt") }}">TXT</a>
|
||||||
<a class="ui button primary" href="{{ url_for("admin.password_reset_html") }}">HTML</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.password_reset_html") }}">HTML</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="middle aligned content">
|
<div class="middle aligned content">
|
||||||
|
@ -101,8 +101,8 @@
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="right floated content">
|
<div class="right floated content">
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<a class="ui button primary" href="{{ url_for("admin.email_confirmation_txt", identifier=user.identifier, email=user.preferred_email) }}">TXT</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.email_confirmation_txt", identifier=user.identifier, email=user.preferred_email) }}">TXT</a>
|
||||||
<a class="ui button primary" href="{{ url_for("admin.email_confirmation_html", identifier=user.identifier, email=user.preferred_email) }}">HTML</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.email_confirmation_html", identifier=user.identifier, email=user.preferred_email) }}">HTML</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="middle aligned content">
|
<div class="middle aligned content">
|
||||||
|
@ -114,8 +114,8 @@
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="right floated content">
|
<div class="right floated content">
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<a class="ui button primary" href="{{ url_for("admin.invitation_txt", identifier=user.identifier, email=user.preferred_email) }}">TXT</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.invitation_txt", identifier=user.identifier, email=user.preferred_email) }}">TXT</a>
|
||||||
<a class="ui button primary" href="{{ url_for("admin.invitation_html", identifier=user.identifier, email=user.preferred_email) }}">HTML</a>
|
<a class="ui button primary" href="{{ url_for("core.admin.invitation_html", identifier=user.identifier, email=user.preferred_email) }}">HTML</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="middle aligned content">
|
<div class="middle aligned content">
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached five item borderless menu">
|
<nav class="ui bottom attached five item borderless menu">
|
||||||
<a class="item" href="{{ url_for('admin.mail_index') }}">
|
<a class="item" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="user mail icon"></i>
|
<i class="user mail icon"></i>
|
||||||
{% trans %}Emails{% endtrans %}
|
{% trans %}Emails{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ _("Subject") }}</td>
|
<td>{{ _("Subject") }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for("account.profile_edition", edited_user=token.subject) }}">
|
<a href="{{ url_for("core.account.profile_edition", edited_user=token.subject) }}">
|
||||||
{{ token.subject.identifier }}
|
{{ token.subject.identifier }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
{% for group in table_form.items_slice %}
|
{% for group in table_form.items_slice %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('groups.group', group=group) }}">
|
<a href="{{ url_for('core.groups.group', group=group) }}">
|
||||||
<i class="users circular black inverted icon"></i>
|
<i class="users circular black inverted icon"></i>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td><a href="{{ url_for('groups.group', group=group) }}">{{ group.display_name }}</a></td>
|
<td><a href="{{ url_for('core.groups.group', group=group) }}">{{ group.display_name }}</a></td>
|
||||||
<td>{% if group.description %}{{ group.description[0] }}{% endif %}</td>
|
<td>{% if group.description %}{{ group.description[0] }}{% endif %}</td>
|
||||||
<td>{{ group.members|len }}</td>
|
<td>{{ group.members|len }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<td><a href="{{ url_for('oidc.authorizations.view', authorization=authorization) }}">{{ authorization.authorization_code_id }}</a></td>
|
<td><a href="{{ url_for('oidc.authorizations.view', authorization=authorization) }}">{{ authorization.authorization_code_id }}</a></td>
|
||||||
<td><a href="{{ url_for('oidc.clients.edit', client=authorization.client) }}">{{ authorization.client.client_id }}</a></td>
|
<td><a href="{{ url_for('oidc.clients.edit', client=authorization.client) }}">{{ authorization.client.client_id }}</a></td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for("account.profile_edition", edited_user=authorization.subject) }}">
|
<a href="{{ url_for("core.account.profile_edition", edited_user=authorization.subject) }}">
|
||||||
{{ authorization.subject.user_name[0] }}
|
{{ authorization.subject.user_name[0] }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for("account.profile_edition", edited_user=token.subject) }}">
|
<a href="{{ url_for("core.account.profile_edition", edited_user=token.subject) }}">
|
||||||
{{ token.subject.user_name[0] }}
|
{{ token.subject.user_name[0] }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
<tr>
|
<tr>
|
||||||
{% if user.can_read("photo") %}
|
{% if user.can_read("photo") %}
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('account.profile_edition', edited_user=watched_user) }}">
|
<a href="{{ url_for('core.account.profile_edition', edited_user=watched_user) }}">
|
||||||
{% if user.can_manage_users and watched_user.locked %}
|
{% if user.can_manage_users and watched_user.locked %}
|
||||||
<i class="lock circle big black icon" title="{% trans %}This account is locked{% endtrans %}"></i>
|
<i class="lock circle big black icon" title="{% trans %}This account is locked{% endtrans %}"></i>
|
||||||
{% elif watched_user.photo and watched_user.photo[0] %}
|
{% elif watched_user.photo and watched_user.photo[0] %}
|
||||||
<img class="ui avatar image" src="{{ url_for("account.photo", user=watched_user, field="photo") }}" alt="User photo">
|
<img class="ui avatar image" src="{{ url_for("core.account.photo", user=watched_user, field="photo") }}" alt="User photo">
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="user circle big black icon"></i>
|
<i class="user circle big black icon"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.can_read("user_name") %}
|
{% if user.can_read("user_name") %}
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('account.profile_edition', edited_user=watched_user) }}">
|
<a href="{{ url_for('core.account.profile_edition', edited_user=watched_user) }}">
|
||||||
{% if watched_user.user_name %}
|
{% if watched_user.user_name %}
|
||||||
{{ watched_user.user_name[0] }}
|
{{ watched_user.user_name[0] }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
{% if user.can_manage_groups %}
|
{% if user.can_manage_groups %}
|
||||||
<td>
|
<td>
|
||||||
{% for group in watched_user.groups %}
|
{% for group in watched_user.groups %}
|
||||||
<a class="ui label" href="{{ url_for('groups.group', group=group) }}"{% if group.description %} title="{{ group.description[0] }}"{% endif %}>
|
<a class="ui label" href="{{ url_for('core.groups.group', group=group) }}"{% if group.description %} title="{{ group.description[0] }}"{% endif %}>
|
||||||
{{ group.display_name }}
|
{{ group.display_name }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="ui clearing segment">
|
<div class="ui clearing segment">
|
||||||
{% if logo_url %}
|
{% if logo_url %}
|
||||||
<a href="{{ url_for('account.index') }}">
|
<a href="{{ url_for('core.account.index') }}">
|
||||||
<img class="ui tiny centered image" src="{{ logo_url }}" alt="{{ website_name }}">
|
<img class="ui tiny centered image" src="{{ logo_url }}" alt="{{ website_name }}">
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
<div class="ui right aligned container">
|
<div class="ui right aligned container">
|
||||||
<div class="ui stackable buttons">
|
<div class="ui stackable buttons">
|
||||||
<a type="button" class="ui right floated button" href="{{ url_for('account.login') }}">{{ _("I am not %(username)s", username=username) }}</a>
|
<a type="button" class="ui right floated button" href="{{ url_for('core.account.login') }}">{{ _("I am not %(username)s", username=username) }}</a>
|
||||||
{% if has_smtp and has_password_recovery %}
|
{% if has_smtp and has_password_recovery %}
|
||||||
<a type="button" class="ui right floated button" href="{{ url_for('account.forgotten') }}">{{ _("Forgotten password") }}</a>
|
<a type="button" class="ui right floated button" href="{{ url_for('core.account.forgotten') }}">{{ _("Forgotten password") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button type="submit" class="ui right floated primary button">{{ _("Sign in") }}</button>
|
<button type="submit" class="ui right floated primary button">{{ _("Sign in") }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,16 +12,16 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached {% if has_smtp %}three{% else %}two{% endif %} item borderless menu">
|
<nav class="ui bottom attached {% if has_smtp %}three{% else %}two{% endif %} item borderless menu">
|
||||||
<a class="item" href="{{ url_for('account.users') }}">
|
<a class="item" href="{{ url_for('core.account.users') }}">
|
||||||
<i class="th list icon"></i>
|
<i class="th list icon"></i>
|
||||||
{% trans %}View{% endtrans %}
|
{% trans %}View{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="active item" href="{{ url_for('account.profile_creation') }}">
|
<a class="active item" href="{{ url_for('core.account.profile_creation') }}">
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
{% trans %}Add{% endtrans %}
|
{% trans %}Add{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% if has_smtp %}
|
{% if has_smtp %}
|
||||||
<a class="item" href="{{ url_for('account.user_invitation') }}">
|
<a class="item" href="{{ url_for('core.account.user_invitation') }}">
|
||||||
<i class="paper plane icon"></i>
|
<i class="paper plane icon"></i>
|
||||||
{% trans %}Invite{% endtrans %}
|
{% trans %}Invite{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached two item borderless menu">
|
<nav class="ui bottom attached two item borderless menu">
|
||||||
<a class="active item" href="{{ url_for('account.profile_edition', edited_user=edited_user) }}">
|
<a class="active item" href="{{ url_for('core.account.profile_edition', edited_user=edited_user) }}">
|
||||||
<i class="id card icon"></i>
|
<i class="id card icon"></i>
|
||||||
{% trans %}Personal information{% endtrans %}
|
{% trans %}Personal information{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="item" href="{{ url_for('account.profile_settings', edited_user=edited_user) }}">
|
<a class="item" href="{{ url_for('core.account.profile_settings', edited_user=edited_user) }}">
|
||||||
<i class="tools icon"></i>
|
<i class="tools icon"></i>
|
||||||
{% trans %}Account settings{% endtrans %}
|
{% trans %}Account settings{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
<a class="ui right corner label photo-delete-icon" title="{{ _("Delete the photo") }}">
|
<a class="ui right corner label photo-delete-icon" title="{{ _("Delete the photo") }}">
|
||||||
<i class="times icon"></i>
|
<i class="times icon"></i>
|
||||||
</a>
|
</a>
|
||||||
<img src="{% if photo %}{{ url_for("account.photo", user=edited_user, field="photo") }}{% endif %}" alt="User photo">
|
<img src="{% if photo %}{{ url_for("core.account.photo", user=edited_user, field="photo") }}{% endif %}" alt="User photo">
|
||||||
</label>
|
</label>
|
||||||
<label
|
<label
|
||||||
class="ui centered photo-placeholder"
|
class="ui centered photo-placeholder"
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached two item borderless menu">
|
<nav class="ui bottom attached two item borderless menu">
|
||||||
<a class="item" href="{{ url_for('account.profile_edition', edited_user=edited_user) }}">
|
<a class="item" href="{{ url_for('core.account.profile_edition', edited_user=edited_user) }}">
|
||||||
<i class="id card icon"></i>
|
<i class="id card icon"></i>
|
||||||
{% trans %}Personal information{% endtrans %}
|
{% trans %}Personal information{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="active item" href="{{ url_for('account.profile_settings', edited_user=edited_user) }}">
|
<a class="active item" href="{{ url_for('core.account.profile_settings', edited_user=edited_user) }}">
|
||||||
<i class="tools icon"></i>
|
<i class="tools icon"></i>
|
||||||
{% trans %}Account settings{% endtrans %}
|
{% trans %}Account settings{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -156,7 +156,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if user.can_impersonate_users and user.identifier != edited_user.identifier %}
|
{% if user.can_impersonate_users and user.identifier != edited_user.identifier %}
|
||||||
<a href="{{ url_for('account.impersonate', puppet=edited_user) }}" class="ui right floated basic button" name="action" value="impersonate" id="impersonate" hx-boost="false">
|
<a href="{{ url_for('core.account.impersonate', puppet=edited_user) }}" class="ui right floated basic button" name="action" value="impersonate" id="impersonate" hx-boost="false">
|
||||||
{{ _("Impersonate") }}
|
{{ _("Impersonate") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="ui attached clearing segment">
|
<div class="ui attached clearing segment">
|
||||||
{{ fui.render_form(form, _("Password reset"), action=url_for("account.reset", user=user, hash=hash)) }}
|
{{ fui.render_form(form, _("Password reset"), action=url_for("core.account.reset", user=user, hash=hash)) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -7,16 +7,16 @@
|
||||||
|
|
||||||
{% block submenu %}
|
{% block submenu %}
|
||||||
<nav class="ui bottom attached {% if has_smtp %}three{% else %}two{% endif %} item borderless menu">
|
<nav class="ui bottom attached {% if has_smtp %}three{% else %}two{% endif %} item borderless menu">
|
||||||
<a class="active item" href="{{ url_for('account.users') }}">
|
<a class="active item" href="{{ url_for('core.account.users') }}">
|
||||||
<i class="th list icon"></i>
|
<i class="th list icon"></i>
|
||||||
{% trans %}View{% endtrans %}
|
{% trans %}View{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
<a class="item" href="{{ url_for('account.profile_creation') }}">
|
<a class="item" href="{{ url_for('core.account.profile_creation') }}">
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
{% trans %}Add{% endtrans %}
|
{% trans %}Add{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% if has_smtp %}
|
{% if has_smtp %}
|
||||||
<a class="item" href="{{ url_for('account.user_invitation') }}">
|
<a class="item" href="{{ url_for('core.account.user_invitation') }}">
|
||||||
<i class="paper plane icon"></i>
|
<i class="paper plane icon"></i>
|
||||||
{% trans %}Invite{% endtrans %}
|
{% trans %}Invite{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
{% if user.can_edit_self %}
|
{% if user.can_edit_self %}
|
||||||
<a class="item {% if menuitem is defined and menuitem == "profile" %}active{% endif %}"
|
<a class="item {% if menuitem is defined and menuitem == "profile" %}active{% endif %}"
|
||||||
href="{{ url_for('account.profile_edition', edited_user=user) }}">
|
href="{{ url_for('core.account.profile_edition', edited_user=user) }}">
|
||||||
<i class="id card icon"></i>
|
<i class="id card icon"></i>
|
||||||
{% trans %}Profile{% endtrans %}
|
{% trans %}Profile{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -45,25 +45,25 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.can_manage_users %}
|
{% if user.can_manage_users %}
|
||||||
<a class="item {% if menuitem is defined and menuitem == "users" %}active{% endif %}"
|
<a class="item {% if menuitem is defined and menuitem == "users" %}active{% endif %}"
|
||||||
href="{{ url_for('account.users') }}">
|
href="{{ url_for('core.account.users') }}">
|
||||||
<i class="address book icon"></i>
|
<i class="address book icon"></i>
|
||||||
{% trans %}Users{% endtrans %}
|
{% trans %}Users{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.can_manage_groups %}
|
{% if user.can_manage_groups %}
|
||||||
<a class="item {% if menuitem is defined and menuitem == "groups" %}active{% endif %}"
|
<a class="item {% if menuitem is defined and menuitem == "groups" %}active{% endif %}"
|
||||||
href="{{ url_for('groups.groups') }}">
|
href="{{ url_for('core.groups.groups') }}">
|
||||||
<i class="users icon"></i>
|
<i class="users icon"></i>
|
||||||
{% trans %}Groups{% endtrans %}
|
{% trans %}Groups{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.can_manage_oidc %}
|
{% if user.can_manage_oidc %}
|
||||||
<a class="item {% if menuitem is defined and menuitem == "admin" %}active{% endif %}" href="{{ url_for('admin.mail_index') }}">
|
<a class="item {% if menuitem is defined and menuitem == "admin" %}active{% endif %}" href="{{ url_for('core.admin.mail_index') }}">
|
||||||
<i class="settings icon"></i>
|
<i class="settings icon"></i>
|
||||||
{% trans %}Admin{% endtrans %}
|
{% trans %}Admin{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="item" href="{{ url_for('account.logout') }}">
|
<a class="item" href="{{ url_for('core.account.logout') }}">
|
||||||
<i class="sign out alternate icon"></i>
|
<i class="sign out alternate icon"></i>
|
||||||
{% trans %}Log out{% endtrans %}
|
{% trans %}Log out{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<a href="{{ url_for('account.about') }}">{{ _("About Canaille") }}</a>
|
<a href="{{ url_for('core.account.about') }}">{{ _("About Canaille") }}</a>
|
||||||
</footer>
|
</footer>
|
||||||
{% if config.get("JAVASCRIPT", true) %}
|
{% if config.get("JAVASCRIPT", true) %}
|
||||||
{% if not is_boosted %}
|
{% if not is_boosted %}
|
||||||
|
|
|
@ -234,7 +234,7 @@ DYNAMIC_CLIENT_REGISTRATION_TOKENS = [
|
||||||
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||||
# LOCALE = "{{ user.preferred_language }}"
|
# LOCALE = "{{ user.preferred_language }}"
|
||||||
# ADDRESS = "{{ user.formatted_address[0] }}"
|
# ADDRESS = "{{ user.formatted_address[0] }}"
|
||||||
# PICTURE = "{% if user.photo %}{{ url_for('account.photo', user=user, field='photo', _external=True) }}{% endif %}"
|
# PICTURE = "{% if user.photo %}{{ url_for('core.account.photo', user=user, field='photo', _external=True) }}{% endif %}"
|
||||||
# WEBSITE = "{{ user.profile_url[0] }}"
|
# WEBSITE = "{{ user.profile_url[0] }}"
|
||||||
|
|
||||||
# The SMTP server options. If not set, mail related features such as
|
# The SMTP server options. If not set, mail related features such as
|
||||||
|
|
|
@ -238,7 +238,7 @@ DYNAMIC_CLIENT_REGISTRATION_TOKENS = [
|
||||||
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||||
# LOCALE = "{{ user.preferred_language }}"
|
# LOCALE = "{{ user.preferred_language }}"
|
||||||
# ADDRESS = "{{ user.formatted_address[0] }}"
|
# ADDRESS = "{{ user.formatted_address[0] }}"
|
||||||
# PICTURE = "{% if user.photo %}{{ url_for('account.photo', user=user, field='photo', _external=True) }}{% endif %}"
|
# PICTURE = "{% if user.photo %}{{ url_for('core.account.photo', user=user, field='photo', _external=True) }}{% endif %}"
|
||||||
# WEBSITE = "{{ user.profile_url[0] }}"
|
# WEBSITE = "{{ user.profile_url[0] }}"
|
||||||
|
|
||||||
# The SMTP server options. If not set, mail related features such as
|
# The SMTP server options. If not set, mail related features such as
|
||||||
|
|
|
@ -274,7 +274,7 @@ Attributes are rendered using jinja2, and can use a ``user`` variable.
|
||||||
*Optional.* Defaults to ``{{ user.address[0] }}``
|
*Optional.* Defaults to ``{{ user.address[0] }}``
|
||||||
|
|
||||||
:PICTURE:
|
:PICTURE:
|
||||||
*Optional.* Defaults to ``{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}``
|
*Optional.* Defaults to ``{% if user.photo %}{{ url_for('core.account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}``
|
||||||
|
|
||||||
:WEBSITE:
|
:WEBSITE:
|
||||||
*Optional.* Defaults to ``{{ user.profile_url[0] }}``
|
*Optional.* Defaults to ``{{ user.profile_url[0] }}``
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="item {% if menuitem == "profile" %}active{% endif %}"
|
<a class="item {% if menuitem == "profile" %}active{% endif %}"
|
||||||
href="{{ url_for('account.profile_edition', edited_user=user) }}">
|
href="{{ url_for('core.account.profile_edition', edited_user=user) }}">
|
||||||
<i class="id card icon"></i>
|
<i class="id card icon"></i>
|
||||||
{% trans %}My profile{% endtrans %}
|
{% trans %}My profile{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -39,14 +39,14 @@
|
||||||
</a>
|
</a>
|
||||||
{% if user.can_manage_users %}
|
{% if user.can_manage_users %}
|
||||||
<a class="item {% if menuitem == "users" %}active{% endif %}"
|
<a class="item {% if menuitem == "users" %}active{% endif %}"
|
||||||
href="{{ url_for('account.users') }}">
|
href="{{ url_for('core.account.users') }}">
|
||||||
<i class="users icon"></i>
|
<i class="users icon"></i>
|
||||||
{% trans %}Users{% endtrans %}
|
{% trans %}Users{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.can_manage_groups %}
|
{% if user.can_manage_groups %}
|
||||||
<a class="item {% if menuitem == "groups" %}active{% endif %}"
|
<a class="item {% if menuitem == "groups" %}active{% endif %}"
|
||||||
href="{{ url_for('groups.groups') }}">
|
href="{{ url_for('core.groups.groups') }}">
|
||||||
<i class="users cog icon"></i>
|
<i class="users cog icon"></i>
|
||||||
{% trans %}Groups{% endtrans %}
|
{% trans %}Groups{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="item" href="{{ url_for('account.logout') }}">
|
<a class="item" href="{{ url_for('core.account.logout') }}">
|
||||||
<i class="sign out alternate icon"></i>
|
<i class="sign out alternate icon"></i>
|
||||||
{% trans %}Log out{% endtrans %}
|
{% trans %}Log out{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<a href="{{ url_for('account.about') }}">{{ _("About canaille") }}</a>
|
<a href="{{ url_for('core.account.about') }}">{{ _("About canaille") }}</a>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="/static/jquery/jquery.min.js" defer></script>
|
<script src="/static/jquery/jquery.min.js" defer></script>
|
||||||
<script src="/static/fomanticui/semantic.min.js" defer></script>
|
<script src="/static/fomanticui/semantic.min.js" defer></script>
|
||||||
|
|
|
@ -168,7 +168,7 @@ def test_confirmation_unset_smtp_enabled_email_user_validation(
|
||||||
"new_email@mydomain.tld",
|
"new_email@mydomain.tld",
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash=email_confirmation.build_hash(),
|
hash=email_confirmation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -264,7 +264,7 @@ def test_confirmation_expired_link(testclient, backend, user):
|
||||||
"new_email@mydomain.tld",
|
"new_email@mydomain.tld",
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash=email_confirmation.build_hash(),
|
hash=email_confirmation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -291,7 +291,7 @@ def test_confirmation_invalid_hash_link(testclient, backend, user):
|
||||||
"new_email@mydomain.tld",
|
"new_email@mydomain.tld",
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash="invalid",
|
hash="invalid",
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -320,7 +320,7 @@ def test_confirmation_invalid_user_link(testclient, backend, user):
|
||||||
"new_email@mydomain.tld",
|
"new_email@mydomain.tld",
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash=email_confirmation.build_hash(),
|
hash=email_confirmation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -347,7 +347,7 @@ def test_confirmation_email_already_confirmed_link(testclient, backend, user, ad
|
||||||
"john@doe.com",
|
"john@doe.com",
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash=email_confirmation.build_hash(),
|
hash=email_confirmation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
@ -376,7 +376,7 @@ def test_confirmation_email_already_used_link(testclient, backend, user, admin):
|
||||||
"jane@doe.com",
|
"jane@doe.com",
|
||||||
)
|
)
|
||||||
email_confirmation_url = url_for(
|
email_confirmation_url = url_for(
|
||||||
"account.email_confirmation",
|
"core.account.email_confirmation",
|
||||||
data=email_confirmation.b64(),
|
data=email_confirmation.b64(),
|
||||||
hash=email_confirmation.build_hash(),
|
hash=email_confirmation.build_hash(),
|
||||||
_external=True,
|
_external=True,
|
||||||
|
|
Loading…
Reference in a new issue