import uuid import structlog from django.contrib.auth.models import AbstractUser from django.db import models from django.db.models import JSONField from django.urls import reverse logger = structlog.get_logger(__name__) class Organisation(models.Model): organisation_id = models.IntegerField(primary_key=True) name_de = models.CharField(max_length=255) name_fr = models.CharField(max_length=255) name_it = models.CharField(max_length=255) def __str__(self): return f"{self.name_de} ({self.organisation_id})" class Meta: verbose_name = "Organisation" verbose_name_plural = "Organisations" ordering = ["organisation_id"] class Country(models.Model): country_id = models.IntegerField(primary_key=True) name_de = models.CharField(max_length=255) name_fr = models.CharField(max_length=255) name_it = models.CharField(max_length=255) order_id = models.FloatField(default=20) def __str__(self): return f"{self.name_de} ({self.country_id})" class Meta: verbose_name = "Country" verbose_name_plural = "Countries" ordering = ["order_id", "country_id"] class User(AbstractUser): """ Default custom user model for VBV Lernwelt. If adding fields that need to be filled at user signup, """ LANGUAGE_CHOICES = ( ("de", "Deutsch"), ("fr", "Français"), ("it", "Italiano"), ) INVOICE_ADDRESS_PRIVATE = "prv" INVOICE_ADDRESS_ORGANISATION = "org" INVOICE_ADDRESS_CHOICES = ( (INVOICE_ADDRESS_PRIVATE, "Private"), (INVOICE_ADDRESS_ORGANISATION, "Organisation"), ) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) avatar = models.ForeignKey( "media_files.UserImage", null=True, blank=True, on_delete=models.SET_NULL, help_text="Avatar image for the user", ) email = models.EmailField("email address", unique=True) sso_id = models.UUIDField( "SSO subscriber ID", unique=True, null=True, blank=True, default=None ) additional_json_data = JSONField(default=dict, blank=True) language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES, default="de") organisation = models.ForeignKey( Organisation, on_delete=models.SET_NULL, null=True, blank=True ) invoice_address = models.CharField( max_length=3, choices=INVOICE_ADDRESS_CHOICES, default="prv" ) street = models.CharField(max_length=255, blank=True) street_number = models.CharField(max_length=255, blank=True) postal_code = models.CharField(max_length=255, blank=True) city = models.CharField(max_length=255, blank=True) country = models.ForeignKey( Country, related_name="user_country", on_delete=models.SET_NULL, null=True, blank=True, ) organisation_detail_name = models.CharField(max_length=255, blank=True) organisation_street = models.CharField(max_length=255, blank=True) organisation_street_number = models.CharField(max_length=255, blank=True) organisation_postal_code = models.CharField(max_length=255, blank=True) organisation_city = models.CharField(max_length=255, blank=True) organisation_country = models.ForeignKey( Country, related_name="organisation_country", on_delete=models.SET_NULL, null=True, blank=True, ) def create_avatar_url(self, size=400): try: if self.avatar: filter_spec = f"fill-{size}x{size}" self.avatar.get_rendition(filter_spec) url = reverse("user_image", kwargs={"image_id": self.avatar.id}) return f"{url}?filter={filter_spec}" except Exception: logger.warn("could not create avatar url", label="security", exc_info=True) return "/static/avatars/myvbv-default-avatar.png" @property def avatar_url(self): return self.create_avatar_url() @property def avatar_url_small(self): return self.create_avatar_url(size=96) class SecurityRequestResponseLog(models.Model): label = models.CharField(max_length=255, blank=True, default="") request_method = models.CharField(max_length=255, blank=True, default="") request_full_path = models.CharField(max_length=255, blank=True, default="") request_username = models.CharField(max_length=255, blank=True, default="") request_client_ip = models.CharField(max_length=255, blank=True, default="") response_status_code = models.CharField(max_length=255, blank=True, default="") additional_json_data = JSONField(default=dict, blank=True) class JobLog(models.Model): started = models.DateTimeField(auto_now_add=True) ended = models.DateTimeField(blank=True, null=True) job_name = models.CharField(max_length=255) success = models.BooleanField(default=False) error_message = models.TextField(blank=True, default="") stack_trace = models.TextField(blank=True, default="") json_data = models.JSONField(default=dict) def __str__(self): return "{job_name} {started:%H:%M %d.%m.%Y}".format(**self.__dict__)