codeforlife-portal 7.4.5__py2.py3-none-any.whl → 7.4.7__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.
- {codeforlife_portal-7.4.5.dist-info → codeforlife_portal-7.4.7.dist-info}/METADATA +2 -2
- {codeforlife_portal-7.4.5.dist-info → codeforlife_portal-7.4.7.dist-info}/RECORD +10 -10
- portal/__init__.py +1 -1
- portal/static/portal/sass/partials/_header.scss +1 -1
- portal/urls.py +33 -47
- portal/views/cron/user.py +36 -36
- portal/views/home.py +1 -1
- {codeforlife_portal-7.4.5.dist-info → codeforlife_portal-7.4.7.dist-info}/LICENSE.md +0 -0
- {codeforlife_portal-7.4.5.dist-info → codeforlife_portal-7.4.7.dist-info}/WHEEL +0 -0
- {codeforlife_portal-7.4.5.dist-info → codeforlife_portal-7.4.7.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codeforlife-portal
|
|
3
|
-
Version: 7.4.
|
|
3
|
+
Version: 7.4.7
|
|
4
4
|
Classifier: Programming Language :: Python
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Framework :: Django
|
|
@@ -21,7 +21,7 @@ Requires-Dist: django-classy-tags==2.0.0
|
|
|
21
21
|
Requires-Dist: libsass==0.23.0
|
|
22
22
|
Requires-Dist: phonenumbers==8.12.12
|
|
23
23
|
Requires-Dist: more-itertools==8.7.0
|
|
24
|
-
Requires-Dist: cfl-common==7.4.
|
|
24
|
+
Requires-Dist: cfl-common==7.4.7
|
|
25
25
|
Requires-Dist: django-ratelimit==3.0.1
|
|
26
26
|
Requires-Dist: django-preventconcurrentlogins==0.8.2
|
|
27
27
|
Requires-Dist: django-csp==3.7
|
|
@@ -108,7 +108,7 @@ example_project/portal_test_settings.py,sha256=_gI7-HMoPJ-cDGO6n5UlEIHKHuTR5SC_X
|
|
|
108
108
|
example_project/settings.py,sha256=HgGSG0n6Xggd0NieFVoJgn8vKGqyRbCddoB3CRuoT-Y,5640
|
|
109
109
|
example_project/urls.py,sha256=3SsP5jvPAXV5xmduka4zbSZB5PbXggjsalu1ojY5KIo,434
|
|
110
110
|
example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
|
|
111
|
-
portal/__init__.py,sha256=
|
|
111
|
+
portal/__init__.py,sha256=u4NoBVHR1T-STbqzVWCh66zP8QxD3S_5n4P87Q_xWOA,22
|
|
112
112
|
portal/admin.py,sha256=on1-zNRnZvf2cwBN6GVRVYRhkaksrCgfzX8XPWtkvz8,6062
|
|
113
113
|
portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
|
|
114
114
|
portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
|
|
@@ -116,7 +116,7 @@ portal/beta.py,sha256=0TCC-9_KZoM1nuzJ9FiuKR5n9JITdMYenHGQtRvn9UU,255
|
|
|
116
116
|
portal/context_processors.py,sha256=Q68UhmArLPRchS2KmfVR4hKrijllXal3sO5cHYWC2Fc,222
|
|
117
117
|
portal/handlers.py,sha256=gF99OfQrGcIGDnUyONhvylZNU8sl6XHYEurwu0fuiss,422
|
|
118
118
|
portal/models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
|
-
portal/urls.py,sha256=
|
|
119
|
+
portal/urls.py,sha256=4bGQQWiQI9zSG1oceVjQctUnDKggzzZsbYAxuBvijpY,18002
|
|
120
120
|
portal/wsgi.py,sha256=3yRcNxBQG30NhzrVi93bX-DrbXtsIQBc70HiW5wbOyE,401
|
|
121
121
|
portal/forms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
122
122
|
portal/forms/admin.py,sha256=Cdl8-wvasAzvMfgUlFYzQjYeuyC7gIsSiy8V_-jMp7w,2080
|
|
@@ -405,7 +405,7 @@ portal/static/portal/sass/partials/_carousel.scss,sha256=m8N6jSuHBzeKyMUNGGc48Nl
|
|
|
405
405
|
portal/static/portal/sass/partials/_footer.scss,sha256=oqt-Qvz7vtUFNnpe4FkQkaZk3J3fojCy9cKCxqGTWoM,2493
|
|
406
406
|
portal/static/portal/sass/partials/_forms.scss,sha256=cbonSxhtfaHR-4R6i0u65AaIZRG_25C837CgZlLuwCI,7101
|
|
407
407
|
portal/static/portal/sass/partials/_grids.scss,sha256=pnMQht5lZ65MRB-0_nl8yn655hlKC_oWCwZopillVwc,4968
|
|
408
|
-
portal/static/portal/sass/partials/_header.scss,sha256=
|
|
408
|
+
portal/static/portal/sass/partials/_header.scss,sha256=NmVmNasogxhrygApoqAY1KSmq_37eJROj0lstVr6MEY,7422
|
|
409
409
|
portal/static/portal/sass/partials/_images.scss,sha256=Fro4a0VfLo6FyrvGk5yjsjzzGKWVdHeMFJiVC96C7vk,6213
|
|
410
410
|
portal/static/portal/sass/partials/_popup.scss,sha256=GQ6Vtmj3vdOP4Hvsf8ZxKdEtuL8gqoClYpDgQ19kvnQ,2280
|
|
411
411
|
portal/static/portal/sass/partials/_progress-bars.scss,sha256=cTyRa9WLeIE0rETmY58Rcyf-8O6JE3iDTa_jw3mk23g,144
|
|
@@ -609,14 +609,14 @@ portal/views/admin.py,sha256=4Xt3zEyQH7sUwQSrwuRtoCodWidjOzd7gJUwWU96pXY,957
|
|
|
609
609
|
portal/views/api.py,sha256=lCwiclR98G-yTgK55u8IjkueIH8iremeiZSa3jAvO-M,6990
|
|
610
610
|
portal/views/dotmailer.py,sha256=x49p89TtwA1MLysRLtq5yRRzVtIpzGoU__Xb5hPuHak,3208
|
|
611
611
|
portal/views/email.py,sha256=V3wXRxIjeZ4OJBVqGCQrPn-GQWKZK1PCXbR1f2Zpa_4,2174
|
|
612
|
-
portal/views/home.py,sha256=
|
|
612
|
+
portal/views/home.py,sha256=qt5kW7TAaRFXz7BA2BrnHe5oYc69jjoLksEbfr0Aa3c,9715
|
|
613
613
|
portal/views/legal.py,sha256=nUunsTHnhMcXBcDlg1GmUal86k9Vhinne4A2FWfq78M,342
|
|
614
614
|
portal/views/organisation.py,sha256=sPDbiM7hdtpF8GKyh_4n4VPl2a-WnAgnF4q9aSvQCVI,3341
|
|
615
615
|
portal/views/play_landing_page.py,sha256=FFmjUFub3ZdlbMqkB8yX3jAImCzqrUqgb8AZcpKywZ4,308
|
|
616
616
|
portal/views/registration.py,sha256=L9AzIG2nOU946cSOXmUMQRtDo3uxApHX-0ceXopbOCw,10888
|
|
617
617
|
portal/views/teach.py,sha256=nzlyTcgq9ImAjnqrF3esqi212qBLH5Ww1LKE2gSjoRY,210
|
|
618
618
|
portal/views/cron/__init__.py,sha256=5rxXyhJmLOExRdrYZ1VJttTsyRIPRybzdftbUDwFByI,20
|
|
619
|
-
portal/views/cron/user.py,sha256=
|
|
619
|
+
portal/views/cron/user.py,sha256=iKM_FOcSQvrXtRSZUtxSiMFD3M869JP5jvEfRWHLpvM,10731
|
|
620
620
|
portal/views/login/__init__.py,sha256=xSCtyFPSI87BRUybBgqa86ekFEolX5gUDbBSfBUMTyI,399
|
|
621
621
|
portal/views/login/independent_student.py,sha256=3dFULhwMAlX4VDrJl-Znril6a9M5xKBSHO1eWvujfS0,2662
|
|
622
622
|
portal/views/login/student.py,sha256=dt6cMfWepBJsVCRcADltfYSHVpyeP1WGLKSogMJ22E0,5539
|
|
@@ -631,8 +631,8 @@ portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
631
631
|
portal/views/two_factor/core.py,sha256=O_wcBeFqdPYSGNGv-pT_vbs5-Dj1Z-Jfkd6f9-E5yZI,760
|
|
632
632
|
portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
|
|
633
633
|
portal/views/two_factor/profile.py,sha256=tkl_ludo8arMtd5LKNmohM66vpC_YQiP-0nspTSJiJ4,383
|
|
634
|
-
codeforlife_portal-7.4.
|
|
635
|
-
codeforlife_portal-7.4.
|
|
636
|
-
codeforlife_portal-7.4.
|
|
637
|
-
codeforlife_portal-7.4.
|
|
638
|
-
codeforlife_portal-7.4.
|
|
634
|
+
codeforlife_portal-7.4.7.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
|
|
635
|
+
codeforlife_portal-7.4.7.dist-info/METADATA,sha256=s2XuydXH4SnXsts2aElQJ_FeKkJShvHfoJgWIC7v24I,3317
|
|
636
|
+
codeforlife_portal-7.4.7.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
|
|
637
|
+
codeforlife_portal-7.4.7.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
|
|
638
|
+
codeforlife_portal-7.4.7.dist-info/RECORD,,
|
portal/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "7.4.
|
|
1
|
+
__version__ = "7.4.7"
|
portal/urls.py
CHANGED
|
@@ -223,63 +223,53 @@ urlpatterns = [
|
|
|
223
223
|
),
|
|
224
224
|
url(r"^$", home, name="home"),
|
|
225
225
|
url(r"^home-learning", home_learning, name="home-learning"),
|
|
226
|
-
url(
|
|
227
|
-
r"^register_form",
|
|
228
|
-
# register_view,
|
|
229
|
-
home,
|
|
230
|
-
name="register",
|
|
231
|
-
),
|
|
226
|
+
url(r"^register_form", register_view, name="register"),
|
|
232
227
|
url(
|
|
233
228
|
r"^login/teacher/$",
|
|
234
|
-
#
|
|
235
|
-
#
|
|
236
|
-
#
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
home,
|
|
229
|
+
# The ratelimit decorator checks how often a POST request is performed on that view.
|
|
230
|
+
# It checks against the username value specifically. If the number of requests
|
|
231
|
+
# exceeds the specified rate, then the user will be blocked (if block = True).
|
|
232
|
+
ratelimit(
|
|
233
|
+
group=RATELIMIT_LOGIN_GROUP,
|
|
234
|
+
key="post:auth-username",
|
|
235
|
+
method=RATELIMIT_METHOD,
|
|
236
|
+
rate=RATELIMIT_LOGIN_RATE,
|
|
237
|
+
block=True,
|
|
238
|
+
)(TeacherLoginView.as_view()),
|
|
245
239
|
name="teacher_login",
|
|
246
240
|
),
|
|
247
241
|
url(
|
|
248
242
|
rf"^login/student/(?P<access_code>{ACCESS_CODE_REGEX})/(?:(?P<login_type>classform)/)?$",
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
home,
|
|
243
|
+
ratelimit(
|
|
244
|
+
group=RATELIMIT_LOGIN_GROUP,
|
|
245
|
+
key=school_student_key,
|
|
246
|
+
method=RATELIMIT_METHOD,
|
|
247
|
+
rate=RATELIMIT_LOGIN_RATE_SCHOOL_STUDENT,
|
|
248
|
+
block=True,
|
|
249
|
+
is_teacher=False,
|
|
250
|
+
)(StudentLoginView.as_view()),
|
|
258
251
|
name="student_login",
|
|
259
252
|
),
|
|
260
253
|
url(
|
|
261
254
|
r"^login/student/$",
|
|
262
|
-
|
|
263
|
-
home,
|
|
255
|
+
StudentClassCodeView.as_view(),
|
|
264
256
|
name="student_login_access_code",
|
|
265
257
|
),
|
|
266
258
|
url(
|
|
267
259
|
r"^u/(?P<user_id>[0-9]+)/(?P<login_id>[a-z0-9]+)/$",
|
|
268
|
-
|
|
269
|
-
home,
|
|
260
|
+
student_direct_login,
|
|
270
261
|
name="student_direct_login",
|
|
271
262
|
),
|
|
272
263
|
url(
|
|
273
264
|
r"^login/independent/$",
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
home,
|
|
265
|
+
ratelimit(
|
|
266
|
+
group=RATELIMIT_LOGIN_GROUP,
|
|
267
|
+
key="post:username",
|
|
268
|
+
method=RATELIMIT_METHOD,
|
|
269
|
+
rate=RATELIMIT_LOGIN_RATE,
|
|
270
|
+
block=True,
|
|
271
|
+
is_teacher=False,
|
|
272
|
+
)(IndependentStudentLoginView.as_view()),
|
|
283
273
|
name="independent_student_login",
|
|
284
274
|
),
|
|
285
275
|
url(r"^login_form", old_login_form_redirect, name="old_login_form"),
|
|
@@ -300,20 +290,17 @@ urlpatterns = [
|
|
|
300
290
|
),
|
|
301
291
|
url(
|
|
302
292
|
rf"^verify_email/(?P<token>{JWT_REGEX})/$",
|
|
303
|
-
|
|
304
|
-
home,
|
|
293
|
+
verify_email,
|
|
305
294
|
name="verify_email",
|
|
306
295
|
),
|
|
307
296
|
url(
|
|
308
297
|
r"^user/password/reset/student/$",
|
|
309
|
-
|
|
310
|
-
home,
|
|
298
|
+
student_password_reset,
|
|
311
299
|
name="student_password_reset",
|
|
312
300
|
),
|
|
313
301
|
url(
|
|
314
302
|
r"^user/password/reset/teacher/$",
|
|
315
|
-
|
|
316
|
-
home,
|
|
303
|
+
teacher_password_reset,
|
|
317
304
|
name="teacher_password_reset",
|
|
318
305
|
),
|
|
319
306
|
url(
|
|
@@ -323,8 +310,7 @@ urlpatterns = [
|
|
|
323
310
|
),
|
|
324
311
|
url(
|
|
325
312
|
r"^user/password/reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$",
|
|
326
|
-
|
|
327
|
-
home,
|
|
313
|
+
password_reset_check_and_confirm,
|
|
328
314
|
name="password_reset_check_and_confirm",
|
|
329
315
|
),
|
|
330
316
|
url(
|
portal/views/cron/user.py
CHANGED
|
@@ -172,42 +172,42 @@ class SecondVerifyEmailReminderView(CronMixin, APIView):
|
|
|
172
172
|
|
|
173
173
|
class AnonymiseUnverifiedAccounts(CronMixin, APIView):
|
|
174
174
|
def get(self, request):
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
175
|
+
user_count = User.objects.filter(is_active=True).count()
|
|
176
|
+
|
|
177
|
+
teacher_queryset, independent_student_queryset = get_unverified_users(
|
|
178
|
+
USER_DELETE_UNVERIFIED_ACCOUNT_DAYS,
|
|
179
|
+
same_day=False,
|
|
180
|
+
)
|
|
181
|
+
teacher_count = teacher_queryset.count()
|
|
182
|
+
indy_count = independent_student_queryset.count()
|
|
183
|
+
|
|
184
|
+
user_queryset = teacher_queryset.union(independent_student_queryset)
|
|
185
|
+
|
|
186
|
+
for user in user_queryset.iterator(chunk_size=100):
|
|
187
|
+
try:
|
|
188
|
+
anonymise(user)
|
|
189
|
+
except Exception as ex:
|
|
190
|
+
logging.error(f"Failed to anonymise user with id: {user.id}")
|
|
191
|
+
logging.exception(ex)
|
|
192
|
+
|
|
193
|
+
user_count -= User.objects.filter(is_active=True).count()
|
|
194
|
+
logging.info(f"{user_count} unverified users anonymised.")
|
|
195
|
+
|
|
196
|
+
activity_today = DailyActivity.objects.get_or_create(
|
|
197
|
+
date=datetime.now().date()
|
|
198
|
+
)[0]
|
|
199
|
+
activity_today.anonymised_unverified_teachers = teacher_count
|
|
200
|
+
activity_today.anonymised_unverified_independents = indy_count
|
|
201
|
+
activity_today.save()
|
|
202
|
+
|
|
203
|
+
TotalActivity.objects.update(
|
|
204
|
+
anonymised_unverified_teachers=F("anonymised_unverified_teachers")
|
|
205
|
+
+ teacher_count,
|
|
206
|
+
anonymised_unverified_independents=F(
|
|
207
|
+
"anonymised_unverified_independents"
|
|
208
|
+
)
|
|
209
|
+
+ indy_count,
|
|
210
|
+
)
|
|
211
211
|
|
|
212
212
|
return Response()
|
|
213
213
|
|
portal/views/home.py
CHANGED
|
@@ -255,7 +255,7 @@ def coding_club(request):
|
|
|
255
255
|
|
|
256
256
|
def download_student_pack(request, student_pack_type):
|
|
257
257
|
if request.method == "POST":
|
|
258
|
-
|
|
258
|
+
count_student_pack_downloads_click(int(student_pack_type))
|
|
259
259
|
link = cloud_storage("club_packs/PrimaryCodingClub.zip")
|
|
260
260
|
return redirect(link)
|
|
261
261
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|