fix(authz): finir SEC-16, que mon propre correctif avait laisse a moitie

La vague K a pose un schema sur create_team et edit_team et a laisse cinq
routes soeurs du meme fichier lire int(request.form.get(...)) : add_coach,
add_manager, remove_coach, remove_manager et add_player. Un identifiant non
numerique y etait un 500 dans chacune.

C'est exactement la lecon que ce projet repete depuis la vague D -- corriger
un motif fautif dans une seule couche le laisse dans les autres -- et cette
fois c'est le correctif lui-meme qui l'a commise. Notee comme telle.

Deux defauts de plus, trouves en finissant.

add_player ecrivait status tel quel dans une colonne NOT NULL String(20). Et
toggle_player_status lit "substitute si status == starter, sinon starter" :
une valeur inconnue devenait donc starter a la premiere bascule, c'est-a-dire
promouvait son porteur. Liste blanche dans TEAM_PLAYER_STATUSES.

Et aucune de ces routes ne regardait is_active_account. La requete qui
alimente la liste deroulante des joueurs ne le filtrait pas non plus, alors
que les deux requetes juste au-dessus, coachs et gerants, le posaient -- deux
lignes d'ecart, meme fichier. Un compte desactive etait donc propose et
accepte, alors que is_active_account est precisement ce qui dit que la
personne a quitte le club. Meme oubli dans tryouts.py.

_staff_member delegue desormais a _assignable au lieu de repeter isinstance :
deux fonctions du meme fichier repondant differemment a "ce compte peut-il
prendre ce role" est la forme de tous les defauts qu'a eus ce module.

