summaryrefslogtreecommitdiff
path: root/tests/auth_tests/test_forms.py
diff options
context:
space:
mode:
authornessita <124304+nessita@users.noreply.github.com>2025-02-01 22:49:07 -0300
committerNatalia <124304+nessita@users.noreply.github.com>2025-02-01 22:50:26 -0300
commitaffad13d0c56184e2089cd7e8ecd80dd4217f6c4 (patch)
treedc9496afe0bfa2efb0fb9557756dd658e4ed780b /tests/auth_tests/test_forms.py
parente939cffa504837d90cf2958306f57649ee6a8323 (diff)
[5.2.x] Fixed #36140 -- Allowed BaseUserCreationForm to define non required password fields.
Regression in e626716c28b6286f8cf0f8174077f3d2244f3eb3. Thanks buffgecko12 for the report and Sarah Boyce for the review. Backport of d15454a6e84a595ffc8dc1b926282f484f782a8f from main.
Diffstat (limited to 'tests/auth_tests/test_forms.py')
-rw-r--r--tests/auth_tests/test_forms.py68
1 files changed, 66 insertions, 2 deletions
diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py
index 5d81d8f7fd..4740cb6200 100644
--- a/tests/auth_tests/test_forms.py
+++ b/tests/auth_tests/test_forms.py
@@ -1,8 +1,10 @@
import datetime
import re
+import sys
import urllib.parse
from unittest import mock
+from django import forms
from django.contrib.auth.forms import (
AdminPasswordChangeForm,
AdminUserCreationForm,
@@ -13,6 +15,7 @@ from django.contrib.auth.forms import (
ReadOnlyPasswordHashField,
ReadOnlyPasswordHashWidget,
SetPasswordForm,
+ SetPasswordMixin,
UserChangeForm,
UserCreationForm,
UsernameField,
@@ -24,13 +27,14 @@ from django.contrib.sites.models import Site
from django.core import mail
from django.core.exceptions import ValidationError
from django.core.mail import EmailMultiAlternatives
-from django.forms import forms
from django.forms.fields import CharField, Field, IntegerField
-from django.test import SimpleTestCase, TestCase, override_settings
+from django.test import RequestFactory, SimpleTestCase, TestCase, override_settings
from django.urls import reverse
from django.utils import translation
from django.utils.text import capfirst
from django.utils.translation import gettext as _
+from django.views.debug import technical_500_response
+from django.views.decorators.debug import sensitive_variables
from .models.custom_user import (
CustomUser,
@@ -412,6 +416,19 @@ class CustomUserCreationFormTest(TestDataMixin, TestCase):
user = form.save(commit=True)
self.assertSequenceEqual(user.orgs.all(), [organization])
+ def test_custom_form_with_non_required_password(self):
+ class CustomUserCreationForm(BaseUserCreationForm):
+ password1 = forms.CharField(required=False)
+ password2 = forms.CharField(required=False)
+ another_field = forms.CharField(required=True)
+
+ data = {
+ "username": "testclientnew",
+ "another_field": "Content",
+ }
+ form = CustomUserCreationForm(data)
+ self.assertIs(form.is_valid(), True, form.errors)
+
class UserCreationFormTest(BaseUserCreationFormTest):
@@ -1671,3 +1688,50 @@ class AdminUserCreationFormTest(BaseUserCreationFormTest):
u = form.save()
self.assertEqual(u.username, data["username"])
self.assertFalse(u.has_usable_password())
+
+
+class SensitiveVariablesTest(TestDataMixin, TestCase):
+ @sensitive_variables("data")
+ def test_passwords_marked_as_sensitive_in_admin_forms(self):
+ data = {
+ "password1": "passwordsensitive",
+ "password2": "sensitivepassword",
+ "usable_password": "true",
+ }
+ forms = [
+ AdminUserCreationForm({**data, "username": "newusername"}),
+ AdminPasswordChangeForm(self.u1, data),
+ ]
+
+ password1_fragment = """
+ <td>password1</td>
+ <td class="code"><pre>&#x27;********************&#x27;</pre></td>
+ """
+ password2_fragment = """
+ <td>password2</td>
+ <td class="code"><pre>&#x27;********************&#x27;</pre></td>
+ """
+ error = ValueError("Forced error")
+ for form in forms:
+ with self.subTest(form=form):
+ with mock.patch.object(
+ SetPasswordMixin, "validate_passwords", side_effect=error
+ ):
+ try:
+ form.is_valid()
+ except ValueError:
+ exc_info = sys.exc_info()
+ else:
+ self.fail("Form validation should have failed.")
+
+ response = technical_500_response(RequestFactory().get("/"), *exc_info)
+
+ self.assertNotContains(response, "sensitivepassword", status_code=500)
+ self.assertNotContains(response, "passwordsensitive", status_code=500)
+ self.assertContains(response, str(error), status_code=500)
+ self.assertContains(
+ response, password1_fragment, html=True, status_code=500
+ )
+ self.assertContains(
+ response, password2_fragment, html=True, status_code=500
+ )