Suggestions: any action word other than 'decline' accepts the suggestion into the record #447
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#447
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, readingSuggestionActionViewand posting to it with the test client.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atapplications/views.py:1285-1298inSuggestionActionView.post;applications/urls.py:31-35has not moved, and the test client gives the same answer.The suggestion route takes the action as free text, and the view treats everything that is not
declineasaccept. A request whose action is misspelt, or names an action the view does not know, writes the suggestion into the timeline and can move the application's status, which is the one thing a suggestion is never meant to do without the person saying yes.applications/urls.py:31-35(suggestions/<int:pk>/<str:action>/);applications/views.py:1245-1258inSuggestionActionView.post(if action == "decline": ... return, thensuggestions.accept(...)for anything else).POSTto/applications/suggestions/<pk>/whatever/for a pending suggestion that proposes Interviewing answers 302, marks the suggestionaccepted, and moves the application to Interviewing throughchange_status. Reproduced with the test client.acceptanddecline, so a person does not meet this by clicking. It costs the moment somebody adds a third action (a later or snooze button, a plugin page, a typo in a template): the new button silently accepts, and the timeline gains an entry signed by the plugin that the person never approved.acceptexplicitly and answer 404 for any other action, or restrict the route to the two words (re_path(r"^suggestions/(?P<pk>\d+)/(?P<action>accept|decline)/$", ...)).Done when
tests/test_suggestions.pyposts tosuggestion_actionwith an unknown action and asserts a 404, a suggestion still pending and an unchanged status; it fails today.