mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.8.x] Moved non-documented auth test models to the new test location.
Backport of 5ab327a389 from master
			
			
This commit is contained in:
		| @@ -8,7 +8,6 @@ from django.db import models | |||||||
| # The custom User uses email as the unique identifier, and requires | # The custom User uses email as the unique identifier, and requires | ||||||
| # that every user provide a date of birth. This lets us test | # that every user provide a date of birth. This lets us test | ||||||
| # changes in username datatype, and non-text required fields. | # changes in username datatype, and non-text required fields. | ||||||
|  |  | ||||||
| class CustomUserManager(BaseUserManager): | class CustomUserManager(BaseUserManager): | ||||||
|     def create_user(self, email, date_of_birth, password=None): |     def create_user(self, email, date_of_birth, password=None): | ||||||
|         """ |         """ | ||||||
| @@ -33,18 +32,6 @@ class CustomUserManager(BaseUserManager): | |||||||
|         return u |         return u | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomUserWithFKManager(BaseUserManager): |  | ||||||
|     def create_superuser(self, username, email, group, password): |  | ||||||
|         user = self.model(username_id=username, email_id=email, group_id=group) |  | ||||||
|         user.set_password(password) |  | ||||||
|         user.save(using=self._db) |  | ||||||
|         return user |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Email(models.Model): |  | ||||||
|     email = models.EmailField(verbose_name='email address', max_length=255, unique=True) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomUser(AbstractBaseUser): | class CustomUser(AbstractBaseUser): | ||||||
|     email = models.EmailField(verbose_name='email address', max_length=255, unique=True) |     email = models.EmailField(verbose_name='email address', max_length=255, unique=True) | ||||||
|     is_active = models.BooleanField(default=True) |     is_active = models.BooleanField(default=True) | ||||||
| @@ -90,132 +77,37 @@ class CustomUser(AbstractBaseUser): | |||||||
|         return self.is_admin |         return self.is_admin | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomUserWithFK(AbstractBaseUser): | class RemoveGroupsAndPermissions(object): | ||||||
|     username = models.ForeignKey(Email, related_name='primary') |     """ | ||||||
|     email = models.ForeignKey(Email, to_field='email', related_name='secondary') |     A context manager to temporarily remove the groups and user_permissions M2M | ||||||
|     group = models.ForeignKey(Group) |     fields from the AbstractUser class, so they don't clash with the | ||||||
|  |     related_name sets. | ||||||
|  |     """ | ||||||
|  |     def __enter__(self): | ||||||
|  |         self._old_au_local_m2m = AbstractUser._meta.local_many_to_many | ||||||
|  |         self._old_pm_local_m2m = PermissionsMixin._meta.local_many_to_many | ||||||
|  |         groups = models.ManyToManyField(Group, blank=True) | ||||||
|  |         groups.contribute_to_class(PermissionsMixin, "groups") | ||||||
|  |         user_permissions = models.ManyToManyField(Permission, blank=True) | ||||||
|  |         user_permissions.contribute_to_class(PermissionsMixin, "user_permissions") | ||||||
|  |         PermissionsMixin._meta.local_many_to_many = [groups, user_permissions] | ||||||
|  |         AbstractUser._meta.local_many_to_many = [groups, user_permissions] | ||||||
|  |  | ||||||
|     custom_objects = CustomUserWithFKManager() |     def __exit__(self, exc_type, exc_value, traceback): | ||||||
|  |         AbstractUser._meta.local_many_to_many = self._old_au_local_m2m | ||||||
|     USERNAME_FIELD = 'username' |         PermissionsMixin._meta.local_many_to_many = self._old_pm_local_m2m | ||||||
|     REQUIRED_FIELDS = ['email', 'group'] |  | ||||||
|  |  | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # At this point, temporarily remove the groups and user_permissions M2M |  | ||||||
| # fields from the AbstractUser class, so they don't clash with the related_name |  | ||||||
| # that sets. |  | ||||||
|  |  | ||||||
| old_au_local_m2m = AbstractUser._meta.local_many_to_many |  | ||||||
| old_pm_local_m2m = PermissionsMixin._meta.local_many_to_many |  | ||||||
| groups = models.ManyToManyField(Group, blank=True) |  | ||||||
| groups.contribute_to_class(PermissionsMixin, "groups") |  | ||||||
| user_permissions = models.ManyToManyField(Permission, blank=True) |  | ||||||
| user_permissions.contribute_to_class(PermissionsMixin, "user_permissions") |  | ||||||
| PermissionsMixin._meta.local_many_to_many = [groups, user_permissions] |  | ||||||
| AbstractUser._meta.local_many_to_many = [groups, user_permissions] |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # The extension user is a simple extension of the built-in user class, | # The extension user is a simple extension of the built-in user class, | ||||||
| # adding a required date_of_birth field. This allows us to check for | # adding a required date_of_birth field. This allows us to check for | ||||||
| # any hard references to the name "User" in forms/handlers etc. | # any hard references to the name "User" in forms/handlers etc. | ||||||
|  | with RemoveGroupsAndPermissions(): | ||||||
|  |     class ExtensionUser(AbstractUser): | ||||||
|  |         date_of_birth = models.DateField() | ||||||
|  |  | ||||||
| class ExtensionUser(AbstractUser): |         custom_objects = UserManager() | ||||||
|     date_of_birth = models.DateField() |  | ||||||
|  |  | ||||||
|     custom_objects = UserManager() |         REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ['date_of_birth'] | ||||||
|  |  | ||||||
|     REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ['date_of_birth'] |         class Meta: | ||||||
|  |             app_label = 'auth' | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # The CustomPermissionsUser users email as the identifier, but uses the normal |  | ||||||
| # Django permissions model. This allows us to check that the PermissionsMixin |  | ||||||
| # includes everything that is needed to interact with the ModelBackend. |  | ||||||
|  |  | ||||||
| class CustomPermissionsUserManager(CustomUserManager): |  | ||||||
|     def create_superuser(self, email, password, date_of_birth): |  | ||||||
|         u = self.create_user(email, password=password, date_of_birth=date_of_birth) |  | ||||||
|         u.is_superuser = True |  | ||||||
|         u.save(using=self._db) |  | ||||||
|         return u |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomPermissionsUser(AbstractBaseUser, PermissionsMixin): |  | ||||||
|     email = models.EmailField(verbose_name='email address', max_length=255, unique=True) |  | ||||||
|     date_of_birth = models.DateField() |  | ||||||
|  |  | ||||||
|     custom_objects = CustomPermissionsUserManager() |  | ||||||
|  |  | ||||||
|     USERNAME_FIELD = 'email' |  | ||||||
|     REQUIRED_FIELDS = ['date_of_birth'] |  | ||||||
|  |  | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
|     def get_full_name(self): |  | ||||||
|         return self.email |  | ||||||
|  |  | ||||||
|     def get_short_name(self): |  | ||||||
|         return self.email |  | ||||||
|  |  | ||||||
|     def __unicode__(self): |  | ||||||
|         return self.email |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class IsActiveTestUser1(AbstractBaseUser): |  | ||||||
|     """ |  | ||||||
|     This test user class and derivatives test the default is_active behavior |  | ||||||
|     """ |  | ||||||
|     username = models.CharField(max_length=30, unique=True) |  | ||||||
|  |  | ||||||
|     custom_objects = BaseUserManager() |  | ||||||
|  |  | ||||||
|     USERNAME_FIELD = 'username' |  | ||||||
|  |  | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
|     # the is_active attr is provided by AbstractBaseUser |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomUserNonUniqueUsername(AbstractBaseUser): |  | ||||||
|     "A user with a non-unique username" |  | ||||||
|     username = models.CharField(max_length=30) |  | ||||||
|  |  | ||||||
|     USERNAME_FIELD = 'username' |  | ||||||
|  |  | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomUserNonListRequiredFields(AbstractBaseUser): |  | ||||||
|     "A user with a non-list REQUIRED_FIELDS" |  | ||||||
|     username = models.CharField(max_length=30, unique=True) |  | ||||||
|     date_of_birth = models.DateField() |  | ||||||
|  |  | ||||||
|     USERNAME_FIELD = 'username' |  | ||||||
|     REQUIRED_FIELDS = 'date_of_birth' |  | ||||||
|  |  | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CustomUserBadRequiredFields(AbstractBaseUser): |  | ||||||
|     "A user with a USERNAME_FIELD that appears in REQUIRED_FIELDS (invalid)" |  | ||||||
|     username = models.CharField(max_length=30, unique=True) |  | ||||||
|     date_of_birth = models.DateField() |  | ||||||
|  |  | ||||||
|     USERNAME_FIELD = 'username' |  | ||||||
|     REQUIRED_FIELDS = ['username', 'date_of_birth'] |  | ||||||
|  |  | ||||||
|     class Meta: |  | ||||||
|         app_label = 'auth' |  | ||||||
|  |  | ||||||
| # Undo swap hack |  | ||||||
| AbstractUser._meta.local_many_to_many = old_au_local_m2m |  | ||||||
| PermissionsMixin._meta.local_many_to_many = old_pm_local_m2m |  | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								tests/auth_tests/models/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/auth_tests/models/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | from .custom_permissions import CustomPermissionsUser | ||||||
|  | from .is_active import IsActiveTestUser1 | ||||||
|  | from .invalid_models import ( | ||||||
|  |     CustomUserNonUniqueUsername, CustomUserNonListRequiredFields, | ||||||
|  |     CustomUserBadRequiredFields, | ||||||
|  | ) | ||||||
|  | from .with_foreign_key import CustomUserWithFK, Email | ||||||
|  |  | ||||||
|  | __all__ = ( | ||||||
|  |     'CustomPermissionsUser', 'CustomUserNonUniqueUsername', | ||||||
|  |     'CustomUserNonListRequiredFields', 'CustomUserBadRequiredFields', | ||||||
|  |     'CustomUserWithFK', 'Email', 'IsActiveTestUser1', | ||||||
|  | ) | ||||||
							
								
								
									
										43
									
								
								tests/auth_tests/models/custom_permissions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								tests/auth_tests/models/custom_permissions.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | """ | ||||||
|  | The CustomPermissionsUser users email as the identifier, but uses the normal | ||||||
|  | Django permissions model. This allows us to check that the PermissionsMixin | ||||||
|  | includes everything that is needed to interact with the ModelBackend. | ||||||
|  | """ | ||||||
|  | from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin | ||||||
|  | from django.contrib.auth.tests.custom_user import ( | ||||||
|  |     CustomUserManager, RemoveGroupsAndPermissions, | ||||||
|  | ) | ||||||
|  | from django.db import models | ||||||
|  | from django.utils.encoding import python_2_unicode_compatible | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CustomPermissionsUserManager(CustomUserManager): | ||||||
|  |     def create_superuser(self, email, password, date_of_birth): | ||||||
|  |         u = self.create_user(email, password=password, date_of_birth=date_of_birth) | ||||||
|  |         u.is_superuser = True | ||||||
|  |         u.save(using=self._db) | ||||||
|  |         return u | ||||||
|  |  | ||||||
|  |  | ||||||
|  | with RemoveGroupsAndPermissions(): | ||||||
|  |     @python_2_unicode_compatible | ||||||
|  |     class CustomPermissionsUser(AbstractBaseUser, PermissionsMixin): | ||||||
|  |         email = models.EmailField(verbose_name='email address', max_length=255, unique=True) | ||||||
|  |         date_of_birth = models.DateField() | ||||||
|  |  | ||||||
|  |         custom_objects = CustomPermissionsUserManager() | ||||||
|  |  | ||||||
|  |         USERNAME_FIELD = 'email' | ||||||
|  |         REQUIRED_FIELDS = ['date_of_birth'] | ||||||
|  |  | ||||||
|  |         class Meta: | ||||||
|  |             app_label = 'auth' | ||||||
|  |  | ||||||
|  |         def get_full_name(self): | ||||||
|  |             return self.email | ||||||
|  |  | ||||||
|  |         def get_short_name(self): | ||||||
|  |             return self.email | ||||||
|  |  | ||||||
|  |         def __str__(self): | ||||||
|  |             return self.email | ||||||
							
								
								
									
										36
									
								
								tests/auth_tests/models/invalid_models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								tests/auth_tests/models/invalid_models.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | from django.contrib.auth.models import AbstractBaseUser | ||||||
