from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): """Project user with optional e621 API credentials and an app role.""" ROLE_USER = "user" ROLE_UPLOADER = "uploader" ROLE_STAFF = "staff" ROLE_CHOICES = [ (ROLE_USER, "User"), (ROLE_UPLOADER, "Uploader"), (ROLE_STAFF, "Staff"), ] role = models.CharField(max_length=20, choices=ROLE_CHOICES, default=ROLE_USER) avatar = models.ForeignKey( "library.MediaItem", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) e621_username = models.CharField(max_length=100, blank=True, default="") # Stored encrypted (see apps/accounts/crypto.py): never the plaintext key. e621_api_key = models.CharField(max_length=400, blank=True, default="") e621_base_url = models.CharField(max_length=200, default="https://e621.net") # Per-user browse preferences (landing page, default filters, grid size). preferences = models.JSONField(default=dict, blank=True) @property def e621_api_key_plain(self): """The decrypted e621 key ("" when it cannot be decrypted).""" from .crypto import decrypt_secret return decrypt_secret(self.e621_api_key) @property def e621_configured(self): return bool(self.e621_username and self.e621_api_key_plain) @property def can_upload(self): return self.is_superuser or self.role in {self.ROLE_UPLOADER, self.ROLE_STAFF} @property def is_app_staff(self): """Staff in this app: superusers, Django staff, or the staff role.""" return bool( self.is_superuser or self.is_staff or self.role == self.ROLE_STAFF )