• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

liqd / diid_adplus / 9711798725

28 Jun 2024 11:06AM UTC coverage: 88.796% (-0.02%) from 88.817%
9711798725

Pull #90

github

web-flow
Merge ee9f1936d into 07652154a
Pull Request #90: rebase aplus 2406.4 again

18 of 27 new or added lines in 2 files covered. (66.67%)

38 existing lines in 1 file now uncovered.

6071 of 6837 relevant lines covered (88.8%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

53.73
/apps/users/forms.py
1
import logging
1✔
2

3
import xmltodict
1✔
4
from allauth.account.forms import LoginForm
1✔
5
from allauth.account.forms import SignupForm
1✔
6
from allauth.socialaccount.forms import SignupForm as SocialSignupForm
1✔
7
from django import forms
1✔
8
from django.conf import settings
1✔
9
from django.contrib.auth import forms as auth_forms
1✔
10
from django.utils.translation import get_language
1✔
11
from django.utils.translation import gettext_lazy as _
1✔
12
from django.utils.translation import pgettext_lazy
1✔
13
from zeep import Client
1✔
14

15
from apps.captcha.fields import CaptcheckCaptchaField
1✔
16
from apps.cms.settings import helpers
1✔
17
from apps.organisations.models import Member
1✔
18
from apps.organisations.models import Organisation
1✔
19
from apps.users.models import User
1✔
20

21
logger = logging.getLogger(__name__)
1✔
22

23
CAPTCHA_HELP = _(
1✔
24
    "Solve the math problem and click on the correct result.<br>"
25
    "If you are having difficulty please contact us  by {}email{}."
26
)
27

28

29
class DefaultLoginForm(LoginForm):
1✔
30
    def __init__(self, *args, **kwargs):
1✔
31
        super().__init__(*args, **kwargs)
1✔
32
        self.fields["login"].label = _("Username/e-mail")
1✔
33
        del self.fields["login"].widget.attrs["placeholder"]
1✔
34
        del self.fields["password"].widget.attrs["placeholder"]
1✔
35
        self.fields["password"].help_text = ""
1✔
36
        self.fields["login"].widget.attrs["autocomplete"] = "username"
1✔
37
        self.fields["password"].widget.attrs["autocomplete"] = "current-password"
1✔
38

39

40
class DefaultSignupForm(SignupForm):
1✔
41
    terms_of_use = forms.BooleanField(
1✔
42
        label=_('Terms of use')
43
    )
44
    data_protection = forms.BooleanField(
1✔
45
        label=_('Data protection')
46
    )
47
    get_notifications = forms.BooleanField(
1✔
48
        label=pgettext_lazy(
49
            'diid',
50
            'Notifications: Yes, I would like to be notified by e-mail about '
51
            'the beginning and end of participation opportunities and about '
52
            'comments on my contributions by other users. This applies to all '
53
            'projects I follow.'
54
        ),
55
        required=False
56
    )
57
    get_newsletters = forms.BooleanField(
1✔
58
        label=pgettext_lazy(
59
            'diid',
60
            'Newsletter: Yes, I would like to receive e-mail newsletters '
61
            'about the projects I follow.'
62
        ),
63
        required=False
64
    )
65
    captcha = CaptcheckCaptchaField(label=_("I am not a robot"))
1✔
66

67
    def __init__(self, *args, **kwargs):
1✔
68
        super().__init__(*args, **kwargs)
1✔
69
        self.fields["username"].help_text = _(
1✔
70
            "Your username will appear publicly next to your posts."
71
        )
72
        self.fields["email"].widget.attrs["autofocus"] = True
1✔
73
        del self.fields["username"].widget.attrs["placeholder"]
1✔
74
        del self.fields["email"].widget.attrs["placeholder"]
1✔
75
        del self.fields["password1"].widget.attrs["placeholder"]
1✔
76
        del self.fields["password2"].widget.attrs["placeholder"]
1✔
77
        self.fields["email"].widget.attrs["autocomplete"] = "username"
1✔
78
        self.fields["password1"].widget.attrs["autocomplete"] = "new-password"
1✔
79
        self.fields["password2"].widget.attrs["autocomplete"] = "new-password"
1✔
80
        if not (hasattr(settings, "CAPTCHA_URL") and settings.CAPTCHA_URL):
1✔
81
            del self.fields["captcha"]
1✔
82
        else:
83
            self.fields["captcha"].help_text = helpers.add_email_link_to_helptext(
1✔
84
                self.fields["captcha"].help_text, CAPTCHA_HELP
85
            )
86

87
    def save(self, request):
1✔
88
        user = super().save(request)
1✔
89
        if user:
1✔
90
            user.get_newsletters = self.cleaned_data["get_newsletters"]
1✔
91
            user.language = get_language()
1✔
92
            user.save()
1✔
93
            return user
1✔
94

95

96
class IgbceSignupForm(DefaultSignupForm):
1✔
97
    member_number = forms.IntegerField(
1✔
98
        label=_("Membership number of IG BCE"),
99
        help_text=_(
100
            "The membership number consists of a seven-digit number "
101
            "and can be found on the membership card."
102
        ),
103
        max_value=99999999999999999999,
104
        min_value=0,
105
    )
106
    birth_date = forms.DateField(
1✔
107
        label=_("Date of birth"),
108
        help_text=_(
109
            "Please also enter your date of birth in the format "
110
            "MM/DD/YYYY for authentication. Only members of the "
111
            "IG BCE can participate."
112
        ),
113
    )
114
    terms_of_use_extra = forms.BooleanField(
1✔
115
        label=_(
116
            "I confirm that I have read and accepted the "
117
            '<a href="/info/ig-bce-datenschutz/" '
118
            'target="_blank">data protection policy</a> of IG '
119
            "BCE."
120
        )
121
    )
122

123
    def validateMemberNumberAndDate(self, member_number, birth_date):
1✔
UNCOV
124
        if not hasattr(settings, "IGBCE_NAV_URL") or not hasattr(
×
125
            settings, "IGBCE_NAV_SECURITYID"
126
        ):
UNCOV
127
            raise forms.ValidationError(
×
128
                _("Something is wrong with the setup - please try again later")
129
            )
130

UNCOV
131
        if Member.objects.filter(member_number=member_number).exists():
×
UNCOV
132
            raise forms.ValidationError(
×
133
                _(
134
                    "There is already a participant with this membership "
135
                    "number. Please check your entry. If this is your "
136
                    "membership number, please send an email to "
137
                    '"zukunftsgewerkschaft@igbce.de".'
138
                )
139
            )
140

UNCOV
141
        result = False
×
UNCOV
142
        try:
×
143
            client = Client("{}".format(settings.IGBCE_NAV_URL))
×
UNCOV
144
            parameters = "{};{}".format(member_number, birth_date.strftime("%d.%m.%Y"))
×
UNCOV
145
            connection_parameters = (
×
146
                "ObjectID:0;SecurityID:{};SetSize:0;UnitopProxyVersion:2.0".format(
147
                    settings.IGBCE_NAV_SECURITYID
148
                )
149
            )
150

UNCOV
151
            response = client.service.SendRequest(
×
152
                functionName="CALCONNECT_MemberNoBirthDate",
153
                functionParameters=parameters,
154
                filters="",
155
                connectionParameters=connection_parameters,
156
            )
157

158
            result_str = xmltodict.parse(response)["Response"]["ResponseData"][
×
159
                "Object"
160
            ]["CalConnectorResult"]
161

UNCOV
162
            if result_str == "true":
×
UNCOV
163
                result = True
×
164

UNCOV
165
        except BaseException:
×
UNCOV
166
            logger.exception("IGBCE API error")
×
167
            raise forms.ValidationError(
×
168
                _("Something is wrong with the setup - please try again later")
169
            )
170

UNCOV
171
        if not result:
×
UNCOV
172
            raise forms.ValidationError(
×
173
                _(
174
                    "Unfortunately, the member number and / or date of birth "
175
                    "could not be linked to an active member account. Please "
176
                    "check your input and try again. If you still have "
177
                    'problems, please contact "zukunftsgewerkschaft@igbce.de".'
178
                )
179
            )
180

181
    def clean(self):
1✔
182
        super().clean()
×
183

UNCOV
184
        if any(self.errors):
×
UNCOV
185
            return self.errors
×
186

187
        member_number = self.cleaned_data.get("member_number")
×
188
        birth_date = self.cleaned_data.get("birth_date")
×
189

UNCOV
190
        self.validateMemberNumberAndDate(member_number, birth_date)
×
191

192
    def save(self, request):
1✔
UNCOV
193
        user = super().save(request)
×
UNCOV
194
        if hasattr(settings, "SITE_ORGANISATION_SLUG"):
×
UNCOV
195
            organisation = Organisation.objects.get(
×
196
                slug=settings.SITE_ORGANISATION_SLUG
197
            )
198
            additional_info = {"birth_date": self.cleaned_data["birth_date"]}
×
UNCOV
199
            member = Member(
×
200
                member=user,
201
                member_number=self.cleaned_data["member_number"],
202
                organisation=organisation,
203
                additional_info=additional_info,
204
            )
UNCOV
205
            member.save()
×
206
        return user
×
207

208

209
class SocialTermsSignupForm(SocialSignupForm):
1✔
210
    terms_of_use = forms.BooleanField(label=_("Terms of use"))
1✔
211
    get_newsletters = forms.BooleanField(
1✔
212
        label=_("I would like to receive further information"),
213
        help_text=_(
214
            "Projects you are following can send you "
215
            "additional information via email."
216
        ),
217
        required=False,
218
    )
219
    email = forms.EmailField(widget=forms.HiddenInput())
1✔
220

221
    def __init__(self, *args, **kwargs):
1✔
222
        super().__init__(*args, **kwargs)
×
UNCOV
223
        self.prevent_enumeration = False
×
UNCOV
224
        self.fields["username"].help_text = _(
×
225
            "Your username will appear publicly next to your posts."
226
        )
UNCOV
227
        del self.fields["username"].widget.attrs["placeholder"]
×
228

229
    def save(self, request):
1✔
UNCOV
230
        user = super().save(request)
×
UNCOV
231
        user.get_newsletters = self.cleaned_data["get_newsletters"]
×
UNCOV
232
        user.language = get_language()
×
UNCOV
233
        user.save()
×
UNCOV
234
        return user
×
235

236

237
class ChangeUserAdminForm(auth_forms.UserChangeForm):
1✔
238
    def clean_username(self):
1✔
239
        username = self.cleaned_data["username"]
×
240
        try:
×
UNCOV
241
            user = User.objects.get(username__iexact=username)
×
UNCOV
242
            if user != self.instance:
×
243
                raise forms.ValidationError(
×
244
                    User._meta.get_field("username").error_messages["unique"]
245
                )
246
        except User.DoesNotExist:
×
247
            pass
×
248

249
        try:
×
250
            user = User.objects.get(email__iexact=username)
×
UNCOV
251
            if user != self.instance:
×
UNCOV
252
                raise forms.ValidationError(
×
253
                    User._meta.get_field("username").error_messages["used_as_email"]
254
                )
255
        except User.DoesNotExist:
×
256
            pass
×
257

258
        return username
×
259

260

261
class AddUserAdminForm(auth_forms.UserCreationForm):
1✔
262
    def clean_username(self):
1✔
263
        username = self.cleaned_data["username"]
×
UNCOV
264
        user = User.objects.filter(username__iexact=username)
×
265
        if user.exists():
×
266
            raise forms.ValidationError(
×
267
                User._meta.get_field("username").error_messages["unique"]
268
            )
269
        else:
UNCOV
270
            user = User.objects.filter(email__iexact=username)
×
271
            if user.exists():
×
272
                raise forms.ValidationError(
×
273
                    User._meta.get_field("username").error_messages["used_as_email"]
274
                )
UNCOV
275
        return username
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc