Suggestions: any action word other than 'decline' accepts the suggestion into the record #447

Closed
opened 2026-10-01 10:46:46 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, reading SuggestionActionView and posting to it with the test client.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The code is now at applications/views.py:1285-1298 in SuggestionActionView.post; applications/urls.py:31-35 has 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 decline as accept. 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.

  • Where: applications/urls.py:31-35 (suggestions/<int:pk>/<str:action>/); applications/views.py:1245-1258 in SuggestionActionView.post (if action == "decline": ... return, then suggestions.accept(...) for anything else).
  • What happens: a POST to /applications/suggestions/<pk>/whatever/ for a pending suggestion that proposes Interviewing answers 302, marks the suggestion accepted, and moves the application to Interviewing through change_status. Reproduced with the test client.
  • Why it matters: today's templates post only accept and decline, 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.
  • Fix: handle accept explicitly 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

  • A test in tests/test_suggestions.py posts to suggestion_action with an unknown action and asserts a 404, a suggestion still pending and an unchanged status; it fails today.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, reading `SuggestionActionView` and posting to it with the test client. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The code is now at `applications/views.py:1285-1298` in `SuggestionActionView.post`; `applications/urls.py:31-35` has 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 `decline` as `accept`. 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. - **Where:** `applications/urls.py:31-35` (`suggestions/<int:pk>/<str:action>/`); `applications/views.py:1245-1258` in `SuggestionActionView.post` (`if action == "decline": ... return`, then `suggestions.accept(...)` for anything else). - **What happens:** a `POST` to `/applications/suggestions/<pk>/whatever/` for a pending suggestion that proposes *Interviewing* answers 302, marks the suggestion `accepted`, and moves the application to *Interviewing* through `change_status`. Reproduced with the test client. - **Why it matters:** today's templates post only `accept` and `decline`, 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. - **Fix:** handle `accept` explicitly 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 - A test in `tests/test_suggestions.py` posts to `suggestion_action` with an unknown action and asserts a 404, a suggestion still pending and an unchanged status; it fails today.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:46:46 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#447
No description provided.