Implemented User.preferred_email

This commit is contained in:
Éloi Rivard 2023-06-22 15:24:13 +02:00
parent 371f806695
commit b5bd497d0e
12 changed files with 23 additions and 19 deletions

View file

@ -204,7 +204,7 @@ PUBLIC_KEY = "canaille/conf/public.pem"
# SUB = "{{ user.user_name[0] }}" # SUB = "{{ user.user_name[0] }}"
# NAME = "{{ user.formatted_name[0] }}" # NAME = "{{ user.formatted_name[0] }}"
# PHONE_NUMBER = "{{ user.phone_number[0] }}" # PHONE_NUMBER = "{{ user.phone_number[0] }}"
# EMAIL = "{{ user.emails[0] }}" # EMAIL = "{{ user.preferred_email }}"
# GIVEN_NAME = "{{ user.given_name[0] }}" # GIVEN_NAME = "{{ user.given_name[0] }}"
# FAMILY_NAME = "{{ user.family_name[0] }}" # FAMILY_NAME = "{{ user.family_name[0] }}"
# PREFERRED_USERNAME = "{{ user.display_name }}" # PREFERRED_USERNAME = "{{ user.display_name }}"

View file

@ -721,7 +721,7 @@ def reset(user_name, hash):
if not user or hash != profile_hash( if not user or hash != profile_hash(
user.user_name[0], user.user_name[0],
user.emails[0], user.preferred_email,
user.password[0] if user.has_password() else "", user.password[0] if user.has_password() else "",
): ):
flash( flash(

View file

@ -76,7 +76,7 @@ def password_init_html(user):
reset_url = url_for( reset_url = url_for(
"account.reset", "account.reset",
user_name=user.user_name[0], user_name=user.user_name[0],
hash=profile_hash(user.user_name[0], user.emails[0], user.password[0]), hash=profile_hash(user.user_name[0], user.preferred_email, user.password[0]),
_external=True, _external=True,
) )
@ -99,7 +99,7 @@ def password_init_txt(user):
reset_url = url_for( reset_url = url_for(
"account.reset", "account.reset",
user_name=user.user_name[0], user_name=user.user_name[0],
hash=profile_hash(user.user_name[0], user.emails[0], user.password[0]), hash=profile_hash(user.user_name[0], user.preferred_email, user.password[0]),
_external=True, _external=True,
) )
@ -118,7 +118,7 @@ def password_reset_html(user):
reset_url = url_for( reset_url = url_for(
"account.reset", "account.reset",
user_name=user.user_name[0], user_name=user.user_name[0],
hash=profile_hash(user.user_name[0], user.emails[0], user.password[0]), hash=profile_hash(user.user_name[0], user.preferred_email, user.password[0]),
_external=True, _external=True,
) )
@ -141,7 +141,7 @@ def password_reset_txt(user):
reset_url = url_for( reset_url = url_for(
"account.reset", "account.reset",
user_name=user.user_name[0], user_name=user.user_name[0],
hash=profile_hash(user.user_name[0], user.emails[0], user.password[0]), hash=profile_hash(user.user_name[0], user.preferred_email, user.password[0]),
_external=True, _external=True,
) )

View file

@ -42,7 +42,7 @@ def send_password_reset_mail(user):
user_name=user.user_name[0], user_name=user.user_name[0],
hash=profile_hash( hash=profile_hash(
user.user_name[0], user.user_name[0],
user.emails[0], user.preferred_email,
user.password[0] if user.has_password() else "", user.password[0] if user.has_password() else "",
), ),
_external=True, _external=True,
@ -68,7 +68,7 @@ def send_password_reset_mail(user):
return send_email( return send_email(
subject=subject, subject=subject,
recipient=user.emails[0], recipient=user.preferred_email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
@ -82,7 +82,7 @@ def send_password_initialization_mail(user):
user_name=user.user_name[0], user_name=user.user_name[0],
hash=profile_hash( hash=profile_hash(
user.user_name[0], user.user_name[0],
user.emails[0], user.preferred_email,
user.password[0] if user.has_password() else "", user.password[0] if user.has_password() else "",
), ),
_external=True, _external=True,
@ -108,7 +108,7 @@ def send_password_initialization_mail(user):
return send_email( return send_email(
subject=subject, subject=subject,
recipient=user.emails[0], recipient=user.preferred_email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,

View file

@ -46,6 +46,10 @@ class User:
def can_read(self, field): def can_read(self, field):
return field in self.read | self.write return field in self.read | self.write
@property
def preferred_email(self):
return self.emails[0] if self.emails else None
@property @property
def can_edit_self(self): def can_edit_self(self):
return "edit_self" in self.permissions return "edit_self" in self.permissions

View file

@ -39,7 +39,7 @@ DEFAULT_JWT_MAPPING = {
"SUB": "{{ user.user_name[0] }}", "SUB": "{{ user.user_name[0] }}",
"NAME": "{% if user.formatted_name %}{{ user.formatted_name[0] }}{% endif %}", "NAME": "{% if user.formatted_name %}{{ user.formatted_name[0] }}{% endif %}",
"PHONE_NUMBER": "{% if user.phone_number %}{{ user.phone_number[0] }}{% endif %}", "PHONE_NUMBER": "{% if user.phone_number %}{{ user.phone_number[0] }}{% endif %}",
"EMAIL": "{% if user.emails %}{{ user.emails[0] }}{% endif %}", "EMAIL": "{% if user.preferred_email %}{{ user.preferred_email }}{% endif %}",
"GIVEN_NAME": "{% if user.given_name %}{{ user.given_name[0] }}{% endif %}", "GIVEN_NAME": "{% if user.given_name %}{{ user.given_name[0] }}{% endif %}",
"FAMILY_NAME": "{% if user.family_name %}{{ user.family_name[0] }}{% endif %}", "FAMILY_NAME": "{% if user.family_name %}{{ user.family_name[0] }}{% endif %}",
"PREFERRED_USERNAME": "{% if user.display_name %}{{ user.display_name }}{% endif %}", "PREFERRED_USERNAME": "{% if user.display_name %}{{ user.display_name }}{% endif %}",

View file

@ -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.invitation_txt", user_name=user.user_name, email=user.emails[0]) }}">TXT</a> <a class="ui button primary" href="{{ url_for("admin.invitation_txt", user_name=user.user_name, email=user.preferred_email) }}">TXT</a>
<a class="ui button primary" href="{{ url_for("admin.invitation_html", user_name=user.user_name, email=user.emails[0]) }}">HTML</a> <a class="ui button primary" href="{{ url_for("admin.invitation_html", user_name=user.user_name, email=user.preferred_email) }}">HTML</a>
</div> </div>
</div> </div>
<div class="middle aligned content"> <div class="middle aligned content">

View file

@ -42,7 +42,7 @@
<td>{{ watched_user.formatted_name[0] }}</td> <td>{{ watched_user.formatted_name[0] }}</td>
{% endif %} {% endif %}
{% if user.can_read("emails") %} {% if user.can_read("emails") %}
<td><a href="mailto:{{ watched_user.emails[0] }}">{{ watched_user.emails[0] }}</a></td> <td><a href="mailto:{{ watched_user.preferred_email }}">{{ watched_user.preferred_email }}</a></td>
{% endif %} {% endif %}
{% if user.can_manage_groups %} {% if user.can_manage_groups %}
<td> <td>

View file

@ -209,7 +209,7 @@ PUBLIC_KEY = "conf/public.pem"
# SUB = "{{ user.user_name[0] }}" # SUB = "{{ user.user_name[0] }}"
# NAME = "{{ user.formatted_name[0] }}" # NAME = "{{ user.formatted_name[0] }}"
# PHONE_NUMBER = "{{ user.phone_number[0] }}" # PHONE_NUMBER = "{{ user.phone_number[0] }}"
# EMAIL = "{{ user.emails[0] }}" # EMAIL = "{{ user.preferred_email }}"
# GIVEN_NAME = "{{ user.given_name[0] }}" # GIVEN_NAME = "{{ user.given_name[0] }}"
# FAMILY_NAME = "{{ user.family_name[0] }}" # FAMILY_NAME = "{{ user.family_name[0] }}"
# PREFERRED_USERNAME = "{{ user.display_name }}" # PREFERRED_USERNAME = "{{ user.display_name }}"

View file

@ -210,7 +210,7 @@ PUBLIC_KEY = "conf/public.pem"
# SUB = "{{ user.user_name[0] }}" # SUB = "{{ user.user_name[0] }}"
# NAME = "{{ user.formatted_name[0] }}" # NAME = "{{ user.formatted_name[0] }}"
# PHONE_NUMBER = "{{ user.phone_number[0] }}" # PHONE_NUMBER = "{{ user.phone_number[0] }}"
# EMAIL = "{{ user.emails[0] }}" # EMAIL = "{{ user.preferred_email }}"
# GIVEN_NAME = "{{ user.given_name[0] }}" # GIVEN_NAME = "{{ user.given_name[0] }}"
# FAMILY_NAME = "{{ user.family_name[0] }}" # FAMILY_NAME = "{{ user.family_name[0] }}"
# PREFERRED_USERNAME = "{{ user.display_name }}" # PREFERRED_USERNAME = "{{ user.display_name }}"

View file

@ -148,7 +148,7 @@ def test_invitation_login_already_taken(testclient, logged_admin):
res = testclient.get("/invite", status=200) res = testclient.get("/invite", status=200)
res.form["user_name"] = logged_admin.user_name res.form["user_name"] = logged_admin.user_name
res.form["email"] = logged_admin.emails[0] res.form["email"] = logged_admin.preferred_email
res = res.form.submit(name="action", value="send", status=200) res = res.form.submit(name="action", value="send", status=200)
res.mustcontain("The login &#39;admin&#39; already exists") res.mustcontain("The login &#39;admin&#39; already exists")

View file

@ -3,7 +3,7 @@ from canaille.core.account import profile_hash
def test_password_reset(testclient, user): def test_password_reset(testclient, user):
assert not user.check_password("foobarbaz")[0] assert not user.check_password("foobarbaz")[0]
hash = profile_hash("user", user.emails[0], user.password[0]) hash = profile_hash("user", user.preferred_email, user.password[0])
res = testclient.get("/reset/user/" + hash, status=200) res = testclient.get("/reset/user/" + hash, status=200)
@ -31,7 +31,7 @@ def test_password_reset_bad_link(testclient, user):
def test_password_reset_bad_password(testclient, user): def test_password_reset_bad_password(testclient, user):
hash = profile_hash("user", user.emails[0], user.password[0]) hash = profile_hash("user", user.preferred_email, user.password[0])
res = testclient.get("/reset/user/" + hash, status=200) res = testclient.get("/reset/user/" + hash, status=200)