Server settings → People → Plugins: a plugin switched off for everybody shows as on and theirs to change #490
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#490
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, reading the per-person plugin page againstpolicy.decideand rendering it in a test.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atcore/server_views.py:1059-1063(_policy_rows),core/server_views.py:1198(context["defaults"]),core/server_views.py:1136-1139(_save_policies) andplugins/policy.py:184.The per-person plugin page draws each row from that person's own policy row only, and treats a missing row as available. What actually applies to the person falls back to the instance row when they have none. So a plugin an administrator has switched off, or forced on, for everybody is drawn on a person's page as on and "This person may change it", which is not what that person gets; and there is no way to store "available" for one person as an exception to an instance-wide decision.
core/server_views.py:1060-1062(_policy_rows:PluginPolicy.objects.filter(person=person), andstate = row.state if row else PluginPolicy.State.AVAILABLE);core/server_views.py:1197(context["defaults"], computed and never read bytemplates/server/person_plugins.html);plugins/policy.py:193(row = rows.get(getattr(person, "pk", None)) or rows.get(None));core/server_views.py:1134-1138(_save_policiesdeletes a person's row when the wanted state is available).schema.org,policy.decide("schema.org", person)returnson=False, theirs=False, decided_by="administrator", and the person's page rendersname="on:schema.org" checkedwithname="free:schema.org" checked. Saving that page with both boxes ticked stores nothing (there is no person row to delete), and the instance row still applies, so an administrator trying to give one member the plugin back leaves the page with "Nothing was different." and the member still without it.defaultsthe view already computes). In_save_policiesfor a person, store an explicit available row when the instance row is not available, and delete the person's row only when what was submitted equals the instance default.Done when
tests/test_plugin_policy.pyhas a test that, with an instance-wide forced off row, the person's page renders the switch unticked and says it follows the instance default; and one that saving on and free for that person makespolicy.decidereturnon=True, theirs=True. Both fail today.