|  | from django.db import models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CustomUserNonUniqueUsername(AbstractBaseUser): | ||||||
|  |     "A user with a non-unique username" | ||||||
|  |     username = models.CharField(max_length=30) | ||||||
|  |  | ||||||
|  |     USERNAME_FIELD = 'username' | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         app_label = 'auth' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CustomUserNonListRequiredFields(AbstractBaseUser): | ||||||
|  |     "A user with a non-list REQUIRED_FIELDS" | ||||||
|  |     username = models.CharField(max_length=30, unique=True) | ||||||
|  |     date_of_birth = models.DateField() | ||||||
|  |  | ||||||
|  |     USERNAME_FIELD = 'username' | ||||||
|  |     REQUIRED_FIELDS = 'date_of_birth' | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         app_label = 'auth' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CustomUserBadRequiredFields(AbstractBaseUser): | ||||||
|  |     "A user with a USERNAME_FIELD that appears in REQUIRED_FIELDS (invalid)" | ||||||
|  |     username = models.CharField(max_length=30, unique=True) | ||||||
|  |     date_of_birth = models.DateField() | ||||||
|  |  | ||||||
|  |     USERNAME_FIELD = 'username' | ||||||
|  |     REQUIRED_FIELDS = ['username', 'date_of_birth'] | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         app_label = 'auth' | ||||||
							
								
								
									
										18
									
								
								tests/auth_tests/models/is_active.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/auth_tests/models/is_active.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | from django.contrib.auth.models import AbstractBaseUser, BaseUserManager | ||||||
|  | from django.db import models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class IsActiveTestUser1(AbstractBaseUser): | ||||||
|  |     """ | ||||||
|  |     This test user class and derivatives test the default is_active behavior | ||||||
|  |     """ | ||||||
|  |     username = models.CharField(max_length=30, unique=True) | ||||||
|  |  | ||||||
|  |     custom_objects = BaseUserManager() | ||||||
|  |  | ||||||
|  |     USERNAME_FIELD = 'username' | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         app_label = 'auth' | ||||||
|  |  | ||||||
|  |     # the is_active attr is provided by AbstractBaseUser | ||||||
							
								
								
									
										31
									
								
								tests/auth_tests/models/with_foreign_key.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tests/auth_tests/models/with_foreign_key.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, Group | ||||||
|  | from django.db import models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Email(models.Model): | ||||||
|  |     email = models.EmailField(verbose_name='email address', max_length=255, unique=True) | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         app_label = 'auth' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CustomUserWithFKManager(BaseUserManager): | ||||||
|  |     def create_superuser(self, username, email, group, password): | ||||||
|  |         user = self.model(username_id=username, email_id=email, group_id=group) | ||||||
|  |         user.set_password(password) | ||||||
|  |         user.save(using=self._db) | ||||||
|  |         return user | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CustomUserWithFK(AbstractBaseUser): | ||||||
|  |     username = models.ForeignKey(Email, related_name='primary') | ||||||
|  |     email = models.ForeignKey(Email, to_field='email', related_name='secondary') | ||||||
|  |     group = models.ForeignKey(Group) | ||||||
|  |  | ||||||
|  |     custom_objects = CustomUserWithFKManager() | ||||||
|  |  | ||||||
|  |     USERNAME_FIELD = 'username' | ||||||
|  |     REQUIRED_FIELDS = ['email', 'group'] | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         app_label = 'auth' | ||||||
| @@ -7,14 +7,14 @@ from django.contrib.auth import BACKEND_SESSION_KEY, authenticate, get_user | |||||||
| from django.contrib.auth.backends import ModelBackend | from django.contrib.auth.backends import ModelBackend | ||||||
| from django.contrib.auth.hashers import MD5PasswordHasher | from django.contrib.auth.hashers import MD5PasswordHasher | ||||||
| from django.contrib.auth.models import AnonymousUser, Group, Permission, User | from django.contrib.auth.models import AnonymousUser, Group, Permission, User | ||||||
| from django.contrib.auth.tests.custom_user import ( | from django.contrib.auth.tests.custom_user import CustomUser, ExtensionUser | ||||||
|     CustomPermissionsUser, CustomUser, ExtensionUser, |  | ||||||
| ) |  | ||||||
| from django.contrib.contenttypes.models import ContentType | from django.contrib.contenttypes.models import ContentType | ||||||
| from django.core.exceptions import ImproperlyConfigured, PermissionDenied | from django.core.exceptions import ImproperlyConfigured, PermissionDenied | ||||||
| from django.http import HttpRequest | from django.http import HttpRequest | ||||||
| from django.test import TestCase, modify_settings, override_settings | from django.test import TestCase, modify_settings, override_settings | ||||||
|  |  | ||||||
|  | from .models import CustomPermissionsUser | ||||||
|  |  | ||||||
|  |  | ||||||
| class CountingMD5PasswordHasher(MD5PasswordHasher): | class CountingMD5PasswordHasher(MD5PasswordHasher): | ||||||
|     """Hasher that counts how many times it computes a hash.""" |     """Hasher that counts how many times it computes a hash.""" | ||||||
|   | |||||||
| @@ -12,10 +12,7 @@ from django.contrib.auth.management.commands import ( | |||||||
|     changepassword, createsuperuser, |     changepassword, createsuperuser, | ||||||
| ) | ) | ||||||
| from django.contrib.auth.models import Group, User | from django.contrib.auth.models import Group, User | ||||||
| from django.contrib.auth.tests.custom_user import ( | from django.contrib.auth.tests.custom_user import CustomUser | ||||||
|     CustomUser, CustomUserBadRequiredFields, CustomUserNonListRequiredFields, |  | ||||||
|     CustomUserNonUniqueUsername, CustomUserWithFK, Email, |  | ||||||
| ) |  | ||||||
| from django.contrib.contenttypes.models import ContentType | from django.contrib.contenttypes.models import ContentType | ||||||
| from django.core import checks, exceptions | from django.core import checks, exceptions | ||||||
| from django.core.management import call_command | from django.core.management import call_command | ||||||
| @@ -25,6 +22,11 @@ from django.utils import six | |||||||
| from django.utils.encoding import force_str | from django.utils.encoding import force_str | ||||||
| from django.utils.translation import ugettext_lazy as _ | from django.utils.translation import ugettext_lazy as _ | ||||||
|  |  | ||||||
|  | from .models import ( | ||||||
|  |     CustomUserBadRequiredFields, CustomUserNonListRequiredFields, | ||||||
|  |     CustomUserNonUniqueUsername, CustomUserWithFK, Email, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
| def mock_inputs(inputs): | def mock_inputs(inputs): | ||||||
|     """ |     """ | ||||||
|   | |||||||
| @@ -2,8 +2,6 @@ from django.contrib.auth import get_user_model | |||||||
| from django.contrib.auth.models import ( | from django.contrib.auth.models import ( | ||||||
|     AbstractUser, Group, Permission, User, UserManager, |     AbstractUser, Group, Permission, User, UserManager, | ||||||
| ) | ) | ||||||
| # Needed so model is installed when tests are run independently: |  | ||||||
| from django.contrib.auth.tests.custom_user import IsActiveTestUser1  # NOQA |  | ||||||
| from django.contrib.contenttypes.models import ContentType | from django.contrib.contenttypes.models import ContentType | ||||||
| from django.core import mail | from django.core import mail | ||||||
| from django.db.models.signals import post_save | from django.db.models.signals import post_save | ||||||
|   | |||||||
| @@ -13,8 +13,6 @@ from django.contrib.auth.forms import ( | |||||||
|     AuthenticationForm, PasswordChangeForm, SetPasswordForm, |     AuthenticationForm, PasswordChangeForm, SetPasswordForm, | ||||||
| ) | ) | ||||||
| from django.contrib.auth.models import User | from django.contrib.auth.models import User | ||||||
| # Needed so model is installed when tests are run independently: |  | ||||||
| from django.contrib.auth.tests.custom_user import CustomUser  # NOQA |  | ||||||
| from django.contrib.auth.views import login as login_view, redirect_to_login | from django.contrib.auth.views import login as login_view, redirect_to_login | ||||||
| from django.contrib.sessions.middleware import SessionMiddleware | from django.contrib.sessions.middleware import SessionMiddleware | ||||||
| from django.contrib.sites.requests import RequestSite | from django.contrib.sites.requests import RequestSite | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user