from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager from django.contrib.auth.models import PermissionsMixin from django.contrib.auth.validators import UnicodeUsernameValidator from django.core.mail import send_mail from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ from userausfall import ldap class MissingUserAttribute(Exception): """The user object is missing a required attribute.""" pass class PasswordMismatch(Exception): """The given password does not match the user's password.""" pass class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self, username, password, **extra_fields): """ Create and save a user with the given username, email, and password. """ # email = self.normalize_email(email) username = self.model.normalize_username(username) user = self.model(username=username, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_user(self, username, password=None, **extra_fields): extra_fields.setdefault("is_staff", False) extra_fields.setdefault("is_superuser", False) return self._create_user(username, password, **extra_fields) def create_superuser(self, email, password, **extra_fields): extra_fields.setdefault("is_staff", True) extra_fields.setdefault("is_superuser", True) if extra_fields.get("is_staff") is not True: raise ValueError("Superuser must have is_staff=True.") if extra_fields.get("is_superuser") is not True: raise ValueError("Superuser must have is_superuser=True.") return self._create_user(email, password, **extra_fields) class User(PermissionsMixin, AbstractBaseUser): username_validator = UnicodeUsernameValidator() username = models.CharField( _("username"), max_length=150, help_text=_("Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."), validators=[username_validator], error_messages={"unique": _("A user with that username already exists.")}, unique=True, blank=True, ) is_staff = models.BooleanField( _("staff status"), default=False, help_text=_("Designates whether the user can log into this admin site."), ) date_joined = models.DateTimeField(_("date joined"), default=timezone.now) objects = UserManager() # EMAIL_FIELD = "email" USERNAME_FIELD = "username" REQUIRED_FIELDS = [] class Meta: verbose_name = _("user") verbose_name_plural = _("users") def clean(self): super().clean() self.email = self.__class__.objects.normalize_email(self.email) def email_user(self, subject, message, from_email=None, **kwargs): """Send an email to this user.""" send_mail(subject, message, from_email, [self.email], **kwargs) def create_ldap_account(self, raw_password): """Create the LDAP account which corresponds to this user.""" if not self.username: raise MissingUserAttribute("User is missing a username.") if not self.check_password(raw_password): raise PasswordMismatch("The given password does not match the user's password.") return ldap.create_account(self.username, raw_password) def get_or_create_trust_bridge(self): try: return self.trust_bridge except TrustBridge.DoesNotExist: return TrustBridge.objects.create(trust_taker=self) class TrustBridge(models.Model): is_trusted = models.BooleanField(default=False) trust_giver = models.ForeignKey("User", on_delete=models.SET_NULL, null=True) trust_taker = models.OneToOneField("User", on_delete=models.CASCADE, related_name="trust_bridge")