custom_user.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from django.contrib.auth.models import (
  2. AbstractBaseUser,
  3. AbstractUser,
  4. BaseUserManager,
  5. Group,
  6. Permission,
  7. PermissionsMixin,
  8. UserManager,
  9. )
  10. from django.db import models
  11. # The custom user uses email as the unique identifier, and requires
  12. # that every user provide a date of birth. This lets us test
  13. # changes in username datatype, and non-text required fields.
  14. class CustomUserManager(BaseUserManager):
  15. def create_user(self, email, date_of_birth, password=None, **fields):
  16. """
  17. Creates and saves a User with the given email and password.
  18. """
  19. if not email:
  20. raise ValueError("Users must have an email address")
  21. user = self.model(
  22. email=self.normalize_email(email), date_of_birth=date_of_birth, **fields
  23. )
  24. user.set_password(password)
  25. user.save(using=self._db)
  26. return user
  27. async def acreate_user(self, email, date_of_birth, password=None, **fields):
  28. """See create_user()"""
  29. if not email:
  30. raise ValueError("Users must have an email address")
  31. user = self.model(
  32. email=self.normalize_email(email), date_of_birth=date_of_birth, **fields
  33. )
  34. user.set_password(password)
  35. await user.asave(using=self._db)
  36. return user
  37. def create_superuser(self, email, password, date_of_birth, **fields):
  38. u = self.create_user(
  39. email, password=password, date_of_birth=date_of_birth, **fields
  40. )
  41. u.is_admin = True
  42. u.save(using=self._db)
  43. return u
  44. class CustomUser(AbstractBaseUser):
  45. email = models.EmailField(verbose_name="email address", max_length=255, unique=True)
  46. is_active = models.BooleanField(default=True)
  47. is_admin = models.BooleanField(default=False)
  48. date_of_birth = models.DateField()
  49. first_name = models.CharField(max_length=50)
  50. custom_objects = CustomUserManager()
  51. USERNAME_FIELD = "email"
  52. REQUIRED_FIELDS = ["date_of_birth", "first_name"]
  53. def __str__(self):
  54. return self.email
  55. # Maybe required?
  56. def get_group_permissions(self, obj=None):
  57. return set()
  58. def get_all_permissions(self, obj=None):
  59. return set()
  60. def has_perm(self, perm, obj=None):
  61. return True
  62. def has_perms(self, perm_list, obj=None):
  63. return True
  64. def has_module_perms(self, app_label):
  65. return True
  66. # Admin required fields
  67. @property
  68. def is_staff(self):
  69. return self.is_admin
  70. class RemoveGroupsAndPermissions:
  71. """
  72. A context manager to temporarily remove the groups and user_permissions M2M
  73. fields from the AbstractUser class, so they don't clash with the
  74. related_name sets.
  75. """
  76. def __enter__(self):
  77. self._old_au_local_m2m = AbstractUser._meta.local_many_to_many
  78. self._old_pm_local_m2m = PermissionsMixin._meta.local_many_to_many
  79. groups = models.ManyToManyField(Group, blank=True)
  80. groups.contribute_to_class(PermissionsMixin, "groups")
  81. user_permissions = models.ManyToManyField(Permission, blank=True)
  82. user_permissions.contribute_to_class(PermissionsMixin, "user_permissions")
  83. PermissionsMixin._meta.local_many_to_many = [groups, user_permissions]
  84. AbstractUser._meta.local_many_to_many = [groups, user_permissions]
  85. def __exit__(self, exc_type, exc_value, traceback):
  86. AbstractUser._meta.local_many_to_many = self._old_au_local_m2m
  87. PermissionsMixin._meta.local_many_to_many = self._old_pm_local_m2m
  88. class CustomUserWithoutIsActiveField(AbstractBaseUser):
  89. username = models.CharField(max_length=150, unique=True)
  90. email = models.EmailField(unique=True)
  91. objects = UserManager()
  92. USERNAME_FIELD = "username"
  93. # The extension user is a simple extension of the built-in user class,
  94. # adding a required date_of_birth field. This allows us to check for
  95. # any hard references to the name "User" in forms/handlers etc.
  96. with RemoveGroupsAndPermissions():
  97. class ExtensionUser(AbstractUser):
  98. date_of_birth = models.DateField()
  99. custom_objects = UserManager()
  100. REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ["date_of_birth"]