codeforlife-portal 6.41.7__py2.py3-none-any.whl → 6.41.9__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codeforlife-portal might be problematic. Click here for more details.
- cfl_common/common/email_messages.py +1 -14
- cfl_common/common/mail.py +1 -0
- cfl_common/common/tests/utils/email.py +1 -4
- {codeforlife_portal-6.41.7.dist-info → codeforlife_portal-6.41.9.dist-info}/METADATA +2 -2
- {codeforlife_portal-6.41.7.dist-info → codeforlife_portal-6.41.9.dist-info}/RECORD +15 -15
- portal/__init__.py +1 -1
- portal/forms/registration.py +16 -21
- portal/templates/portal/privacy_notice.html +5 -0
- portal/tests/test_independent_student.py +11 -7
- portal/tests/test_ratelimit.py +9 -6
- portal/tests/test_teacher.py +19 -10
- portal/views/legal.py +1 -1
- {codeforlife_portal-6.41.7.dist-info → codeforlife_portal-6.41.9.dist-info}/LICENSE.md +0 -0
- {codeforlife_portal-6.41.7.dist-info → codeforlife_portal-6.41.9.dist-info}/WHEEL +0 -0
- {codeforlife_portal-6.41.7.dist-info → codeforlife_portal-6.41.9.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
from django.urls import reverse
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def resetEmailPasswordMessage(request, domain, uid, token, protocol):
|
|
5
|
-
password_reset_uri = reverse_lazy("password_reset_check_and_confirm", kwargs={"uidb64": uid, "token": token})
|
|
6
|
-
url = f"{protocol}://{domain}{password_reset_uri}"
|
|
7
|
-
return {
|
|
8
|
-
"subject": f"Password reset request",
|
|
9
|
-
"message": (
|
|
10
|
-
f"You are receiving this email because you requested "
|
|
11
|
-
f"a password reset for your Code For Life user account.\n\n"
|
|
12
|
-
f"Please go to the following page and choose a new password: {url}"
|
|
13
|
-
),
|
|
14
|
-
}
|
|
1
|
+
from django.urls import reverse
|
|
15
2
|
|
|
16
3
|
|
|
17
4
|
def userAlreadyRegisteredEmail(request, email, is_independent_student=False):
|
cfl_common/common/mail.py
CHANGED
|
@@ -7,6 +7,7 @@ from common import app_settings
|
|
|
7
7
|
campaign_ids = {
|
|
8
8
|
"email_change_notification": 1551600,
|
|
9
9
|
"email_change_verification": 1551594,
|
|
10
|
+
"reset_password": 1557153,
|
|
10
11
|
"verify_new_user": 1551577,
|
|
11
12
|
"verify_new_user_first_reminder": 1557170,
|
|
12
13
|
"verify_new_user_second_reminder": 1557173,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import re
|
|
2
1
|
from builtins import str
|
|
3
2
|
|
|
4
3
|
|
|
@@ -35,9 +34,7 @@ def _follow_duplicate_account_email_link(page, email):
|
|
|
35
34
|
page.browser.get(message[i:j])
|
|
36
35
|
|
|
37
36
|
|
|
38
|
-
def follow_reset_email_link(browser,
|
|
39
|
-
message = str(email.body)
|
|
40
|
-
link = re.search("http.+/", message).group(0)[:-1]
|
|
37
|
+
def follow_reset_email_link(browser, link):
|
|
41
38
|
browser.get(link)
|
|
42
39
|
|
|
43
40
|
from portal.tests.pageObjects.portal.password_reset_form_page import (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codeforlife-portal
|
|
3
|
-
Version: 6.41.
|
|
3
|
+
Version: 6.41.9
|
|
4
4
|
Classifier: Programming Language :: Python
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.8
|
|
6
6
|
Classifier: Framework :: Django
|
|
@@ -25,7 +25,7 @@ Requires-Dist: sqlparse ==0.4.4
|
|
|
25
25
|
Requires-Dist: libsass ==0.22.0
|
|
26
26
|
Requires-Dist: phonenumbers ==8.12.12
|
|
27
27
|
Requires-Dist: more-itertools ==8.7.0
|
|
28
|
-
Requires-Dist: cfl-common ==6.41.
|
|
28
|
+
Requires-Dist: cfl-common ==6.41.9
|
|
29
29
|
Requires-Dist: django-ratelimit ==3.0.1
|
|
30
30
|
Requires-Dist: django-preventconcurrentlogins ==0.8.2
|
|
31
31
|
Requires-Dist: django-csp ==3.7
|
|
@@ -5,8 +5,8 @@ cfl_common/common/app_settings.py,sha256=x2ROLY5Xl5LgqjxyTiChZvQorZYUXpFzEkaLsjh
|
|
|
5
5
|
cfl_common/common/apps.py,sha256=49UXZ3bSkFKvIEOL4zM7y1sAhccQJyRtsoOg5XVd_8Y,129
|
|
6
6
|
cfl_common/common/context_processors.py,sha256=X0iuX5qu9kMWa7q8osE9CJ2LgM7pPOYQFGdjm8X3rk0,236
|
|
7
7
|
cfl_common/common/csp_config.py,sha256=sZT6s9zMT5FFIqNODsURT0ifxbDgXpDlki8UxaBq2iE,2940
|
|
8
|
-
cfl_common/common/email_messages.py,sha256=
|
|
9
|
-
cfl_common/common/mail.py,sha256=
|
|
8
|
+
cfl_common/common/email_messages.py,sha256=DRiz6MCKUGdFsC-pN9EwFqzPhpzMWXaT9HPcji1BkvE,4437
|
|
9
|
+
cfl_common/common/mail.py,sha256=5iwvedYfaJUv7v8vVpV1kyBtnw04EJhHPy3FRGI9WHM,4223
|
|
10
10
|
cfl_common/common/models.py,sha256=vnvy8U-sHopyaxgJK9wTxelbKsCnYMjuEu3HIuAEkrs,14974
|
|
11
11
|
cfl_common/common/permissions.py,sha256=gC6RQGZI2QDBbglx-xr_V4Hl2C2nf1V2_uPmEuoEcJo,2416
|
|
12
12
|
cfl_common/common/utils.py,sha256=Nn2Npao9Uqad5Js_IdHwF-ow6wrPNpBLW4AO1LxoEBc,1727
|
|
@@ -72,7 +72,7 @@ cfl_common/common/tests/test_migration_remove_teacher_title.py,sha256=wwm6tayb75
|
|
|
72
72
|
cfl_common/common/tests/test_models.py,sha256=xMdzonW5CADMjas_zfg8V1YPQpUetleyn6TE95hbO9k,3723
|
|
73
73
|
cfl_common/common/tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
cfl_common/common/tests/utils/classes.py,sha256=ZA2pp9Pyx3rwi0VFwtuUA2Pys9xQJ-L_zE0u2tpwEH4,1094
|
|
75
|
-
cfl_common/common/tests/utils/email.py,sha256=
|
|
75
|
+
cfl_common/common/tests/utils/email.py,sha256=x3DjWCT997wwj33YuiA3mDqkNahr63zVmz_mX7XIomo,2094
|
|
76
76
|
cfl_common/common/tests/utils/organisation.py,sha256=vNgKFtU3VPcWRnZfh82yCS90PLAK1XTYJNIxGwfgUI4,966
|
|
77
77
|
cfl_common/common/tests/utils/student.py,sha256=XlgWT0TdbIY6w9uB4SqOoXmhxxCRnucEcPY9Q5Xva0U,4415
|
|
78
78
|
cfl_common/common/tests/utils/teacher.py,sha256=kY9LuP1mTEj_andYxF9k54xEHiJ36a6dokHxA9cB9f0,2500
|
|
@@ -100,7 +100,7 @@ example_project/portal_test_settings.py,sha256=fkbeU36YhWvNbR_hm28Rq4pV6ln-dGHK1
|
|
|
100
100
|
example_project/settings.py,sha256=GLelTfsnhAuf_rqjXUoIWoLtzKvr-9l8UQDQ23rxPQc,5580
|
|
101
101
|
example_project/urls.py,sha256=OVeRQ-TCpzHISBRuzqD0yd3ewF7H5U3c-f2p2alfUD0,430
|
|
102
102
|
example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
|
|
103
|
-
portal/__init__.py,sha256=
|
|
103
|
+
portal/__init__.py,sha256=nAOTZ1PFPrTXtaItbh3AKoAgKP-NWvT-PzlyaRCQ8gE,23
|
|
104
104
|
portal/admin.py,sha256=k5Hsiln43DlVPoufnrx5AXWu_RijX8xi_n7wwBuuCJo,5132
|
|
105
105
|
portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
|
|
106
106
|
portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
|
|
@@ -118,7 +118,7 @@ portal/forms/error_messages.py,sha256=8d3z_3e2L-5zwj5hFhnUByC5k2CEpIVVuJg2nYkCUQ
|
|
|
118
118
|
portal/forms/invite_teacher.py,sha256=jkDNcCfkts4_lXRzhcI3xBam21Zn2yX9wMpMVhDtW1w,880
|
|
119
119
|
portal/forms/organisation.py,sha256=QcQyd7AiqBmvt4y8uQSQylguUbKOKqo2pjqWIkpWjDg,7433
|
|
120
120
|
portal/forms/play.py,sha256=IO0gfKfTv7lXEN1K9w0XG8vY-55obBqLpiEBWaUluZ8,11351
|
|
121
|
-
portal/forms/registration.py,sha256=
|
|
121
|
+
portal/forms/registration.py,sha256=gWcY7rllhWO3c9as6QHUDWZx1Jme7DqtGHYaKcvxe-U,5990
|
|
122
122
|
portal/forms/teach.py,sha256=-3dMQxIQtYq2xg5DgtIJMpN7RajNhTvc56Clr5QjsHo,20440
|
|
123
123
|
portal/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
124
124
|
portal/helpers/captcha.py,sha256=Amwg3HZ9eIh1LGYVYWYruk1ccNj6P3nYP_evufOY8BY,254
|
|
@@ -446,7 +446,7 @@ portal/templates/portal/locked_out.html,sha256=JeiFHFyueFX03D54k82swjxvKY78cFG8V
|
|
|
446
446
|
portal/templates/portal/locked_out_school_student.html,sha256=bcpLtu4mkHR-zILLuArtHH2OfUSjHiqntcdbTMlx5Kg,684
|
|
447
447
|
portal/templates/portal/mouseflow.html,sha256=ji9SWR86nqC59xdmivfdPNG5OzFk8gJEUeOUUh52alk,361
|
|
448
448
|
portal/templates/portal/play.html,sha256=P5riFKSqaz_6aycgGC7-ql8u_ut6Igsa2SX9kMv8qM0,5162
|
|
449
|
-
portal/templates/portal/privacy_notice.html,sha256=
|
|
449
|
+
portal/templates/portal/privacy_notice.html,sha256=USklp2FWK4yEpa_-UGYrOutC4lORBMIxqcQihvCLTSA,56338
|
|
450
450
|
portal/templates/portal/register.html,sha256=9AFNejCCcG2VwNCJ8AU5r3Wk0u_ftK_NbVfxZb5weh0,12547
|
|
451
451
|
portal/templates/portal/reset_password.html,sha256=YzsREz5D2OwhicMLahVOVDXiNDxoHlPqU5iu96i36W0,1373
|
|
452
452
|
portal/templates/portal/reset_password_confirm.html,sha256=jPHSDatezRXzCG4zH_5BQPWAxLblidqro0hzvsH54ho,3499
|
|
@@ -538,16 +538,16 @@ portal/tests/test_class.py,sha256=V6Fkc6PqdisefKD3xs9PbfE2pKp-9e0gwQVkPUiu6bk,14
|
|
|
538
538
|
portal/tests/test_daily_activities.py,sha256=-siDCMGBD1ijjccHVk7eEmrk4bgTsvbh0B6hDoj2fo0,1803
|
|
539
539
|
portal/tests/test_emails.py,sha256=-rI3FlJO7n9qfZ8Vz_Fe3DmjOngr4r23PCpjIoRxNY0,9133
|
|
540
540
|
portal/tests/test_helper_methods.py,sha256=-SQCDZm2XUtyXGEp0CHIb_SSC9CPD-XOSnpnY8QclHk,890
|
|
541
|
-
portal/tests/test_independent_student.py,sha256=
|
|
541
|
+
portal/tests/test_independent_student.py,sha256=ysWpkYiwjPdB7gO3ow-5JuxqLi0IywRSxG1s3rKzTK0,26282
|
|
542
542
|
portal/tests/test_invite_teacher.py,sha256=oeOaoJV1IqJSYPlaPFjnhVXdB2mq8otCTLp_lfjuCfk,12224
|
|
543
543
|
portal/tests/test_middleware.py,sha256=b6jfNmiRZ2snqLKsyJUG-RivoX5fmrqLlQkG9MeVnqM,8034
|
|
544
544
|
portal/tests/test_newsletter_footer.py,sha256=MdVUX53mEoDTa4Krq-jg9LFNo-QyghqvTvhHeNXBGnE,838
|
|
545
545
|
portal/tests/test_organisation.py,sha256=fOtck-0MkPM2F0V4RFH-QUeWEk6yUIXDv_GI5cl8sdg,7649
|
|
546
546
|
portal/tests/test_partials.py,sha256=ydh1nef6BqvMfah2BSBS9QDiKY0xopY74k_W1YVobAE,3687
|
|
547
|
-
portal/tests/test_ratelimit.py,sha256
|
|
547
|
+
portal/tests/test_ratelimit.py,sha256=XWq1A9XgRrlcMHibGoJ0kc4gLc5U_u5UhKHjthxCfYA,19376
|
|
548
548
|
portal/tests/test_school_student.py,sha256=bFZwY4twaFHQLp0cltMq8cLNDZGgCHTZBCZHK0JcV8s,8604
|
|
549
549
|
portal/tests/test_security.py,sha256=FGrlRfnzi-Xx2_bn4fTZlYORKm7w_GhGkD3havvplwc,3239
|
|
550
|
-
portal/tests/test_teacher.py,sha256=
|
|
550
|
+
portal/tests/test_teacher.py,sha256=_VmQCWq07uCFbvq6Vd7GN00mE7vY7WNMeQTk6bHxFPI,36898
|
|
551
551
|
portal/tests/test_teacher_student.py,sha256=NWITbUw1kijqu3c8eRHLHJKaYQMOsOMvl7PAVx5QghI,21567
|
|
552
552
|
portal/tests/test_views.py,sha256=6y4ICpo5KPTWQed3J1Hg74ZGBKI2y3-HNHAowOsge80,38769
|
|
553
553
|
portal/tests/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -613,7 +613,7 @@ portal/views/api.py,sha256=lCwiclR98G-yTgK55u8IjkueIH8iremeiZSa3jAvO-M,6990
|
|
|
613
613
|
portal/views/dotmailer.py,sha256=_subSoy5f1j5sAcRrjE_xMejdarjHIY1d_jwSrf7_o0,2299
|
|
614
614
|
portal/views/email.py,sha256=dSgTp0kEZRTBRwPbtCrMoWhiOqZ1dPZT1YMvR6f1GQU,3899
|
|
615
615
|
portal/views/home.py,sha256=J_kb0Kv5Ubk9yQ4r0IAvhPV5o_iezcaqA4Z5bd0-Idc,9869
|
|
616
|
-
portal/views/legal.py,sha256=
|
|
616
|
+
portal/views/legal.py,sha256=nUunsTHnhMcXBcDlg1GmUal86k9Vhinne4A2FWfq78M,342
|
|
617
617
|
portal/views/organisation.py,sha256=sPDbiM7hdtpF8GKyh_4n4VPl2a-WnAgnF4q9aSvQCVI,3341
|
|
618
618
|
portal/views/play_landing_page.py,sha256=FFmjUFub3ZdlbMqkB8yX3jAImCzqrUqgb8AZcpKywZ4,308
|
|
619
619
|
portal/views/registration.py,sha256=oGHec_NvBTRd--4pAXtCevteAj6ivF8PKwbwul46Mmk,11011
|
|
@@ -636,8 +636,8 @@ portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
636
636
|
portal/views/two_factor/core.py,sha256=O_wcBeFqdPYSGNGv-pT_vbs5-Dj1Z-Jfkd6f9-E5yZI,760
|
|
637
637
|
portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
|
|
638
638
|
portal/views/two_factor/profile.py,sha256=tkl_ludo8arMtd5LKNmohM66vpC_YQiP-0nspTSJiJ4,383
|
|
639
|
-
codeforlife_portal-6.41.
|
|
640
|
-
codeforlife_portal-6.41.
|
|
641
|
-
codeforlife_portal-6.41.
|
|
642
|
-
codeforlife_portal-6.41.
|
|
643
|
-
codeforlife_portal-6.41.
|
|
639
|
+
codeforlife_portal-6.41.9.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
|
|
640
|
+
codeforlife_portal-6.41.9.dist-info/METADATA,sha256=KJR7skjhTgCC6qAImEMgWNl5VRqDo4I4hpSNERjawsY,1169
|
|
641
|
+
codeforlife_portal-6.41.9.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
642
|
+
codeforlife_portal-6.41.9.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
|
|
643
|
+
codeforlife_portal-6.41.9.dist-info/RECORD,,
|
portal/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "6.41.
|
|
1
|
+
__version__ = "6.41.9"
|
portal/forms/registration.py
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from captcha.fields import ReCaptchaField
|
|
2
2
|
from captcha.widgets import ReCaptchaV2Invisible
|
|
3
|
-
from common.
|
|
4
|
-
from common.helpers.emails import NOTIFICATION_EMAIL, send_email
|
|
3
|
+
from common.mail import campaign_ids, send_dotdigital_email
|
|
5
4
|
from common.models import Student, Teacher
|
|
6
5
|
from django import forms
|
|
7
6
|
from django.contrib.auth import forms as django_auth_forms
|
|
8
7
|
from django.contrib.auth import get_user_model
|
|
9
8
|
from django.contrib.auth.tokens import default_token_generator
|
|
10
9
|
from django.contrib.sites.shortcuts import get_current_site
|
|
10
|
+
from django.urls import reverse_lazy
|
|
11
11
|
from django.utils.encoding import force_bytes
|
|
12
12
|
from django.utils.http import urlsafe_base64_encode
|
|
13
|
+
|
|
13
14
|
from portal.helpers.password import PasswordStrength, form_clean_password
|
|
14
15
|
|
|
15
16
|
|
|
@@ -74,30 +75,24 @@ class PasswordResetForm(forms.Form):
|
|
|
74
75
|
continue
|
|
75
76
|
if not domain_override:
|
|
76
77
|
current_site = get_current_site(request)
|
|
77
|
-
site_name = current_site.name
|
|
78
78
|
domain = current_site.domain
|
|
79
79
|
else:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"protocol": self._compute_protocol(use_https),
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
email_subject_content = resetEmailPasswordMessage(
|
|
92
|
-
request, domain, context["uid"], context["token"], context["protocol"]
|
|
80
|
+
domain = domain_override
|
|
81
|
+
|
|
82
|
+
reset_password_uri = reverse_lazy(
|
|
83
|
+
"password_reset_check_and_confirm",
|
|
84
|
+
kwargs={
|
|
85
|
+
"uidb64": urlsafe_base64_encode(force_bytes(user.pk)),
|
|
86
|
+
"token": token_generator.make_token(user),
|
|
87
|
+
},
|
|
93
88
|
)
|
|
89
|
+
protocol = self._compute_protocol(use_https)
|
|
90
|
+
reset_password_url = f"{protocol}://{domain}{reset_password_uri}"
|
|
94
91
|
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
send_dotdigital_email(
|
|
93
|
+
campaign_ids["reset_password"],
|
|
97
94
|
[user.email],
|
|
98
|
-
|
|
99
|
-
email_subject_content["message"],
|
|
100
|
-
email_subject_content["subject"],
|
|
95
|
+
personalization_values={"RESET_PASSWORD_LINK": reset_password_url},
|
|
101
96
|
)
|
|
102
97
|
|
|
103
98
|
def _compute_protocol(self, use_https):
|
|
@@ -335,6 +335,11 @@
|
|
|
335
335
|
(desktop/tablet/phone), screen resolution, location (city/country), language, and similar metadata). Mouseflow
|
|
336
336
|
does not collect any information on pages where it is not installed, nor does it track or collect information
|
|
337
337
|
outside your web browser.</p>
|
|
338
|
+
<p><strong>YouTube</strong>. While embedded YouTube videos on our website do not use cookies, your browser's
|
|
339
|
+
Local Storage may be used by the video platform provider to enhance your viewing experience and collect
|
|
340
|
+
analytics data. This data enables the platform to track your interaction with the video content and may
|
|
341
|
+
gather information about your device and browsing behavior. The use of Local Storage by embedded video
|
|
342
|
+
providers is subject to their respective policies.</p>
|
|
338
343
|
|
|
339
344
|
<h6>6.4 Managing and disabling cookies</h6>
|
|
340
345
|
<p>We make available a cookie management platform on our portal (provided by
|
|
@@ -284,7 +284,8 @@ class TestIndependentStudentFrontend(BaseTest):
|
|
|
284
284
|
|
|
285
285
|
assert self.is_dashboard(page)
|
|
286
286
|
|
|
287
|
-
|
|
287
|
+
@patch("portal.forms.registration.send_dotdigital_email")
|
|
288
|
+
def test_reset_password(self, mock_send_dotdigital_email: Mock):
|
|
288
289
|
page = self.go_to_homepage()
|
|
289
290
|
|
|
290
291
|
page, name, username, _, _ = create_independent_student(page)
|
|
@@ -292,9 +293,13 @@ class TestIndependentStudentFrontend(BaseTest):
|
|
|
292
293
|
|
|
293
294
|
page.reset_email_submit(username)
|
|
294
295
|
|
|
295
|
-
|
|
296
|
+
mock_send_dotdigital_email.assert_called_with(campaign_ids["reset_password"], ANY, personalization_values=ANY)
|
|
296
297
|
|
|
297
|
-
|
|
298
|
+
reset_password_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"][
|
|
299
|
+
"RESET_PASSWORD_LINK"
|
|
300
|
+
]
|
|
301
|
+
|
|
302
|
+
page = email_utils.follow_reset_email_link(self.selenium, reset_password_url)
|
|
298
303
|
|
|
299
304
|
new_password = "AnotherPassword12"
|
|
300
305
|
|
|
@@ -312,14 +317,13 @@ class TestIndependentStudentFrontend(BaseTest):
|
|
|
312
317
|
page = page.go_to_account_page()
|
|
313
318
|
assert page.check_account_details({"name": name})
|
|
314
319
|
|
|
315
|
-
|
|
320
|
+
@patch("portal.forms.registration.send_dotdigital_email")
|
|
321
|
+
def test_reset_password_fail(self, mock_send_dotdigital_email: Mock):
|
|
316
322
|
page = self.get_to_forgotten_password_page()
|
|
317
323
|
fake_email = "fake_email@fakeemail.com"
|
|
318
324
|
page.reset_email_submit(fake_email)
|
|
319
325
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
assert len(mail.outbox) == 0
|
|
326
|
+
mock_send_dotdigital_email.assert_not_called()
|
|
323
327
|
|
|
324
328
|
def test_update_name_success(self):
|
|
325
329
|
homepage = self.go_to_homepage()
|
portal/tests/test_ratelimit.py
CHANGED
|
@@ -326,7 +326,8 @@ class TestRatelimit(TestCase):
|
|
|
326
326
|
|
|
327
327
|
assert get_ratelimit_count_for_user(email) == 1
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
@patch("portal.forms.registration.send_dotdigital_email")
|
|
330
|
+
def test_teacher_reset_password_unblocks_user(self, mock_send_dotdigital_email: Mock):
|
|
330
331
|
"""
|
|
331
332
|
Given a blocked teacher,
|
|
332
333
|
When they reset they password,
|
|
@@ -344,15 +345,17 @@ class TestRatelimit(TestCase):
|
|
|
344
345
|
# Ask for reset password link
|
|
345
346
|
self._reset_password_request(email)
|
|
346
347
|
|
|
347
|
-
|
|
348
|
+
mock_send_dotdigital_email.assert_called_once_with(
|
|
349
|
+
campaign_ids["reset_password"], ANY, personalization_values=ANY
|
|
350
|
+
)
|
|
348
351
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
+
reset_password_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"][
|
|
353
|
+
"RESET_PASSWORD_LINK"
|
|
354
|
+
]
|
|
352
355
|
|
|
353
356
|
new_password = "AnotherPassword12!"
|
|
354
357
|
|
|
355
|
-
self._reset_password(
|
|
358
|
+
self._reset_password(reset_password_url, new_password)
|
|
356
359
|
|
|
357
360
|
login_response = self._teacher_login(email, new_password)
|
|
358
361
|
|
portal/tests/test_teacher.py
CHANGED
|
@@ -628,7 +628,8 @@ class TestTeacherFrontend(BaseTest):
|
|
|
628
628
|
|
|
629
629
|
assert self.is_dashboard_page(page)
|
|
630
630
|
|
|
631
|
-
|
|
631
|
+
@patch("portal.forms.registration.send_dotdigital_email")
|
|
632
|
+
def test_reset_password(self, mock_send_dotdigital_email: Mock):
|
|
632
633
|
email, _ = signup_teacher_directly()
|
|
633
634
|
create_organisation_directly(email)
|
|
634
635
|
_, _, access_code = create_class_directly(email)
|
|
@@ -638,9 +639,13 @@ class TestTeacherFrontend(BaseTest):
|
|
|
638
639
|
|
|
639
640
|
page.reset_email_submit(email)
|
|
640
641
|
|
|
641
|
-
|
|
642
|
+
mock_send_dotdigital_email.assert_called_with(campaign_ids["reset_password"], ANY, personalization_values=ANY)
|
|
642
643
|
|
|
643
|
-
|
|
644
|
+
reset_password_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"][
|
|
645
|
+
"RESET_PASSWORD_LINK"
|
|
646
|
+
]
|
|
647
|
+
|
|
648
|
+
page = email_utils.follow_reset_email_link(self.selenium, reset_password_url)
|
|
644
649
|
|
|
645
650
|
new_password = "AnotherPassword12!"
|
|
646
651
|
|
|
@@ -650,7 +655,8 @@ class TestTeacherFrontend(BaseTest):
|
|
|
650
655
|
page = HomePage(self.selenium).go_to_teacher_login_page().login(email, new_password)
|
|
651
656
|
assert self.is_dashboard_page(page)
|
|
652
657
|
|
|
653
|
-
|
|
658
|
+
@patch("portal.forms.registration.send_dotdigital_email")
|
|
659
|
+
def test_reset_with_same_password(self, mock_send_dotdigital_email: Mock):
|
|
654
660
|
email, password = signup_teacher_directly()
|
|
655
661
|
create_organisation_directly(email)
|
|
656
662
|
_, _, access_code = create_class_directly(email)
|
|
@@ -660,23 +666,26 @@ class TestTeacherFrontend(BaseTest):
|
|
|
660
666
|
|
|
661
667
|
page.reset_email_submit(email)
|
|
662
668
|
|
|
663
|
-
|
|
669
|
+
mock_send_dotdigital_email.assert_called_with(campaign_ids["reset_password"], ANY, personalization_values=ANY)
|
|
670
|
+
|
|
671
|
+
reset_password_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"][
|
|
672
|
+
"RESET_PASSWORD_LINK"
|
|
673
|
+
]
|
|
664
674
|
|
|
665
|
-
page = email_utils.follow_reset_email_link(self.selenium,
|
|
675
|
+
page = email_utils.follow_reset_email_link(self.selenium, reset_password_url)
|
|
666
676
|
|
|
667
677
|
page.reset_password_fail(password)
|
|
668
678
|
|
|
669
679
|
message = page.browser.find_element(By.CLASS_NAME, "errorlist")
|
|
670
680
|
assert "Please choose a password that you haven't used before" in message.text
|
|
671
681
|
|
|
672
|
-
|
|
682
|
+
@patch("portal.forms.registration.send_dotdigital_email")
|
|
683
|
+
def test_reset_password_fail(self, mock_send_dotdigital_email: Mock):
|
|
673
684
|
page = self.get_to_forgotten_password_page()
|
|
674
685
|
fake_email = "fake_email@fakeemail.com"
|
|
675
686
|
page.reset_email_submit(fake_email)
|
|
676
687
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
assert len(mail.outbox) == 0
|
|
688
|
+
mock_send_dotdigital_email.assert_not_called()
|
|
680
689
|
|
|
681
690
|
def test_admin_sees_all_school_classes(self):
|
|
682
691
|
email, password = signup_teacher_directly()
|
portal/views/legal.py
CHANGED
|
@@ -5,7 +5,7 @@ def privacy_notice(request):
|
|
|
5
5
|
return render(
|
|
6
6
|
request,
|
|
7
7
|
"portal/privacy_notice.html",
|
|
8
|
-
{"last_updated": "
|
|
8
|
+
{"last_updated": "11th April 2024", "last_updated_children": "11th April 2024"},
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|