cfl-common 5.3.0__py3-none-any.whl → 8.9.15__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.
- cfl_common-8.9.15.dist-info/METADATA +47 -0
- cfl_common-8.9.15.dist-info/RECORD +99 -0
- {cfl_common-5.3.0.dist-info → cfl_common-8.9.15.dist-info}/WHEEL +1 -1
- common/app_settings.py +35 -5
- common/csp_config.py +85 -0
- common/fixtures/aimmo_characters.json +30 -30
- common/fixtures/aimmo_characters2.json +1 -1
- common/fixtures/aimmo_characters3.json +35 -0
- common/helpers/data_migration_loader.py +3 -4
- common/helpers/emails.py +228 -108
- common/helpers/generators.py +1 -1
- common/helpers/organisation.py +10 -0
- common/mail.py +201 -0
- common/migrations/0002_emailverification.py +1 -3
- common/migrations/0005_add_worksheets.py +2 -13
- common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +2 -14
- common/migrations/0008_unlock_worksheet_3.py +1 -6
- common/migrations/0011_student_login_id.py +3 -3
- common/migrations/0012_usersession.py +39 -0
- common/migrations/0013_class_school.py +42 -0
- common/migrations/0014_login_type.py +29 -0
- common/migrations/0015_dailyactivity.py +31 -0
- common/migrations/0016_joinreleasestudent.py +42 -0
- common/migrations/0017_copy_email_to_username.py +18 -0
- common/migrations/0018_update_aimmo_character_image_path.py +15 -0
- common/migrations/0019_aimmocharacter_alt.py +16 -0
- common/migrations/0020_class_is_active_and_null_access_code.py +23 -0
- common/migrations/0021_school_is_active.py +28 -0
- common/migrations/0022_school_cleanup.py +29 -0
- common/migrations/0023_userprofile_aimmo_badges.py +22 -0
- common/migrations/0024_teacher_invited_by.py +25 -0
- common/migrations/0025_schoolteacherinvitation.py +47 -0
- common/migrations/0026_teacher_remove_join_request.py +22 -0
- common/migrations/0027_class_created_by.py +25 -0
- common/migrations/0028_coding_club_downloads.py +23 -0
- common/migrations/0029_dynamicelement.py +22 -0
- common/migrations/0030_add_maintenance_banner.py +25 -0
- common/migrations/0031_improve_admin_panel.py +56 -0
- common/migrations/0032_dailyactivity_level_control_submits.py +18 -0
- common/migrations/0033_password_reset_tracking_fields.py +23 -0
- common/migrations/0034_dailyactivity_daily_school_student_lockout_reset.py +18 -0
- common/migrations/0035_rename_lockout_fields.py +27 -0
- common/migrations/0036_rename_awaiting_email_verification_userprofile_is_verified.py +17 -0
- common/migrations/0037_migrate_email_verification.py +21 -0
- common/migrations/0038_delete_emailverification.py +16 -0
- common/migrations/0039_copy_email_to_username.py +18 -0
- common/migrations/0040_school_county.py +18 -0
- common/migrations/0041_populate_gb_counties.py +27 -0
- common/migrations/0042_totalactivity.py +25 -0
- common/migrations/0043_add_total_activity.py +30 -0
- common/migrations/0044_update_activity_models.py +33 -0
- common/migrations/0045_otp.py +23 -0
- common/migrations/0046_alter_school_country.py +19 -0
- common/migrations/0047_delete_school_postcode.py +16 -0
- common/migrations/0048_unique_school_names.py +42 -0
- common/migrations/0049_anonymise_orphan_users.py +29 -0
- common/migrations/0050_anonymise_orphan_schools.py +30 -0
- common/migrations/0051_verify_returning_users.py +26 -0
- common/migrations/0052_add_cse_fields.py +68 -0
- common/migrations/0053_clean_class_data.py +24 -0
- common/migrations/0054_delete_aimmo_models.py +20 -0
- common/migrations/0055_alter_schoolteacherinvitation_token.py +18 -0
- common/migrations/0056_set_non_school_teachers_as_non_admins.py +25 -0
- common/migrations/0057_teacher_teacher__is_admin.py +19 -0
- common/migrations/0058_userprofile_google_refresh_token_and_more.py +24 -0
- common/models.py +347 -63
- common/permissions.py +20 -8
- common/static/common/img/RR_logo.svg +336 -0
- common/static/common/img/brain.svg +1 -0
- common/templates/common/onetrust_cookies_consent_notice.html +6 -6
- common/tests/test_migration_anonymise_orphan_schools.py +30 -0
- common/tests/test_migration_anonymise_orphan_users.py +30 -0
- common/tests/test_migration_blocked_time.py +3 -11
- common/tests/test_migration_remove_teacher_title.py +1 -3
- common/tests/test_migration_unique_school_names.py +33 -0
- common/tests/test_migration_verify_returning_users.py +59 -0
- common/tests/test_models.py +49 -43
- common/tests/utils/classes.py +1 -3
- common/tests/utils/email.py +11 -49
- common/tests/utils/organisation.py +10 -14
- common/tests/utils/student.py +14 -67
- common/tests/utils/teacher.py +16 -38
- common/tests/utils/user.py +1 -3
- cfl_common-5.3.0.dist-info/METADATA +0 -20
- cfl_common-5.3.0.dist-info/RECORD +0 -48
- common/email_messages.py +0 -218
- common/fixtures/unlock_worksheet3.json +0 -20
- common/fixtures/worksheets.json +0 -98
- common/fixtures/worksheets2.json +0 -110
- common/tests/test_migration_aimmo_characters.py +0 -31
- common/tests/test_migration_worksheets.py +0 -49
- {cfl_common-5.3.0.dist-info → cfl_common-8.9.15.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cfl-common
|
|
3
|
+
Version: 8.9.15
|
|
4
|
+
Classifier: Programming Language :: Python :: 3
|
|
5
|
+
Classifier: Operating System :: OS Independent
|
|
6
|
+
Requires-Dist: asgiref==3.11.0; python_version >= "3.9"
|
|
7
|
+
Requires-Dist: certifi==2026.1.4; python_version >= "3.7"
|
|
8
|
+
Requires-Dist: cffi==2.0.0; platform_python_implementation != "PyPy"
|
|
9
|
+
Requires-Dist: charset-normalizer==3.4.4; python_version >= "3.7"
|
|
10
|
+
Requires-Dist: cryptography==44.0.1; python_version >= "3.7" and python_full_version not in "3.9.0, 3.9.1"
|
|
11
|
+
Requires-Dist: diff-match-patch==20241021; python_version >= "3.7"
|
|
12
|
+
Requires-Dist: django==5.1.15; python_version >= "3.10"
|
|
13
|
+
Requires-Dist: django-countries==7.6.1
|
|
14
|
+
Requires-Dist: django-csp==3.8
|
|
15
|
+
Requires-Dist: django-formtools==2.5.1; python_version >= "3.8"
|
|
16
|
+
Requires-Dist: django-import-export==4.2.0; python_version >= "3.9"
|
|
17
|
+
Requires-Dist: django-otp==1.7.0; python_version >= "3.8"
|
|
18
|
+
Requires-Dist: django-phonenumber-field==8.4.0; python_version >= "3.10"
|
|
19
|
+
Requires-Dist: django-pipeline==4.0.0; python_version >= "3.9"
|
|
20
|
+
Requires-Dist: django-two-factor-auth==1.17.0; python_version >= "3.8"
|
|
21
|
+
Requires-Dist: djangorestframework==3.16.0; python_version >= "3.9"
|
|
22
|
+
Requires-Dist: idna==3.11; python_version >= "3.8"
|
|
23
|
+
Requires-Dist: libsass==0.23.0; python_version >= "3.8"
|
|
24
|
+
Requires-Dist: more-itertools==8.7.0; python_version >= "3.5"
|
|
25
|
+
Requires-Dist: numpy==2.4.1; python_version >= "3.11"
|
|
26
|
+
Requires-Dist: pandas==2.3.3; python_version >= "3.9"
|
|
27
|
+
Requires-Dist: pgeocode==0.4.0; python_version >= "3.8"
|
|
28
|
+
Requires-Dist: pycparser==2.23; implementation_name != "PyPy"
|
|
29
|
+
Requires-Dist: pyjwt==2.6.0; python_version >= "3.7"
|
|
30
|
+
Requires-Dist: pypng==0.20220715.0
|
|
31
|
+
Requires-Dist: python-dateutil==2.9.0.post0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2"
|
|
32
|
+
Requires-Dist: pytz==2025.2
|
|
33
|
+
Requires-Dist: qrcode==7.4.2; python_version >= "3.7"
|
|
34
|
+
Requires-Dist: requests==2.32.5; python_version >= "3.9"
|
|
35
|
+
Requires-Dist: setuptools==80.9.0; python_version >= "3.9"
|
|
36
|
+
Requires-Dist: six==1.17.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2"
|
|
37
|
+
Requires-Dist: sqlparse==0.5.5; python_version >= "3.8"
|
|
38
|
+
Requires-Dist: tablib==3.7.0; python_version >= "3.9"
|
|
39
|
+
Requires-Dist: typing-extensions==4.15.0; python_version >= "3.9"
|
|
40
|
+
Requires-Dist: tzdata==2025.3; python_version >= "2"
|
|
41
|
+
Requires-Dist: urllib3==2.6.3; python_version >= "3.9"
|
|
42
|
+
Requires-Dist: wheel==0.45.1; python_version >= "3.8"
|
|
43
|
+
Dynamic: classifier
|
|
44
|
+
Dynamic: description
|
|
45
|
+
Dynamic: requires-dist
|
|
46
|
+
|
|
47
|
+
Common package for Code for Life
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
common/__init__.py,sha256=XlncBOpKp_gekbKH7Y_i6yu1qy5tJc3Y8sn8cDy-Vgk,48
|
|
2
|
+
common/app_settings.py,sha256=br31aXMTs48oyxkvGmCSoGb94Ir8imONuD2uNO3k7-k,2763
|
|
3
|
+
common/apps.py,sha256=49UXZ3bSkFKvIEOL4zM7y1sAhccQJyRtsoOg5XVd_8Y,129
|
|
4
|
+
common/context_processors.py,sha256=X0iuX5qu9kMWa7q8osE9CJ2LgM7pPOYQFGdjm8X3rk0,236
|
|
5
|
+
common/csp_config.py,sha256=saeg9LbRr5xw7NDJPlt6fqi8Zz0vI8Rpc4VCS6oJNe8,2976
|
|
6
|
+
common/mail.py,sha256=pIRfUMVoJWxdv74UqToj_0_pTVTC51z6QlFVLI3QBOw,6874
|
|
7
|
+
common/models.py,sha256=Qm-UHUR4Qbjn407HbA-YPFHQQk0qOZAsylukptnBXq0,19149
|
|
8
|
+
common/permissions.py,sha256=gC6RQGZI2QDBbglx-xr_V4Hl2C2nf1V2_uPmEuoEcJo,2416
|
|
9
|
+
common/utils.py,sha256=Nn2Npao9Uqad5Js_IdHwF-ow6wrPNpBLW4AO1LxoEBc,1727
|
|
10
|
+
common/fixtures/aimmo_characters.json,sha256=LqjwI05-H4heSBxl6_hS-nb3gMN_4SNVlDnDRT6qNZ8,1234
|
|
11
|
+
common/fixtures/aimmo_characters2.json,sha256=R-23mbjLrvpH4G9khXKcu7PTDK86xf9eHf2HfFTp6us,1285
|
|
12
|
+
common/fixtures/aimmo_characters3.json,sha256=7Pv_6DFastPzmM86sPx6D60Y8Biq84GLL5pWz5NGSUA,1392
|
|
13
|
+
common/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
common/helpers/data_migration_loader.py,sha256=_BhS5lPmhcuVUbryBmJytlWdHyT02KYyxPkHar32mOE,1748
|
|
15
|
+
common/helpers/emails.py,sha256=wBgwTsOQSDIEFGZ3SS4N5XZO9nlwuCVzsjvgH4NNUkc,12060
|
|
16
|
+
common/helpers/generators.py,sha256=kTL5e91I8wgmjJ-mu4jr9vIacjccUZ5pZSAz5cUNhdM,1505
|
|
17
|
+
common/helpers/organisation.py,sha256=e-JKumKoXrkMTzZPv0H4ViWL8vtCt7oXJjn_zZ1ec00,427
|
|
18
|
+
common/migrations/0001_initial.py,sha256=Y2kt2xmdCbrmDXCgqmhXeacicNg26Zj7L7SANSsgAAI,9664
|
|
19
|
+
common/migrations/0002_emailverification.py,sha256=csWNasKNB5HQfrg5Owa6ovwx9f-v3ved-1B6QSu2_3s,2094
|
|
20
|
+
common/migrations/0003_aimmocharacter.py,sha256=ZS_-sJCVUnFdhDjyH75P5bryg5QKHPDfe-SXXK7k9KM,922
|
|
21
|
+
common/migrations/0004_add_aimmocharacters.py,sha256=543WKEphsvdKo8Z7f8wPgZHGxRPWMdo288O5_7edawo,430
|
|
22
|
+
common/migrations/0005_add_worksheets.py,sha256=gM-5yJQ-0r3Plrv__agri5JD5f5pqRf-fuvxYg9RrQw,243
|
|
23
|
+
common/migrations/0006_update_aimmo_character_image_path.py,sha256=De1d02dAYE2KT8uW1qPi0NmWp45_zXVNH7kjWg3f2ko,431
|
|
24
|
+
common/migrations/0007_add_pdf_names_to_first_two_worksheets.py,sha256=XxAVaQpwwst2L5Bh6EuNBwA_jtc04ULwtDY6SNMM46k,257
|
|
25
|
+
common/migrations/0008_unlock_worksheet_3.py,sha256=WzTdGbSjYNlyxNLVRMPWOhNBkR5e-lRewu0xBy5d69c,345
|
|
26
|
+
common/migrations/0009_add_blocked_time_to_teacher_and_student.py,sha256=hdff316HkAVCB0EW61qbR2lxwkxSTsD7OBK66PLBUUQ,599
|
|
27
|
+
common/migrations/0010_remove_teacher_title.py,sha256=dMX-wgD-nzRx2AmrvuLMtb1X7TIv1gZ9icacFgI1LNc,396
|
|
28
|
+
common/migrations/0011_student_login_id.py,sha256=0sMdbzshOu_hT3s7uC0ILKd4PA1waw14y83Re736788,400
|
|
29
|
+
common/migrations/0012_usersession.py,sha256=xmW1hqECQsJw9fKZ-GfwEIhNfdTtOnnq4xiu9ODw4zk,1135
|
|
30
|
+
common/migrations/0013_class_school.py,sha256=n5slnrrOFnrBsjAmkdcRxIUIXOXClHMjuCoDAJrYXAE,1142
|
|
31
|
+
common/migrations/0014_login_type.py,sha256=_liGPnErUKWj2hfErZjkw--2BM8pZCYIvdg96uJts08,817
|
|
32
|
+
common/migrations/0015_dailyactivity.py,sha256=jbzA7hwcEd7mg-w0he-OMpVGSUrjYuWW_QFXY2RWzjk,901
|
|
33
|
+
common/migrations/0016_joinreleasestudent.py,sha256=bu7s-artUHMRPxP0Rnbw10cQy47c2_GYOD8fzzHgXQ8,1208
|
|
34
|
+
common/migrations/0017_copy_email_to_username.py,sha256=oon4z_fHDxABJ-J3T3IeucAJPl2lYCu75zcZk0a1xfs,587
|
|
35
|
+
common/migrations/0018_update_aimmo_character_image_path.py,sha256=WKrxcjGjQ2pE4lcubkU37nsThmHbeVni9tCNSQWm8Sk,387
|
|
36
|
+
common/migrations/0019_aimmocharacter_alt.py,sha256=vhcO1-1TFNYJ2ILLj-tHq_z7jlhd9URwColHqTh11m8,418
|
|
37
|
+
common/migrations/0020_class_is_active_and_null_access_code.py,sha256=g0frY5T5AuVwCPIhj9UEtyB0lyMktl285eBJtLpN-zk,555
|
|
38
|
+
common/migrations/0021_school_is_active.py,sha256=S1HjZIalqLSbqrTu7AF0xvqZEbzcvLCCa1rMa7Pnc-w,736
|
|
39
|
+
common/migrations/0022_school_cleanup.py,sha256=r3YYnC6gJtBy5Ewa8_cjDxvK-W3oEm1IKopn-UXVyXg,661
|
|
40
|
+
common/migrations/0023_userprofile_aimmo_badges.py,sha256=NsOOw2XB03k4U5-2wDzuvN7P69IHLNKcjsPLMxmJbPM,515
|
|
41
|
+
common/migrations/0024_teacher_invited_by.py,sha256=UxsKaGB16y7NjH6mrqZceNLi3tERgLb7gxS14ozsTjw,632
|
|
42
|
+
common/migrations/0025_schoolteacherinvitation.py,sha256=Ba2gpIfeCkPGDnB6JqbM1DXlixkLqsbE3voKVK9Gvok,1819
|
|
43
|
+
common/migrations/0026_teacher_remove_join_request.py,sha256=U7hfnmNwQ0c6yzkiXhMrm2AdgrQszTjBal4U-v0H_VE,528
|
|
44
|
+
common/migrations/0027_class_created_by.py,sha256=H9T78SxvnrM0mjh5l_msa060MsJoWZ_bV-VizBElNpc,632
|
|
45
|
+
common/migrations/0028_coding_club_downloads.py,sha256=RLp7-M95MhwHCZfvo2qHfA_KZXa4pqXBni1Kaf26kOw,606
|
|
46
|
+
common/migrations/0029_dynamicelement.py,sha256=T48j7Uwik_H0bg8eFpSxB-PgxEfmPlPgrr19UFETrj4,684
|
|
47
|
+
common/migrations/0030_add_maintenance_banner.py,sha256=gZAVSbUPfZBTXHlJ_vjO4XwlAgIm6JcR59xZWawS4Ns,851
|
|
48
|
+
common/migrations/0031_improve_admin_panel.py,sha256=UAOBZUS5jR071ciQjO-CoEN6y4BJqMSD1YvYwJBd3FI,1665
|
|
49
|
+
common/migrations/0032_dailyactivity_level_control_submits.py,sha256=E6KiHkUXs1ka0SknETP_HXRTr1cKELPBIj5WgVdZNS8,417
|
|
50
|
+
common/migrations/0033_password_reset_tracking_fields.py,sha256=s2kqLCJBeAIeYJjdlRdXHlmNwZb7Czq7omJp51VKc8M,619
|
|
51
|
+
common/migrations/0034_dailyactivity_daily_school_student_lockout_reset.py,sha256=j3OKxJZTK4NQKVx2JkcK4o9Ie6C9yqbQHfZRsn4NIZg,438
|
|
52
|
+
common/migrations/0035_rename_lockout_fields.py,sha256=1UbvNJ1Qf2SNqGRRJCjXhxHi_rnJuToUW8DEF-tH0ZM,808
|
|
53
|
+
common/migrations/0036_rename_awaiting_email_verification_userprofile_is_verified.py,sha256=wmfENAwFqegcBJYk0wcFdgvY-m2BlGAFQjt-wNO6kBM,396
|
|
54
|
+
common/migrations/0037_migrate_email_verification.py,sha256=zC8rZ3xFhkbHqr3oUyTO2XHleqbx8o9wA2S_24_Y6kY,1018
|
|
55
|
+
common/migrations/0038_delete_emailverification.py,sha256=JTjGGrcJQY7sagMWLTn8jWP4Ldm99LwWo8Sn7QgfIgw,314
|
|
56
|
+
common/migrations/0039_copy_email_to_username.py,sha256=h2NwkcMJ1pBCVKtEj9spM72hG4zm0JnWKXkQI7i9p48,552
|
|
57
|
+
common/migrations/0040_school_county.py,sha256=LuPMnxLXOVZDlIeFtKr5wNrxBvVVrcjbnXyCjWgq4QQ,411
|
|
58
|
+
common/migrations/0041_populate_gb_counties.py,sha256=74pFXOqUcPh8fCyhlOGQNUd0yzfDCUDR-Y2aO6UyP_Y,898
|
|
59
|
+
common/migrations/0042_totalactivity.py,sha256=U8nY0lcnreU4ugWpt8xi8lSDDRDg3cnV7liYVU_MxNw,810
|
|
60
|
+
common/migrations/0043_add_total_activity.py,sha256=9dCx3-uCrmG5XS9snhTeFEOpaqFWZvjIvkgukYldZ4I,1065
|
|
61
|
+
common/migrations/0044_update_activity_models.py,sha256=9ZwggtsiMB8LzKQEoyeDSIaADbz_wFk55bt-C9wSooY,997
|
|
62
|
+
common/migrations/0045_otp.py,sha256=_GmCOFOINqFMBqPBvdBaR1nwAI_FkzIlMTq_kfaN1IQ,599
|
|
63
|
+
common/migrations/0046_alter_school_country.py,sha256=dg_lexw7ALB-jlOm_EBQauk9mI4VbqUGv0qQsHo0b5s,437
|
|
64
|
+
common/migrations/0047_delete_school_postcode.py,sha256=GPV0hLfXmbPpx4-G5OaaLy6aalKvSnZLH0aGggYx9u0,331
|
|
65
|
+
common/migrations/0048_unique_school_names.py,sha256=pu5xiuesvFNGngD-hl0OQ6Gi2r6pEY9fPCayKyb9n04,1433
|
|
66
|
+
common/migrations/0049_anonymise_orphan_users.py,sha256=tw9xMrDMRPDCO8HWjBVlnQF8r1YVCKZnVr2wZ3He6og,847
|
|
67
|
+
common/migrations/0050_anonymise_orphan_schools.py,sha256=_KCkSkoObTpLplX6gXvlV3JXpddn7neyJEa8YKFWeW0,869
|
|
68
|
+
common/migrations/0051_verify_returning_users.py,sha256=WMpoTA24WgimLEVmKXuPqZ3aZdClRhY5vuGtYseeJp0,758
|
|
69
|
+
common/migrations/0052_add_cse_fields.py,sha256=NhUkkcu2EBzJFhewCTccQ63AoANkGq1CXbFWIGJG9jk,2232
|
|
70
|
+
common/migrations/0053_clean_class_data.py,sha256=lBKlDa49YwT660o-Ot6IYe4I1KfervTn4uAijda0nyw,584
|
|
71
|
+
common/migrations/0054_delete_aimmo_models.py,sha256=fmn4mDdlHr5DhPbIl_ygvGwWVFD8TZHAgQ6VUQQgCx8,415
|
|
72
|
+
common/migrations/0055_alter_schoolteacherinvitation_token.py,sha256=lzPAMaI3zU_q25RuIos_LV97NXOa3MIn_eWaEL71Y4I,403
|
|
73
|
+
common/migrations/0056_set_non_school_teachers_as_non_admins.py,sha256=_BrC9yfSYpP-c7EGFZmz8a4Kx_SxnRhpLMxJ70RVFOY,603
|
|
74
|
+
common/migrations/0057_teacher_teacher__is_admin.py,sha256=4pinm9T3JF3PRNLnbXI6mdFiNyxg1MnRs8lMKC4S5Bc,511
|
|
75
|
+
common/migrations/0058_userprofile_google_refresh_token_and_more.py,sha256=xHBv29aWKGkISxhQd_ao5RcZPg5UkirsVf9sqajkk_8,656
|
|
76
|
+
common/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
|
+
common/static/common/img/RR_logo.svg,sha256=DjbNHUHWrYkyuefTsg3uSHFI9-kVHBndpaeznfPPcTw,557149
|
|
78
|
+
common/static/common/img/brain.svg,sha256=689wY5b7E40oKlGumLoHBRpV5z6zCcCp0sGrxjXToXU,16332
|
|
79
|
+
common/templates/common/freshdesk_widget.html,sha256=gc4BCbyh-ADCd0TkLYnT4X8FgOcJL_Bum-PSFXv3Vog,336
|
|
80
|
+
common/templates/common/onetrust_cookies_consent_notice.html,sha256=yrmLn-vbxkYUhaaAdJjefEhaSCbQBNsBb8ACIx4Hzpk,1077
|
|
81
|
+
common/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
82
|
+
common/tests/test_migration_anonymise_orphan_schools.py,sha256=wJRyPgRvBsXLSCFdbBi2GXjgSgDbKUTRiM31CXIvpqs,1194
|
|
83
|
+
common/tests/test_migration_anonymise_orphan_users.py,sha256=MGuI8YVvUReXxjK36i2n-vkC677I8HqVHph778zL34Q,1368
|
|
84
|
+
common/tests/test_migration_blocked_time.py,sha256=z9WxMTrZTKFieLfbQwkoOZozziPHmWVk6T4FysLeHGk,590
|
|
85
|
+
common/tests/test_migration_remove_teacher_title.py,sha256=wwm6tayb75QmDXwXBfxu6SIMf7Ant4rEHHEBLIFjHcI,522
|
|
86
|
+
common/tests/test_migration_unique_school_names.py,sha256=D5SQ1UmD8yHLiEDsA7mWl1O4HzzxsBN_RXErB3ikg5I,1032
|
|
87
|
+
common/tests/test_migration_verify_returning_users.py,sha256=n8JGW-TmE1Hv_4AHl3kn9b6Hwp7DkpZWiYkbPeR8PXw,2054
|
|
88
|
+
common/tests/test_models.py,sha256=xMdzonW5CADMjas_zfg8V1YPQpUetleyn6TE95hbO9k,3723
|
|
89
|
+
common/tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
90
|
+
common/tests/utils/classes.py,sha256=ZA2pp9Pyx3rwi0VFwtuUA2Pys9xQJ-L_zE0u2tpwEH4,1094
|
|
91
|
+
common/tests/utils/email.py,sha256=RljsVjIob4Uqi3O5YhP2ifqfc4cMcdP4Gv0EaL-sHXo,1780
|
|
92
|
+
common/tests/utils/organisation.py,sha256=vNgKFtU3VPcWRnZfh82yCS90PLAK1XTYJNIxGwfgUI4,966
|
|
93
|
+
common/tests/utils/student.py,sha256=GYOyd2VH6QXjjLzjCh4hpT86U5si2URlJJWZwlCVLrU,3846
|
|
94
|
+
common/tests/utils/teacher.py,sha256=KQ_NAl4yQqiX_zwcULQjkovc29JPhnkLR5Nk3Ljzbpg,2661
|
|
95
|
+
common/tests/utils/user.py,sha256=NvLzZLVP4jy5Hn1iztOYF_BTQ9WsbSmuWMEzGzhAsRU,919
|
|
96
|
+
cfl_common-8.9.15.dist-info/METADATA,sha256=T3AlBNWQDjp7QKxJHCviAKmbqjc5uclhdg0b9XF32Wk,2486
|
|
97
|
+
cfl_common-8.9.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
98
|
+
cfl_common-8.9.15.dist-info/top_level.txt,sha256=LOtYx8KZTmnxM_zLK4rwrcI3PRc40Ihwp5rgaQ-ceaI,7
|
|
99
|
+
cfl_common-8.9.15.dist-info/RECORD,,
|
common/app_settings.py
CHANGED
|
@@ -3,9 +3,14 @@ from django.conf import settings
|
|
|
3
3
|
# Email address to source notifications from
|
|
4
4
|
EMAIL_ADDRESS = getattr(settings, "EMAIL_ADDRESS", "no-reply@codeforlife.education")
|
|
5
5
|
|
|
6
|
+
# Dotdigital authorization details
|
|
7
|
+
DOTDIGITAL_AUTH = getattr(settings, "DOTDIGITAL_AUTH", "")
|
|
8
|
+
|
|
6
9
|
# Dotmailer URLs for adding users to the newsletter address book
|
|
7
10
|
DOTMAILER_CREATE_CONTACT_URL = getattr(settings, "DOTMAILER_CREATE_CONTACT_URL", "")
|
|
8
|
-
|
|
11
|
+
DOTMAILER_TEACHER_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_TEACHER_ADDRESS_BOOK_URL", "")
|
|
12
|
+
DOTMAILER_STUDENT_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_STUDENT_ADDRESS_BOOK_URL", "")
|
|
13
|
+
DOTMAILER_NO_ACCOUNT_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_NO_ACCOUNT_ADDRESS_BOOK_URL", "")
|
|
9
14
|
|
|
10
15
|
# Dotmailer username for API authentication
|
|
11
16
|
DOTMAILER_USER = getattr(settings, "DOTMAILER_USER", "")
|
|
@@ -18,7 +23,16 @@ DOTMAILER_DEFAULT_PREFERENCES = getattr(settings, "DOTMAILER_DEFAULT_PREFERENCES
|
|
|
18
23
|
|
|
19
24
|
# Dotmailer URL for getting a user by email
|
|
20
25
|
DOTMAILER_GET_USER_BY_EMAIL_URL = getattr(
|
|
21
|
-
settings,
|
|
26
|
+
settings,
|
|
27
|
+
"DOTMAILER_GET_USER_BY_EMAIL_URL",
|
|
28
|
+
"",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Dotmailer URL for deleting a contact by id
|
|
32
|
+
DOTMAILER_DELETE_USER_BY_ID_URL = getattr(
|
|
33
|
+
settings,
|
|
34
|
+
"DOTMAILER_DELETE_USER_BY_ID_URL",
|
|
35
|
+
"",
|
|
22
36
|
)
|
|
23
37
|
|
|
24
38
|
# Dotmailer URL for adding consent data to a user
|
|
@@ -28,12 +42,28 @@ DOTMAILER_PUT_CONSENT_DATA_URL = getattr(settings, "DOTMAILER_PUT_CONSENT_DATA_U
|
|
|
28
42
|
DOTMAILER_SEND_CAMPAIGN_URL = getattr(settings, "DOTMAILER_SEND_CAMPAIGN_URL", "")
|
|
29
43
|
|
|
30
44
|
# ID of the "Thanks for staying!" campaign in Dotmailer
|
|
31
|
-
DOTMAILER_THANKS_FOR_STAYING_CAMPAIGN_ID = getattr(
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
DOTMAILER_THANKS_FOR_STAYING_CAMPAIGN_ID = getattr(settings, "DOTMAILER_THANKS_FOR_STAYING_CAMPAIGN_ID", "")
|
|
46
|
+
|
|
47
|
+
# Fernet encryption for OAuth2 sign in
|
|
48
|
+
ENCRYPTION_KEY = getattr(settings, "ENCRYPTION_KEY", "")
|
|
34
49
|
|
|
35
50
|
# The name of the google app engine service the application is running on, local otherwise
|
|
36
51
|
MODULE_NAME = getattr(settings, "MODULE_NAME", "local")
|
|
37
52
|
|
|
38
53
|
# Boolean indicating if OneTrust cookie management is enabled or not
|
|
39
54
|
COOKIE_MANAGEMENT_ENABLED = getattr(settings, "COOKIE_MANAGEMENT_ENABLED", True)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def domain(request=None):
|
|
58
|
+
"""Returns the full domain depending on whether it's local, dev, staging or prod."""
|
|
59
|
+
if hasattr(settings, "SERVICE_BASE_URL"):
|
|
60
|
+
return getattr(settings, "SERVICE_BASE_URL")
|
|
61
|
+
|
|
62
|
+
domain = "https://www.codeforlife.education"
|
|
63
|
+
|
|
64
|
+
if MODULE_NAME == "local":
|
|
65
|
+
domain = f"http://{request.get_host()}" if request is not None else "localhost:8000"
|
|
66
|
+
elif MODULE_NAME == "staging" or MODULE_NAME == "dev":
|
|
67
|
+
domain = f"https://{MODULE_NAME}-dot-decent-digit-629.appspot.com"
|
|
68
|
+
|
|
69
|
+
return domain
|
common/csp_config.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""CSP Config"""
|
|
2
|
+
|
|
3
|
+
from .app_settings import domain, MODULE_NAME
|
|
4
|
+
|
|
5
|
+
CSP_DEFAULT_SRC = ("self",)
|
|
6
|
+
CSP_CONNECT_SRC = (
|
|
7
|
+
"'self'",
|
|
8
|
+
"https://*.onetrust.com/",
|
|
9
|
+
"https://api.pwnedpasswords.com",
|
|
10
|
+
"https://euc-widget.freshworks.com/",
|
|
11
|
+
"https://codeforlife.freshdesk.com/",
|
|
12
|
+
"https://api.iconify.design/",
|
|
13
|
+
"https://api.simplesvg.com/",
|
|
14
|
+
"https://api.unisvg.com/",
|
|
15
|
+
"https://www.google-analytics.com/",
|
|
16
|
+
"https://pyodide-cdn2.iodide.io/v0.15.0/full/",
|
|
17
|
+
"https://crowdin.com/",
|
|
18
|
+
)
|
|
19
|
+
CSP_FONT_SRC = ("'self'", "https://fonts.gstatic.com/", "https://fonts.googleapis.com/", "https://use.typekit.net/")
|
|
20
|
+
CSP_SCRIPT_SRC = (
|
|
21
|
+
"'self'",
|
|
22
|
+
"'unsafe-inline'",
|
|
23
|
+
"'unsafe-eval'",
|
|
24
|
+
"https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js",
|
|
25
|
+
"https://cdn.crowdin.com/",
|
|
26
|
+
"https://*.onetrust.com/",
|
|
27
|
+
"https://code.jquery.com/",
|
|
28
|
+
"https://euc-widget.freshworks.com/",
|
|
29
|
+
"https://cdn-ukwest.onetrust.com/",
|
|
30
|
+
"https://code.iconify.design/2/2.0.3/iconify.min.js",
|
|
31
|
+
"https://www.googletagmanager.com/",
|
|
32
|
+
"https://www.recaptcha.net/",
|
|
33
|
+
"https://www.google.com/recaptcha/",
|
|
34
|
+
"https://www.gstatic.com/recaptcha/",
|
|
35
|
+
"https://use.typekit.net/mrl4ieu.js",
|
|
36
|
+
"https://pyodide-cdn2.iodide.io/v0.15.0/full/",
|
|
37
|
+
f"{domain()}/static/portal/",
|
|
38
|
+
f"{domain()}/static/common/",
|
|
39
|
+
)
|
|
40
|
+
CSP_STYLE_SRC = (
|
|
41
|
+
"'self'",
|
|
42
|
+
"'unsafe-inline'",
|
|
43
|
+
"https://euc-widget.freshworks.com/",
|
|
44
|
+
"https://cdn-ukwest.onetrust.com/",
|
|
45
|
+
"https://fonts.googleapis.com/",
|
|
46
|
+
"https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css",
|
|
47
|
+
"https://cdn.crowdin.com/",
|
|
48
|
+
f"{domain()}/static/portal/",
|
|
49
|
+
)
|
|
50
|
+
CSP_FRAME_SRC = (
|
|
51
|
+
"https://storage.googleapis.com/",
|
|
52
|
+
"https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/",
|
|
53
|
+
"https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/",
|
|
54
|
+
"https://www.recaptcha.net/",
|
|
55
|
+
"https://www.google.com/recaptcha/",
|
|
56
|
+
"https://crowdin.com/",
|
|
57
|
+
f"{domain()}/static/common/img/",
|
|
58
|
+
f"{domain()}/static/game/image/",
|
|
59
|
+
)
|
|
60
|
+
CSP_IMG_SRC = (
|
|
61
|
+
"'self'",
|
|
62
|
+
"https://storage.googleapis.com/codeforlife-assets/images/",
|
|
63
|
+
"https://cdn-ukwest.onetrust.com/",
|
|
64
|
+
"https://p.typekit.net/",
|
|
65
|
+
"https://cdn.crowdin.com/",
|
|
66
|
+
"https://crowdin-static.downloads.crowdin.com/",
|
|
67
|
+
"data:",
|
|
68
|
+
f"{domain()}/static/portal/img/",
|
|
69
|
+
f"{domain()}/static/portal/static/portal/img/",
|
|
70
|
+
f"{domain()}/static/portal/img/",
|
|
71
|
+
f"{domain()}/favicon.ico",
|
|
72
|
+
f"{domain()}/img/",
|
|
73
|
+
f"{domain()}/account/two_factor/qrcode/",
|
|
74
|
+
f"{domain()}/static/",
|
|
75
|
+
f"{domain()}/static/game/image/",
|
|
76
|
+
f"{domain()}/static/game/raphael_image/",
|
|
77
|
+
f"{domain()}/static/game/js/blockly/media/",
|
|
78
|
+
f"{domain()}/static/icons/",
|
|
79
|
+
)
|
|
80
|
+
CSP_OBJECT_SRC = (f"{domain()}/static/common/img/", f"{domain()}/static/game/image/")
|
|
81
|
+
CSP_MEDIA_SRC = (
|
|
82
|
+
"https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/",
|
|
83
|
+
f"{domain()}/static/game/sound/",
|
|
84
|
+
f"{domain()}/static/game/js/blockly/media/",
|
|
85
|
+
)
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
[
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"model": "common.aimmocharacter",
|
|
14
|
-
"pk": 2,
|
|
15
|
-
"fields": {
|
|
16
|
-
"name": "Xian",
|
|
17
|
-
"description": "Fun, active, will dance to just about anything that produces a beat. Has great memory, always a joke at hand, might try to introduce memes in Ancient Greece. Scored gold in a track race once and will take any opportunity to bring that up.",
|
|
18
|
-
"image_path": "images/Xian.png",
|
|
19
|
-
"sort_order": 100
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"model": "common.aimmocharacter",
|
|
24
|
-
"pk": 3,
|
|
25
|
-
"fields": {
|
|
26
|
-
"name": "Jools",
|
|
27
|
-
"description": "A quick-witted kid who wasn\u2019t expecting to embark in a time-warping journey but can\u2019t say no to a challenge. Someone has to keep the rest of the group in check, after all!",
|
|
28
|
-
"image_path": "images/Jools.png",
|
|
29
|
-
"sort_order": 200
|
|
30
|
-
}
|
|
2
|
+
{
|
|
3
|
+
"model": "common.aimmocharacter",
|
|
4
|
+
"pk": 1,
|
|
5
|
+
"fields": {
|
|
6
|
+
"name": "Zayed",
|
|
7
|
+
"description": "A pretty chill, curious soul that prefers practice to theory. Always ready to jump into an adventure if it looks interesting enough; not so much otherwise. Probably the one who accidentally turned the time machine on in first place.",
|
|
8
|
+
"image_path": "images/Zayed.png",
|
|
9
|
+
"sort_order": 300
|
|
31
10
|
}
|
|
32
|
-
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"model": "common.aimmocharacter",
|
|
14
|
+
"pk": 2,
|
|
15
|
+
"fields": {
|
|
16
|
+
"name": "Xian",
|
|
17
|
+
"description": "Fun, active, will dance to just about anything that produces a beat. Has great memory, always a joke at hand, might try to introduce memes in Ancient Greece. Scored gold in a track race once and will take any opportunity to bring that up.",
|
|
18
|
+
"image_path": "images/Xian.png",
|
|
19
|
+
"sort_order": 100
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"model": "common.aimmocharacter",
|
|
24
|
+
"pk": 3,
|
|
25
|
+
"fields": {
|
|
26
|
+
"name": "Jools",
|
|
27
|
+
"description": "A quick-witted kid who wasn\u2019t expecting to embark in a time-warping journey but can\u2019t say no to a challenge. Someone has to keep the rest of the group in check, after all!",
|
|
28
|
+
"image_path": "images/Jools.png",
|
|
29
|
+
"sort_order": 200
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"model": "common.aimmocharacter",
|
|
4
|
+
"pk": 1,
|
|
5
|
+
"fields": {
|
|
6
|
+
"name": "Zayed",
|
|
7
|
+
"description": "A pretty chill, curious soul that prefers practice to theory. Always ready to jump into an adventure if it looks interesting enough; not so much otherwise. Probably the one who accidentally turned the time machine on in the first place.",
|
|
8
|
+
"image_path": "images/aimmo_characters/Zayed.png",
|
|
9
|
+
"sort_order": 300,
|
|
10
|
+
"alt": "Illustration of Zayed"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"model": "common.aimmocharacter",
|
|
15
|
+
"pk": 2,
|
|
16
|
+
"fields": {
|
|
17
|
+
"name": "Xian",
|
|
18
|
+
"description": "Fun, active, will dance to just about anything that produces a beat. Has great memory, always a joke at hand, might try to introduce memes in Ancient Greece. Scored gold in a track race once and will take any opportunity to bring that up.",
|
|
19
|
+
"image_path": "images/aimmo_characters/Xian.png",
|
|
20
|
+
"sort_order": 100,
|
|
21
|
+
"alt": "Illustration of Xian"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"model": "common.aimmocharacter",
|
|
26
|
+
"pk": 3,
|
|
27
|
+
"fields": {
|
|
28
|
+
"name": "Jools",
|
|
29
|
+
"description": "A quick-witted kid who wasn't expecting to embark in a time-warping journey but can't say no to a challenge. Someone has to keep the rest of the group in check, after all!",
|
|
30
|
+
"image_path": "images/aimmo_characters/Jools.png",
|
|
31
|
+
"sort_order": 200,
|
|
32
|
+
"alt": "Illustration of Jools"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
]
|
|
@@ -10,7 +10,8 @@ def load_data_from_file(file_name) -> Callable:
|
|
|
10
10
|
For use with migrations.RunPython
|
|
11
11
|
|
|
12
12
|
Args:
|
|
13
|
-
file_name (str): The name of the file containing the data you want to load. Include `.json` at the end.
|
|
13
|
+
file_name (str): The name of the file containing the data you want to load. Include `.json` at the end.
|
|
14
|
+
The file must be in the fixtures directory.
|
|
14
15
|
"""
|
|
15
16
|
absolute_file_path = Path(__file__).resolve().parent.parent / "fixtures" / file_name
|
|
16
17
|
|
|
@@ -26,9 +27,7 @@ def load_data_from_file(file_name) -> Callable:
|
|
|
26
27
|
try:
|
|
27
28
|
return apps.get_model(model_identifier)
|
|
28
29
|
except (LookupError, TypeError):
|
|
29
|
-
raise base.DeserializationError(
|
|
30
|
-
"Invalid model identifier: '%s'" % model_identifier
|
|
31
|
-
)
|
|
30
|
+
raise base.DeserializationError("Invalid model identifier: '%s'" % model_identifier)
|
|
32
31
|
|
|
33
32
|
# Replace the _get_model() function on the module, so loaddata can utilize it.
|
|
34
33
|
python._get_model = _get_model
|