Repository: pennersr/django-allauth
Pull request #3986 (2024-07-21 19:21:48)

Update django.po better translate with native language person from Perian(Farsi)
better translate with native language person.

# Submitting Pull Requests

## General

 - [ ] Make sure you use [semantic commit messages](https://seesparkbox.com/foundry/semantic_commit_messages).
       Examples: `"fix(google): Fixed foobar bug"`, `"feat(accounts): Added foobar feature"`.
 - [ ] All Python code must formatted using Black, and clean from pep8 and isort issues.
 - [ ] JavaScript code should adhere to [StandardJS](https://standardjs.com).
 - [ ] If your changes are significant, please update `ChangeLog.rst`.
 - [ ] If your change is substantial, feel free to add yourself to `AUTHORS`.

 ## Provider Specifics

 In case you add a new provider:

- [ ] Make sure unit tests are available.
- [ ] Add an entry of your provider in `test_settings.py::INSTALLED_APPS` and `docs/installation.rst::INSTALLED_APPS`.
- [ ] Add documentation to `docs/providers/<provider name>.rst` and `docs/providers/index.rst` Provider Specifics toctree.
- [ ] Add an entry to the list of supported providers over at `docs/overview.rst`.


coveralls: 
[![Coverage Status](https://coveralls.io/builds/68785338/badge)](https://coveralls.io/builds/68785338)

coverage: 95.767%. remained the same
when pulling **f90114db102c31861abbe539b1f96d95716fa1f8 on sinalalebakhsh:patch-1**
into **c76e9fbd3b03e16d272a9f0d0f69ba762e03812a on pennersr:main**.

sinalalebakhsh: ?

Patch:
diff --git a/allauth/account/utils.py b/allauth/account/utils.py
index f36547c4..ea6ee333 100644
--- a/allauth/account/utils.py
+++ b/allauth/account/utils.py
@@ -69,10 +69,10 @@ _user_display_callable = None
 
 
 def default_user_display(user) -> str:
+    ret = ""
     if app_settings.USER_MODEL_USERNAME_FIELD:
-        return getattr(user, app_settings.USER_MODEL_USERNAME_FIELD)
-    else:
-        return force_str(user)
+        ret = getattr(user, app_settings.USER_MODEL_USERNAME_FIELD)
+    return ret or force_str(user) or user._meta.verbose_name
 
 
 def user_display(user) -> str:
diff --git a/allauth/headless/internal/authkit.py b/allauth/headless/internal/authkit.py
index 6b231fb2..a705199f 100644
--- a/allauth/headless/internal/authkit.py
+++ b/allauth/headless/internal/authkit.py
@@ -1,6 +1,8 @@
 import typing
 from contextlib import contextmanager
 
+from django.utils.functional import SimpleLazyObject, empty
+
 from allauth import app_settings as allauth_settings
 from allauth.account.stages import LoginStageController
 from allauth.account.utils import unstash_login
@@ -37,8 +39,11 @@ class AuthenticationStatus:
 
 
 def purge_request_user_cache(request):
-    if hasattr(request, "_cached_user"):
-        delattr(request, "_cached_user")
+    for attr in ["_cached_user", "_acached_user"]:
+        if hasattr(request, attr):
+            delattr(request, attr)
+    if isinstance(request.user, SimpleLazyObject):
+        request.user._wrapped = empty
 
 
 @contextmanager
diff --git a/allauth/locale/fa/LC_MESSAGES/django.po b/allauth/locale/fa/LC_MESSAGES/django.po
index cb58d477..ee327656 100644
--- a/allauth/locale/fa/LC_MESSAGES/django.po
+++ b/allauth/locale/fa/LC_MESSAGES/django.po
@@ -32,7 +32,7 @@ msgstr "نمی‌توانی نشانی رایانامه‌ی اصلی‌ات (%(
 #, fuzzy
 #| msgid "This email address is already associated with another account."
 msgid "This email address is already associated with this account."
-msgstr "این نشانی رایانامه ازقبل به این حساب وصل شده."
+msgstr "این نشانی ایمیل ازقبل به این حساب وصل شده."
 
 #: account/adapter.py:66
 msgid "The email address and/or password you specified are not correct."
@@ -40,7 +40,7 @@ msgstr "نشانی رایانامه یا گذرواژه نادرست است."
 
 #: account/adapter.py:68
 msgid "A user is already registered with this email address."
-msgstr "یک کاربر ازقبل با این نشانی رایانامه ثبت شده."
+msgstr " یک کاربر ازقبل با این نشانی ایمیل ثبت شده است."
 
 #: account/adapter.py:69
 msgid "Please type your current password."
@@ -69,16 +69,16 @@ msgstr "نمی توانید بیش از %d آدرس ایمیل اضافه کنی
 
 #: account/adapter.py:76
 msgid "Too many failed login attempts. Try again later."
-msgstr "خیلی زیاد تلاش ناموفق کردی، لطفا بعدا ازنو سعی کن."
+msgstr "خیلی زیاد تلاش ناموفق کردی، لطفا بعدا دوباره سعی کن."
 
 #: account/adapter.py:78
 msgid "The email address is not assigned to any user account"
-msgstr "این نشانی رایانامه به هیچ حساب کاربری‌ای منتسب نشده."
+msgstr "این نشانی ایمیل به هیچ حساب کاربری‌ای منتسب نشده."
 
 #: account/adapter.py:79
 #: templates/account/messages/unverified_primary_email.txt:2
 msgid "Your primary email address must be verified."
-msgstr "نشانی رایانامه‌ی اصلی‌ات باید تاییدشده باشد."
+msgstr "نشانی ایمیل اصلی‌ات باید تایید شده باشد."
 
 #: account/adapter.py:81
 msgid "Username can not be used. Please use other username."
@@ -111,7 +111,7 @@ msgstr "کلید محرمانه"
 #, fuzzy
 #| msgid "Your primary email address must be verified."
 msgid "Mark selected email addresses as verified"
-msgstr "نشانی رایانامه‌ی اصلی‌ات باید تاییدشده باشد."
+msgstr "نشانی ایمیل اصلی‌ات باید تاییدشده باشد."
 
 #: account/apps.py:11
 #, fuzzy
@@ -120,7 +120,7 @@ msgstr "حساب‌ها"
 
 #: account/forms.py:56 account/forms.py:479
 msgid "You must type the same password each time."
-msgstr "هربار باید گذرواژه‌ی یکسانی وارد کنی."
+msgstr "هربار باید گذرواژه‌ی یکسانی را وارد کنی."
 
 #: account/forms.py:91 account/forms.py:409 account/forms.py:560
 #: account/forms.py:674
@@ -129,7 +129,7 @@ msgstr "گذرواژه"
 
 #: account/forms.py:92
 msgid "Remember Me"
-msgstr "مرا به یادآور"
+msgstr "مرا به حفظ کن"
 
 #: account/forms.py:102 account/forms.py:269 account/forms.py:495
 #: account/forms.py:578 account/forms.py:691
@@ -139,7 +139,7 @@ msgstr "نشانی رایانامه"
 #: account/forms.py:106 account/forms.py:307 account/forms.py:492
 #: account/forms.py:573
 msgid "Email"
-msgstr "رایانامه"
+msgstr "ایمیل"
 
 #: account/forms.py:109 account/forms.py:112 account/forms.py:259
 #: account/forms.py:262
@@ -165,7 +165,7 @@ msgstr "گذرواژه‌ات را فراموش کرده‌ای؟"
 #, fuzzy
 #| msgid "Email (optional)"
 msgid "Email (again)"
-msgstr "رایانامه (ازنو)"
+msgstr "ایمیل (دوباره)"
 
 #: account/forms.py:302
 #, fuzzy
@@ -175,13 +175,13 @@ msgstr "تاییدیه‌ی نشانی رایانامه"
 
 #: account/forms.py:310
 msgid "Email (optional)"
-msgstr "رایانامه (اختیاری)"
+msgstr "ایمیل (اختیاری)"
 
 #: account/forms.py:369
 #, fuzzy
 #| msgid "You must type the same password each time."
 msgid "You must type the same email each time."
-msgstr "هربار باید رایانامه‌ی یکسانی وارد کنی."
+msgstr "هربار باید ایمیل یکسانی وارد کنی."
 
 #: account/forms.py:415 account/forms.py:561
 msgid "Password (again)"
@@ -210,7 +210,7 @@ msgstr "کاربر"
 
 #: account/models.py:30 account/models.py:38 account/models.py:150
 msgid "email address"
-msgstr "نشانی رایانامه"
+msgstr "نشانی ایمیل"
 
 #: account/models.py:32
 msgid "verified"
@@ -238,15 +238,15 @@ msgstr "کلید"
 
 #: account/models.py:160
 msgid "email confirmation"
-msgstr "تاییدیه‌ی رایانامه"
+msgstr "تاییدیه‌ی ایمیل"
 
 #: account/models.py:161
 msgid "email confirmations"
-msgstr "تاییدیه‌های رایانامه"
+msgstr "تاییدیه‌های ایمیل"
 
 #: headless/apps.py:7
 msgid "Headless"
-msgstr ""
+msgstr "بی نتیجه"
 
 #: mfa/adapter.py:32
 msgid ""
@@ -256,7 +256,7 @@ msgstr ""
 
 #: mfa/adapter.py:35
 msgid "You cannot deactivate two-factor authentication."
-msgstr ""
+msgstr "شما نمی توانید یک آدرس ایمیل محافظت شده توسط احراز هویت دوعاملی را غیر فعال کنید"
 
 #: mfa/adapter.py:38
 msgid ""
diff --git a/allauth/socialaccount/providers/saml/provider.py b/allauth/socialaccount/providers/saml/provider.py
index f5e5e309..d68c11a3 100644
--- a/allauth/socialaccount/providers/saml/provider.py
+++ b/allauth/socialaccount/providers/saml/provider.py
@@ -106,10 +106,11 @@ class SAMLProvider(Provider):
             attributes["email_verified"] = email_verified
 
         # If we did not find an email, check if the NameID contains the email.
-        if (
-            not attributes.get("email")
-            and data.get_nameid_format()
+        if not attributes.get("email") and (
+            data.get_nameid_format()
             == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
+            # Alternatively, if `use_id_for_email` is true, then we always interpret the nameID as email
+            or provider_config.get("use_nameid_for_email", False)
         ):
             attributes["email"] = data.get_nameid()
 
diff --git a/docs/socialaccount/providers/saml.rst b/docs/socialaccount/providers/saml.rst
index 7479b054..ddcac98a 100644
--- a/docs/socialaccount/providers/saml.rst
+++ b/docs/socialaccount/providers/saml.rst
@@ -68,6 +68,7 @@ via the Django admin as well:
                     # additional configuration is needed, which is placed in
                     # `SocialApp.settings`:
                     "settings": {
+
                         # Mapping account attributes to upstream (IdP specific) attributes.
                         # If left empty, an attempt will be done to map the attributes using
                         # built-in defaults.
@@ -76,6 +77,12 @@ via the Django admin as well:
                             "email_verified": "http://schemas.auth0.com/email_verified",
                             "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
                         },
+
+                        # The following setting allows you to force the use of nameID as email.
+                        # This can be useful if you are using a SAML IdP that is broken in some way and
+                        # does not allow use of the emailAddress nameid format
+                        "use_nameid_for_email": False,
+
                         # The configuration of the IdP.
                         "idp": {
                             # The entity ID of the IdP is required.


Test patch:
diff --git a/allauth/headless/internal/tests/__init__.py b/allauth/headless/internal/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/allauth/headless/internal/tests/test_authkit.py b/allauth/headless/internal/tests/test_authkit.py
new file mode 100644
index 00000000..5bd76489
--- /dev/null
+++ b/allauth/headless/internal/tests/test_authkit.py
@@ -0,0 +1,28 @@
+from django.contrib.auth import (
+    BACKEND_SESSION_KEY,
+    HASH_SESSION_KEY,
+    SESSION_KEY,
+)
+from django.contrib.auth.middleware import AuthenticationMiddleware
+from django.contrib.sessions.middleware import SessionMiddleware
+from django.http import HttpResponse
+
+from allauth.headless.internal.authkit import purge_request_user_cache
+
+
+def test_purge_request_user_cache(rf, user):
+    request = rf.get("/")
+    smw = SessionMiddleware(lambda request: HttpResponse())
+    smw(request)
+    amw = AuthenticationMiddleware(lambda request: HttpResponse())
+    amw(request)
+    assert request.user.is_anonymous
+    assert not request.user.pk
+    purge_request_user_cache(request)
+    request.session[SESSION_KEY] = user.pk
+    request.session[BACKEND_SESSION_KEY] = (
+        "allauth.account.auth_backends.AuthenticationBackend"
+    )
+    request.session[HASH_SESSION_KEY] = user.get_session_auth_hash()
+    assert request.user.is_authenticated
+    assert request.user.pk == user.pk