| 117 | |
| 118 | |
| 119 | class FFAdminUser(LifecycleModel, AbstractUser): # type: ignore[django-manager-missing,misc] |
| 120 | organisations = models.ManyToManyField( |
| 121 | Organisation, related_name="users", blank=True, through=UserOrganisation |
| 122 | ) |
| 123 | email = models.EmailField(unique=True, null=False) |
| 124 | objects = UserManager() # type: ignore[assignment,misc] |
| 125 | username = models.CharField(unique=True, max_length=150, null=True, blank=True) # type: ignore[misc] |
| 126 | first_name = models.CharField("first name", max_length=150) |
| 127 | last_name = models.CharField("last name", max_length=150) |
| 128 | google_user_id = models.CharField(max_length=50, null=True, blank=True) |
| 129 | github_user_id = models.CharField(max_length=50, null=True, blank=True) |
| 130 | onboarding_data = models.TextField(blank=True, null=True) |
| 131 | # Default to True, since it is covered in our Terms of Service. |
| 132 | marketing_consent_given = models.BooleanField( |
| 133 | default=True, |
| 134 | help_text="Determines whether the user has agreed to receive marketing mails", |
| 135 | ) |
| 136 | |
| 137 | sign_up_type = models.CharField( |
| 138 | choices=SignUpType.choices, max_length=100, blank=True, null=True |
| 139 | ) |
| 140 | |
| 141 | uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) |
| 142 | |
| 143 | USERNAME_FIELD = "username" if settings.LDAP_ENABLED else "email" |
| 144 | REQUIRED_FIELDS = ["first_name", "last_name", "sign_up_type"] |
| 145 | |
| 146 | class Meta: |
| 147 | ordering = ["id"] |
| 148 | verbose_name = "Feature flag admin user" |
| 149 | |
| 150 | def __str__(self): # type: ignore[no-untyped-def] |
| 151 | return self.email |
| 152 | |
| 153 | @property |
| 154 | def superuser(self) -> bool: |
| 155 | return self.is_staff and self.is_superuser |
| 156 | |
| 157 | @superuser.setter |
| 158 | def superuser(self, value: bool) -> None: |
| 159 | self.is_staff = value |
| 160 | self.is_superuser = value |
| 161 | |
| 162 | @hook(AFTER_SAVE, condition=(WhenFieldHasChanged("email", has_changed=True))) # type: ignore[misc] |
| 163 | def send_warning_email(self) -> None: |
| 164 | from users.tasks import send_email_changed_notification_email |
| 165 | |
| 166 | send_email_changed_notification_email.delay( |
| 167 | args=( |
| 168 | self.first_name, |
| 169 | settings.DEFAULT_FROM_EMAIL, |
| 170 | self.initial_value("email"), |
| 171 | ) |
| 172 | ) |
| 173 | |
| 174 | def delete_orphan_organisations(self) -> None: |
| 175 | Organisation.objects.filter( |
| 176 | id__in=self.organisations.values_list("id", flat=True) |