import uuid from django.contrib.auth.models import AbstractUser from django.db import models from django.conf import settings class User(AbstractUser): email = models.EmailField(unique=True) display_name = models.CharField(max_length=150, blank=True, default='') skills = models.ManyToManyField('events.Skill', blank=True, related_name='users') is_admin_user = models.BooleanField(default=False) is_approved = models.BooleanField(default=False, help_text="Per Admin oder E-Mail-Bestätigung freigeschaltet") is_email_verified = models.BooleanField(default=False, help_text="E-Mail Bestätigungslink angeklickt") def get_display_name(self): return self.display_name or self.username or self.email def __str__(self): status_str = " (Ausstehend)" if not (self.is_approved or self.is_email_verified) else "" return f"{self.get_display_name()} ({self.email}){status_str}" class RegistrationDomainRule(models.Model): domain = models.CharField(max_length=150, unique=True, help_text="z. B. verein.de oder @beispiel.org") is_active = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True) def clean_domain(self): domain = self.domain.strip().lower() if not domain.startswith('@'): domain = '@' + domain return domain def save(self, *args, **kwargs): self.domain = self.clean_domain() super().save(*args, **kwargs) def __str__(self): return f"{self.domain} ({'Aktiv' if self.is_active else 'Inaktiv'})" class RegistrationRestrictionSetting(models.Model): is_restriction_enabled = models.BooleanField(default=False) require_admin_approval = models.BooleanField(default=False, help_text="Neue Registrierungen müssen von einem Admin freigeschaltet werden") require_email_verification = models.BooleanField(default=True, help_text="E-Mail Bestätigungslink für neue Konten erforderlich") @classmethod def get_solo(cls): obj, _ = cls.objects.get_or_create(pk=1) return obj def __str__(self): return f"Domain-Einschränkung: {self.is_restriction_enabled}, Admin-Freischaltung: {self.require_admin_approval}, E-Mail-Pflicht: {self.require_email_verification}" class SMTPSetting(models.Model): is_active = models.BooleanField(default=False, help_text="SMTP-Versand aktivieren") host = models.CharField(max_length=255, default="smtp.example.com") port = models.IntegerField(default=587) username = models.CharField(max_length=255, blank=True, default="") password = models.CharField(max_length=255, blank=True, default="") use_tls = models.BooleanField(default=True) use_ssl = models.BooleanField(default=False) from_email = models.EmailField(default="noreply@schichtplaner.local") @classmethod def get_solo(cls): obj, _ = cls.objects.get_or_create(pk=1) return obj def __str__(self): return f"SMTP {self.host}:{self.port} ({'Aktiv' if self.is_active else 'Inaktiv'})" class EmailVerificationToken(models.Model): token = models.UUIDField(default=uuid.uuid4, unique=True, editable=False) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='verification_tokens') is_used = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Verification Token for {self.user.username} ({self.token})" class GuestClaimToken(models.Model): token = models.UUIDField(default=uuid.uuid4, unique=True, editable=False) signup = models.ForeignKey('events.ShiftSignup', on_delete=models.CASCADE, related_name='claim_tokens') guest_name = models.CharField(max_length=150) created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='created_claim_tokens') is_claimed = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Claim Token for {self.guest_name} ({self.token})" class UserActivity(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='activities') guest_name = models.CharField(max_length=150, null=True, blank=True) session_key = models.CharField(max_length=255, db_index=True) ip_address = models.CharField(max_length=50, blank=True, default='') user_agent = models.CharField(max_length=255, blank=True, default='') last_path = models.CharField(max_length=255, blank=True, default='') last_seen = models.DateTimeField(auto_now=True) class Meta: ordering = ['-last_seen'] verbose_name = 'Benutzer-Aktivität / Sitzung' verbose_name_plural = 'Benutzer-Aktivitäten / Sitzungen' def __str__(self): name = self.user.get_display_name() if self.user else (self.guest_name or "Gast") return f"{name} ({self.ip_address}) - {self.last_seen}"