1
|
|
|
""" |
2
|
|
|
byceps.blueprints.common.user.creation.forms |
3
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4
|
|
|
|
5
|
|
|
:Copyright: 2006-2020 Jochen Kupperschmidt |
6
|
|
|
:License: Modified BSD, see LICENSE for details. |
7
|
|
|
""" |
8
|
|
|
|
9
|
1 |
|
import re |
10
|
1 |
|
from typing import Set |
11
|
1 |
|
from uuid import UUID |
12
|
|
|
|
13
|
1 |
|
from wtforms import BooleanField, HiddenField, PasswordField, StringField |
14
|
1 |
|
from wtforms.validators import InputRequired, Length, ValidationError |
15
|
|
|
|
16
|
1 |
|
from .....services.consent.transfer.models import Subject, SubjectID |
17
|
1 |
|
from .....services.user import screen_name_validator |
18
|
1 |
|
from .....services.user import service as user_service |
19
|
1 |
|
from .....util.l10n import LocalizedForm |
20
|
|
|
|
21
|
|
|
|
22
|
1 |
|
EMAIL_ADDRESS_PATTERN = re.compile(r'^.+?@.+?\..+?$') |
23
|
|
|
|
24
|
|
|
|
25
|
1 |
|
class ScreenNameValidator: |
26
|
|
|
"""Make sure screen name contains only permitted characters. |
27
|
|
|
|
28
|
|
|
However, do *not* check the length; use WTForms' `Length` for that. |
29
|
|
|
""" |
30
|
|
|
|
31
|
1 |
|
def __call__(self, form, field): |
32
|
1 |
|
if not screen_name_validator.contains_only_valid_chars(field.data): |
33
|
|
|
special_chars_spaced = ' '.join(screen_name_validator.SPECIAL_CHARS) |
34
|
|
|
raise ValidationError( |
35
|
|
|
'Enthält ungültige Zeichen. Erlaubt sind Buchstaben, ' |
36
|
|
|
f' Ziffern und diese Sonderzeichen: {special_chars_spaced}' |
37
|
|
|
) |
38
|
|
|
|
39
|
|
|
|
40
|
1 |
|
def assemble_user_create_form( |
41
|
|
|
real_name_required: bool, |
42
|
|
|
terms_consent_required: bool, |
43
|
|
|
required_consent_subjects: Set[Subject], |
44
|
|
|
newsletter_offered: bool, |
45
|
|
|
): |
46
|
1 |
|
class UserCreateForm(LocalizedForm): |
47
|
1 |
|
screen_name = StringField('Benutzername', [ |
48
|
|
|
InputRequired(), |
49
|
|
|
Length(min=screen_name_validator.MIN_LENGTH, |
50
|
|
|
max=screen_name_validator.MAX_LENGTH), |
51
|
|
|
ScreenNameValidator(), |
52
|
|
|
]) |
53
|
1 |
|
first_names = StringField('Vorname(n)', [InputRequired(), Length(min=2, max=40)]) |
54
|
1 |
|
last_name = StringField('Nachname', [InputRequired(), Length(min=2, max=80)]) |
55
|
1 |
|
email_address = StringField('E-Mail-Adresse', [InputRequired(), Length(min=6, max=120)]) |
56
|
1 |
|
password = PasswordField('Passwort', [InputRequired(), Length(min=8)]) |
57
|
1 |
|
is_bot = BooleanField('Bot') |
58
|
|
|
|
59
|
1 |
|
@staticmethod |
60
|
|
|
def validate_screen_name(form, field): |
61
|
1 |
|
if user_service.is_screen_name_already_assigned(field.data): |
62
|
|
|
raise ValueError('Dieser Benutzername kann nicht verwendet werden.') |
63
|
|
|
|
64
|
1 |
|
@staticmethod |
65
|
|
|
def validate_email_address(form, field): |
66
|
1 |
|
if EMAIL_ADDRESS_PATTERN.search(field.data) is None: |
67
|
|
|
raise ValueError('Die E-Mail-Adresse ist ungültig.') |
68
|
|
|
|
69
|
1 |
|
if user_service.is_email_address_already_assigned(field.data): |
70
|
|
|
raise ValueError( |
71
|
|
|
'Diese E-Mail-Adresse kann nicht verwendet werden.' |
72
|
|
|
) |
73
|
|
|
|
74
|
1 |
|
@staticmethod |
75
|
|
|
def validate_terms_version_id(form, field): |
76
|
1 |
|
try: |
77
|
1 |
|
UUID(field.data) |
78
|
|
|
except ValueError: |
79
|
|
|
raise ValueError('Ungültige AGB-Version.') |
80
|
|
|
|
81
|
1 |
|
@staticmethod |
82
|
|
|
def validate_is_bot(form, field): |
83
|
1 |
|
if field.data: |
84
|
|
|
raise ValueError('Bots sind nicht erlaubt.') |
85
|
|
|
|
86
|
1 |
|
def get_field_for_consent_subject_id(self, subject_id: SubjectID): |
87
|
|
|
name = _generate_consent_subject_field_name(subject_id) |
88
|
|
|
return getattr(self, name) |
89
|
|
|
|
90
|
1 |
|
if not real_name_required: |
91
|
|
|
del UserCreateForm.first_names |
92
|
|
|
del UserCreateForm.last_name |
93
|
|
|
|
94
|
1 |
|
if terms_consent_required: |
95
|
1 |
|
terms_version_id = HiddenField('AGB-Version', [InputRequired()]) |
96
|
1 |
|
consent_to_terms = BooleanField('AGB', [InputRequired()]) |
97
|
1 |
|
setattr(UserCreateForm, 'terms_version_id', terms_version_id) |
98
|
1 |
|
setattr(UserCreateForm, 'consent_to_terms', consent_to_terms) |
99
|
|
|
|
100
|
1 |
|
for subject in required_consent_subjects: |
101
|
1 |
|
field_name = _generate_consent_subject_field_name(subject.id) |
102
|
1 |
|
field = BooleanField('', [InputRequired()]) |
103
|
1 |
|
setattr(UserCreateForm, field_name, field) |
104
|
|
|
|
105
|
1 |
|
if newsletter_offered: |
106
|
1 |
|
subscribe_to_newsletter = BooleanField('Newsletter') |
107
|
1 |
|
setattr(UserCreateForm, 'subscribe_to_newsletter', subscribe_to_newsletter) |
108
|
|
|
|
109
|
1 |
|
return UserCreateForm |
110
|
|
|
|
111
|
|
|
|
112
|
1 |
|
def _generate_consent_subject_field_name(subject_id: SubjectID) -> str: |
113
|
|
|
return f'consent_to_subject_{subject_id}' |
114
|
|
|
|