Verifie par mutation : retirer le controle d'activite ou la liste blanche
fait tomber trois tests.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
GGThed
2026-08-11 20:42:26 -04:00
co-authored by Claude Opus 5
parent 838b247649
commit 20dabecd67
8 changed files with 633 additions and 361 deletions
+172 -164
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: team-tryouts VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-08-11 20:15-0400\n"
"POT-Creation-Date: 2026-08-11 20:39-0400\n"
"PO-Revision-Date: 2026-08-07 20:22-0400\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
@@ -90,127 +90,135 @@ msgstr "Player must be selected."
msgid "Notes must be 2000 characters or less."
msgstr "Notes must be 2000 characters or less."
#: app/validators.py:482
msgid "Date must be in YYYY-MM-DD format."
msgstr "Date must be in YYYY-MM-DD format."
#: app/validators.py:483
msgid "A date is required."
msgstr "A date is required."
#: app/validators.py:489 app/validators.py:554
msgid "Start time must be in HH:MM format."
msgstr "Start time must be in HH:MM format."
#: app/validators.py:490 app/validators.py:555
msgid "A start time is required."
msgstr "A start time is required."
#: app/validators.py:496
msgid "End time must be in HH:MM format."
msgstr "End time must be in HH:MM format."
#: app/validators.py:497
msgid "An end time is required."
msgstr "An end time is required."
#: app/validators.py:501
msgid "Points must be 2000 characters or less."
msgstr "Points must be 2000 characters or less."
#: app/validators.py:516
msgid "End time must be after start time."
msgstr "End time must be after start time."
#: app/validators.py:545 app/validators.py:547
msgid "Day must be 0 (Monday) to 6 (Sunday)."
msgstr "Day must be 0 (Monday) to 6 (Sunday)."
#: app/validators.py:548
msgid "A day is required."
msgstr "A day is required."
#: app/validators.py:583
msgid "Player selection is malformed."
msgstr "Player selection is malformed."
#: app/validators.py:609 app/validators.py:719
msgid "A title is required."
msgstr "A title is required."
#: app/validators.py:618
msgid "Invalid date format."
msgstr "Invalid date format."
#: app/validators.py:623 app/validators.py:630
msgid "Invalid time format."
msgstr "Invalid time format."
#: app/validators.py:624
msgid "Start time is required. Please select a time slot."
msgstr "Start time is required. Please select a time slot."
#: app/validators.py:638
msgid "Unknown match status."
msgstr "Unknown match status."
#: app/validators.py:654
msgid "The end time must come after the start time."
msgstr "The end time must come after the start time."
#: app/validators.py:668
msgid "Unknown match type."
msgstr "Unknown match type."
#: app/validators.py:680
msgid "A team cannot play against itself."
msgstr "A team cannot play against itself."
#: app/validators.py:728
msgid "Unknown game."
msgstr "Unknown game."
#: app/validators.py:733
msgid "Invalid start date format."
msgstr "Invalid start date format."
#: app/validators.py:734
msgid "A start date is required."
msgstr "A start date is required."
#: app/validators.py:740
msgid "Invalid end date format."
msgstr "Invalid end date format."
#: app/validators.py:748
msgid "A tryout must allow at least one player."
msgstr "A tryout must allow at least one player."
#: app/validators.py:751
msgid "The player limit must be a whole number."
msgstr "The player limit must be a whole number."
#: app/validators.py:763
msgid "End date cannot be before start date."
msgstr "End date cannot be before start date."
#: app/validators.py:790 app/validators.py:791
msgid "Team name is required."
msgstr "Team name is required."
#: app/validators.py:797
#: app/validators.py:494 app/validators.py:853
msgid "Invalid coach selection."
msgstr "Invalid coach selection."
#: app/validators.py:803
#: app/validators.py:500 app/validators.py:859
msgid "Invalid manager selection."
msgstr "Invalid manager selection."
#: app/validators.py:815
#: app/validators.py:511
msgid "Invalid player selection."
msgstr "Invalid player selection."
#: app/validators.py:515
msgid "Unknown roster status."
msgstr "Unknown roster status."
#: app/validators.py:538
msgid "Date must be in YYYY-MM-DD format."
msgstr "Date must be in YYYY-MM-DD format."
#: app/validators.py:539
msgid "A date is required."
msgstr "A date is required."
#: app/validators.py:545 app/validators.py:610
msgid "Start time must be in HH:MM format."
msgstr "Start time must be in HH:MM format."
#: app/validators.py:546 app/validators.py:611
msgid "A start time is required."
msgstr "A start time is required."
#: app/validators.py:552
msgid "End time must be in HH:MM format."
msgstr "End time must be in HH:MM format."
#: app/validators.py:553
msgid "An end time is required."
msgstr "An end time is required."
#: app/validators.py:557
msgid "Points must be 2000 characters or less."
msgstr "Points must be 2000 characters or less."
#: app/validators.py:572
msgid "End time must be after start time."
msgstr "End time must be after start time."
#: app/validators.py:601 app/validators.py:603
msgid "Day must be 0 (Monday) to 6 (Sunday)."
msgstr "Day must be 0 (Monday) to 6 (Sunday)."
#: app/validators.py:604
msgid "A day is required."
msgstr "A day is required."
#: app/validators.py:639
msgid "Player selection is malformed."
msgstr "Player selection is malformed."
#: app/validators.py:665 app/validators.py:775
msgid "A title is required."
msgstr "A title is required."
#: app/validators.py:674
msgid "Invalid date format."
msgstr "Invalid date format."
#: app/validators.py:679 app/validators.py:686
msgid "Invalid time format."
msgstr "Invalid time format."
#: app/validators.py:680
msgid "Start time is required. Please select a time slot."
msgstr "Start time is required. Please select a time slot."
#: app/validators.py:694
msgid "Unknown match status."
msgstr "Unknown match status."
#: app/validators.py:710
msgid "The end time must come after the start time."
msgstr "The end time must come after the start time."
#: app/validators.py:724
msgid "Unknown match type."
msgstr "Unknown match type."
#: app/validators.py:736
msgid "A team cannot play against itself."
msgstr "A team cannot play against itself."
#: app/validators.py:784
msgid "Unknown game."
msgstr "Unknown game."
#: app/validators.py:789
msgid "Invalid start date format."
msgstr "Invalid start date format."
#: app/validators.py:790
msgid "A start date is required."
msgstr "A start date is required."
#: app/validators.py:796
msgid "Invalid end date format."
msgstr "Invalid end date format."
#: app/validators.py:804
msgid "A tryout must allow at least one player."
msgstr "A tryout must allow at least one player."
#: app/validators.py:807
msgid "The player limit must be a whole number."
msgstr "The player limit must be a whole number."
#: app/validators.py:819
msgid "End date cannot be before start date."
msgstr "End date cannot be before start date."
#: app/validators.py:846 app/validators.py:847
msgid "Team name is required."
msgstr "Team name is required."
#: app/validators.py:871
msgid "Scores run from 1 to 10."
msgstr "Scores run from 1 to 10."
#: app/validators.py:816
#: app/validators.py:872
msgid "A score must be a whole number from 1 to 10."
msgstr "A score must be a whole number from 1 to 10."
@@ -311,12 +319,12 @@ msgstr "Evaluation submitted successfully!"
msgid "Evaluation updated!"
msgstr "Evaluation updated!"
#: app/routes/evaluations.py:210 app/routes/teams.py:305
#: app/routes/teams.py:346 app/routes/teams.py:387 app/routes/teams.py:412
#: app/routes/teams.py:437 app/routes/teams.py:472 app/routes/tryouts.py:437
#: app/routes/tryouts.py:453 app/routes/tryouts.py:473
#: app/routes/tryouts.py:512 app/routes/tryouts.py:548
#: app/routes/tryouts.py:567
#: app/routes/evaluations.py:210 app/routes/teams.py:341
#: app/routes/teams.py:384 app/routes/teams.py:427 app/routes/teams.py:455
#: app/routes/teams.py:483 app/routes/teams.py:520 app/routes/tryouts.py:444
#: app/routes/tryouts.py:460 app/routes/tryouts.py:480
#: app/routes/tryouts.py:519 app/routes/tryouts.py:555
#: app/routes/tryouts.py:574
msgid "Permission denied."
msgstr "Permission denied."
@@ -373,130 +381,130 @@ msgstr "Use My Team(s) to view your teams."
msgid "You do not have permission to view teams."
msgstr "You do not have permission to view teams."
#: app/routes/teams.py:74
#: app/routes/teams.py:79
msgid "This page is for players."
msgstr "This page is for players."
#: app/routes/teams.py:150
#: app/routes/teams.py:186
msgid "You do not have permission to create teams."
msgstr "You do not have permission to create teams."
#: app/routes/teams.py:161 app/routes/teams.py:203
#: app/routes/teams.py:197 app/routes/teams.py:239
#, python-format
msgid "Team \"%(name)s\" already exists."
msgstr "Team \"%(name)s\" already exists."
#: app/routes/teams.py:182
#: app/routes/teams.py:218
#, python-format
msgid "Team \"%(name)s\" created successfully!"
msgstr "Team \"%(name)s\" created successfully!"
#: app/routes/teams.py:192
#: app/routes/teams.py:228
msgid "You do not have permission to edit this team."
msgstr "You do not have permission to edit this team."
#: app/routes/teams.py:236
#: app/routes/teams.py:272
#, python-format
msgid "Team \"%(name)s\" updated successfully!"
msgstr "Team \"%(name)s\" updated successfully!"
#: app/routes/teams.py:264
#: app/routes/teams.py:300
msgid "You do not have permission to delete teams."
msgstr "You do not have permission to delete teams."
#: app/routes/teams.py:295
#: app/routes/teams.py:331
#, python-format
msgid "Team \"%(name)s\" deleted successfully."
msgstr "Team \"%(name)s\" deleted successfully."
#: app/routes/teams.py:310
#: app/routes/teams.py:348
msgid "Please select a coach."
msgstr "Please select a coach."
#: app/routes/teams.py:315
#: app/routes/teams.py:353
msgid "Only coaches can be assigned as coach."
msgstr "Only coaches can be assigned as coach."
#: app/routes/teams.py:321
#: app/routes/teams.py:359
#, python-format
msgid "%(username)s is already a coach of %(name)s."
msgstr "%(username)s is already a coach of %(name)s."
#: app/routes/teams.py:334
#: app/routes/teams.py:372
#, python-format
msgid "%(username)s added as coach of %(name)s."
msgstr "%(username)s added as coach of %(name)s."
#: app/routes/teams.py:351
#: app/routes/teams.py:391
msgid "Please select a manager."
msgstr "Please select a manager."
#: app/routes/teams.py:356
#: app/routes/teams.py:396
msgid "Only managers can be assigned as manager."
msgstr "Only managers can be assigned as manager."
#: app/routes/teams.py:362
#: app/routes/teams.py:402
#, python-format
msgid "%(username)s is already a manager of %(name)s."
msgstr "%(username)s is already a manager of %(name)s."
#: app/routes/teams.py:375
#: app/routes/teams.py:415
#, python-format
msgid "%(username)s added as manager of %(name)s."
msgstr "%(username)s added as manager of %(name)s."
#: app/routes/teams.py:402
#: app/routes/teams.py:445
#, python-format
msgid "Coach removed from %(name)s."
msgstr "Coach removed from %(name)s."
#: app/routes/teams.py:427
#: app/routes/teams.py:473
#, python-format
msgid "Manager removed from %(name)s."
msgstr "Manager removed from %(name)s."
#: app/routes/teams.py:443 app/routes/tryouts.py:477 app/routes/tryouts.py:578
#: app/routes/teams.py:490 app/routes/tryouts.py:484 app/routes/tryouts.py:585
msgid "Please select a player."
msgstr "Please select a player."
#: app/routes/teams.py:448
#: app/routes/teams.py:496
msgid "Can only assign players to teams."
msgstr "Can only assign players to teams."
#: app/routes/teams.py:454
#: app/routes/teams.py:502
#, python-format
msgid "%(username)s is already on %(name)s."
msgstr "%(username)s is already on %(name)s."
#: app/routes/teams.py:462
#: app/routes/teams.py:510
#, python-format
msgid "%(username)s added to %(name)s!"
msgstr "%(username)s added to %(name)s!"
#: app/routes/teams.py:479 app/routes/teams.py:553
#: app/routes/teams.py:527 app/routes/teams.py:601
#, python-format
msgid "%(username)s is not on %(name)s."
msgstr "%(username)s is not on %(name)s."
#: app/routes/teams.py:487
#: app/routes/teams.py:535
#, python-format
msgid "%(username)s removed from %(name)s."
msgstr "%(username)s removed from %(name)s."
#: app/routes/teams.py:524 app/routes/teams.py:542
#: app/routes/teams.py:572 app/routes/teams.py:590
msgid "You do not have permission to add notes to this team."
msgstr "You do not have permission to add notes to this team."
#: app/routes/teams.py:532
#: app/routes/teams.py:580
msgid "Team notes added successfully!"
msgstr "Team notes added successfully!"
#: app/routes/teams.py:547 app/routes/users/notes.py:207
#: app/routes/teams.py:595 app/routes/users/notes.py:207
#: app/routes/users/notes.py:250
msgid "Can only add notes for players."
msgstr "Can only add notes for players."
#: app/routes/teams.py:563
#: app/routes/teams.py:611
#, python-format
msgid "Note added for %(username)s!"
msgstr "Note added for %(username)s!"
@@ -525,76 +533,76 @@ msgstr "Tryout updated successfully!"
msgid "You do not have permission to view this tryout."
msgstr "You do not have permission to view this tryout."
#: app/routes/tryouts.py:404
#: app/routes/tryouts.py:411
msgid "Only players can register for tryouts."
msgstr "Only players can register for tryouts."
#: app/routes/tryouts.py:408
#: app/routes/tryouts.py:415
msgid "This tryout is not accepting registrations."
msgstr "This tryout is not accepting registrations."
#: app/routes/tryouts.py:415
#: app/routes/tryouts.py:422
msgid "You are already registered for this tryout."
msgstr "You are already registered for this tryout."
#: app/routes/tryouts.py:421 app/routes/tryouts.py:496
#: app/routes/tryouts.py:428 app/routes/tryouts.py:503
msgid "This tryout is full."
msgstr "This tryout is full."
#: app/routes/tryouts.py:427
#: app/routes/tryouts.py:434
msgid "Successfully registered for tryout!"
msgstr "Successfully registered for tryout!"
#: app/routes/tryouts.py:443
#: app/routes/tryouts.py:450
#, python-format
msgid "Tryout status updated to %(new_status)s."
msgstr "Tryout status updated to %(new_status)s."
#: app/routes/tryouts.py:463
#: app/routes/tryouts.py:470
msgid "Registration status updated."
msgstr "Registration status updated."
#: app/routes/tryouts.py:482
#: app/routes/tryouts.py:489
msgid "Can only register players."
msgstr "Can only register players."
#: app/routes/tryouts.py:488
#: app/routes/tryouts.py:495
#, python-format
msgid "%(username)s is already registered for this tryout."
msgstr "%(username)s is already registered for this tryout."
#: app/routes/tryouts.py:502
#: app/routes/tryouts.py:509
#, python-format
msgid "%(username)s registered for tryout!"
msgstr "%(username)s registered for tryout!"
#: app/routes/tryouts.py:538
#: app/routes/tryouts.py:545
#, python-format
msgid "%(username)s removed from tryout."
msgstr "%(username)s removed from tryout."
#: app/routes/tryouts.py:556
#: app/routes/tryouts.py:563
#, python-format
msgid "Team \"%(team_name)s\" created!"
msgstr "Team \"%(team_name)s\" created!"
#: app/routes/tryouts.py:587
#: app/routes/tryouts.py:594
msgid "That player is not registered for this tryout."
msgstr "That player is not registered for this tryout."
#: app/routes/tryouts.py:593
#: app/routes/tryouts.py:600
msgid "Player is already on this team."
msgstr "Player is already on this team."
#: app/routes/tryouts.py:598
#: app/routes/tryouts.py:605
msgid "Player added to team!"
msgstr "Player added to team!"
#: app/routes/tryouts.py:608
#: app/routes/tryouts.py:615
msgid "You do not have permission to delete this tryout."
msgstr "You do not have permission to delete this tryout."
#: app/routes/tryouts.py:644
#: app/routes/tryouts.py:651
msgid "Tryout deleted successfully."
msgstr "Tryout deleted successfully."