diff --git a/apps/authentik/authentik-blueprints.yaml b/apps/authentik/authentik-blueprints.yaml index 3ba2b1a..8d31edf 100644 --- a/apps/authentik/authentik-blueprints.yaml +++ b/apps/authentik/authentik-blueprints.yaml @@ -28,12 +28,45 @@ data: # from manual UI setup, likely a "select all" slip in the policy picker. # These crash on an anonymous enrollment context ('AnonymousUser' object # has no attribute 'group_attributes', etc). A prompt stage needs none here. + # Eindeutigkeit case-insensitiv pruefen (#0043). Authentiks eigene Pruefung + # ist case-sensitiv, "Boje" und "boje" gelten ihr also als verschieden -- + # in Matrix kollidieren sie. Seit ADR-0011 faengt MAS das mit + # on_conflict:fail ab, aber erst BEIM LOGIN: der Nutzer registriert sich + # erfolgreich und scheitert spaeter ohne Erklaerung. Diese Policy gibt die + # Rueckmeldung dort, wo der Fehler entsteht. + # + # ⚠️ Bewusst ohne Zugriff auf request.user: die Stage laeuft im ANONYMEN + # Enrollment-Kontext. Genau daran sind die frueher hier haengenden + # System-Policies gescheitert ('AnonymousUser' hat kein group_attributes). + # Gelesen wird ausschliesslich prompt_data. + - model: authentik_policies_expression.expressionpolicy + state: present + identifiers: + name: matrix-username-eindeutig-ci + id: username_unique_ci + attrs: + execution_logging: false + expression: | + from authentik.core.models import User + + gewuenscht = (request.context.get("prompt_data") or {}).get("username") or "" + gewuenscht = gewuenscht.strip() + if not gewuenscht: + return True # Pflichtfeld-Pruefung macht der Prompt selbst + + if User.objects.filter(username__iexact=gewuenscht).exists(): + ak_message("Dieser Benutzername ist bereits vergeben - auch in anderer " + "Gross-/Kleinschreibung. Bitte waehle einen anderen.") + return False + return True + - model: authentik_stages_prompt.promptstage state: present identifiers: name: matrix-invitation-prompt attrs: - validation_policies: [] + validation_policies: + - !KeyOf username_unique_ci # Correct stage chain, mirroring the working matrix-enrollment flow: # Invite -> Prompt (username/email/password) -> Write -> Password -> Login