# -*- coding: utf-8 -*- import re from flask import url_for from flask_wtf import FlaskForm as Form from flask_login import current_user from wtforms import StringField, PasswordField, ValidationError, \ BooleanField, validators from wtforms.form import FormMeta from markupsafe import Markup from .utils import NotRegexp from accounts.app import accounts_app USERNAME_RE = re.compile(r'^[a-zA-Z][a-zA-Z0-9-]{1,15}$') USERNAME_EXCLUDE_RE = re.compile(r'^(admin|root)') class RegisterForm(Form): username = StringField('Benutzername', [ validators.Regexp(USERNAME_RE, message='Benutzername darf nur aus a-z, ' 'Zahlen und - bestehen (2-16 Zeichen, am Anfang nur a-z).'), NotRegexp(USERNAME_EXCLUDE_RE, message='Dieser Benutzername ist nicht erlaubt.'), ]) mail = StringField('E-Mail-Adresse', [validators.Email(), validators.Length(min=6, max=50)]) question = StringField('Hauptstadt von Deutschland?', [validators.AnyOf( ('Berlin', 'berlin'), message='Bitte beantworte die Frage.')]) def validate_username(self, field): try: accounts_app.user_backend.get_by_uid(field.data) except accounts_app.user_backend.NoSuchUserError: if accounts_app.username_blacklist: if field.data.lower() in accounts_app.username_blacklist: raise ValidationError(Markup( 'Dieser Benutzername ist momentan nicht erlaubt. ' 'Weitere Informationen' % url_for('default.about'))) else: raise ValidationError('Dieser Benutzername ist schon vergeben.') def validate_mail(self, field): try: accounts_app.user_backend.get_by_mail(field.data) except accounts_app.user_backend.NoSuchUserError: pass else: raise ValidationError(Markup( 'Ein Benutzername mit dieser Adresse existiert bereits. ' 'Falls du deinen Benutzernamen vergessen hast, kannst du ' 'die Passwort-vergessen-Funktion benutzen.' % url_for('default.lost_password'))) class AdminCreateAccountForm(RegisterForm): def validate_username(self, field): try: accounts_app.user_backend.get_by_uid(field.data) except accounts_app.user_backend.NoSuchUserError: return else: raise ValidationError('Dieser Benutzername ist schon vergeben') question = None class RegisterCompleteForm(Form): password = PasswordField('Passwort', [validators.DataRequired(), validators.EqualTo('password_confirm', message='Passwörter stimmen nicht überein')]) password_confirm = PasswordField('Passwort bestätigen') # n.b. this form is also used in lost_password_complete class LostPasswordForm(Form): username_or_mail = StringField('Benutzername oder E-Mail') user = None def validate_username_or_mail(self, field): if '@' not in field.data: try: self.user = accounts_app.user_backend.get_by_uid(field.data) except accounts_app.user_backend.NoSuchUserError: raise ValidationError('Es gibt keinen Benutzer mit diesem Namen.') else: try: self.user = accounts_app.user_backend.get_by_mail(field.data) except accounts_app.user_backend.NoSuchUserError: raise ValidationError('Es gibt keinen Benutzer mit dieser Adresse.') class SettingsMeta(FormMeta): def __call__(cls, *args, **kwargs): for service in accounts_app.all_services: setattr(cls, 'password_%s' % service.id, PasswordField( 'Passwort für %s' % service.name, [ validators.Optional(), validators.EqualTo( 'password_confirm_%s' % service.id, message='Passwörter stimmen nicht überein'), ])) setattr(cls, 'password_confirm_%s' % service.id, PasswordField( 'Passwort für %s (Bestätigung)' % service.name)) setattr(cls, 'delete_%s' % service.id, BooleanField( 'Passwort für %s löschen' % service.name)) return super(SettingsMeta, cls).__call__(*args, **kwargs) class SettingsForm(Form, metaclass=SettingsMeta): old_password = PasswordField('Altes Passwort') password = PasswordField('Neues Passwort', [validators.Optional(), validators.EqualTo('password_confirm', message='Passwörter stimmen nicht überein')]) password_confirm = PasswordField('Passwort bestätigen') mail = StringField('E-Mail-Adresse', [validators.Optional(), validators.Email(), validators.Length(min=6, max=50)]) def validate_old_password(self, field): if self.password.data: if not field.data: raise ValidationError('Gib bitte dein altes Passwort ein, um ein neues zu setzen.') if field.data != current_user.password: raise ValidationError('Altes Passwort ist falsch.') def validate_mail(self, field): results = accounts_app.user_backend.find_by_mail(field.data) for user in results: if user.uid != current_user.uid: raise ValidationError('Diese E-Mail-Adresse wird schon von einem anderen Account benutzt!') def get_servicepassword(self, service_id: str): return getattr(self, 'password_%s' % service_id) def get_servicepasswordconfirm(self, service_id: str): return getattr(self, 'password_confirm_%s' % service_id) def get_servicedelete(self, service_id: str): return getattr(self, 'delete_%s' % service_id) class AdminDisableAccountForm(Form): username = StringField('Benutzername') user = None def validate_username(self, field): try: self.user = accounts_app.user_backend.get_by_uid(field.data) except accounts_app.user_backend.NoSuchUserError: raise ValidationError('Dieser Benutzername existiert nicht')