Secure regenerate_cycles: require can?(:create, MembershipFeeCycle) in handler
- Handler returns flash error when non-admin triggers event (e.g. DevTools). - Test: read_only cannot create MembershipFeeCycle so handler rejects.
This commit is contained in:
parent
03d3a7eb1b
commit
dbd0a57292
2 changed files with 55 additions and 33 deletions
|
|
@ -568,7 +568,10 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("regenerate_cycles", _params, socket) do
|
def handle_event("regenerate_cycles", _params, socket) do
|
||||||
# Button is only shown when can_create_cycle (normal_user and admin). Cycle generation uses system actor.
|
# Server-side authorization: do not rely on UI hiding the button (e.g. read_only could trigger via DevTools).
|
||||||
|
actor = current_actor(socket)
|
||||||
|
|
||||||
|
if can?(actor, :create, MembershipFeeCycle) do
|
||||||
socket = assign(socket, :regenerating, true)
|
socket = assign(socket, :regenerating, true)
|
||||||
member = socket.assigns.member
|
member = socket.assigns.member
|
||||||
|
|
||||||
|
|
@ -608,6 +611,12 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
||||||
|> assign(:regenerating, false)
|
|> assign(:regenerating, false)
|
||||||
|> put_flash(:error, format_error(error))}
|
|> put_flash(:error, format_error(error))}
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(:regenerating, false)
|
||||||
|
|> put_flash(:error, format_error(%Ash.Error.Forbidden{}))}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("edit_cycle_amount", %{"cycle_id" => cycle_id}, socket) do
|
def handle_event("edit_cycle_amount", %{"cycle_id" => cycle_id}, socket) do
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,19 @@ defmodule MvWeb.MemberLive.ShowMembershipFeesTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "read_only cannot trigger regenerate_cycles (handler enforces can?)" do
|
||||||
|
@tag role: :read_only
|
||||||
|
test "read_only cannot create MembershipFeeCycle so regenerate_cycles handler would show flash error",
|
||||||
|
%{current_user: read_only_user} do
|
||||||
|
# The regenerate_cycles handler checks can?(actor, :create, MembershipFeeCycle) before
|
||||||
|
# calling the generator. If a read_only user triggered the event (e.g. via DevTools),
|
||||||
|
# the handler returns flash error and no new cycles are created.
|
||||||
|
# This test verifies the condition the handler uses.
|
||||||
|
refute MvWeb.Authorization.can?(read_only_user, :create, MembershipFeeCycle),
|
||||||
|
"read_only must not be allowed to create MembershipFeeCycle so handler rejects regenerate_cycles"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "confirm_delete_all_cycles handler (policy enforced)" do
|
describe "confirm_delete_all_cycles handler (policy enforced)" do
|
||||||
@tag role: :admin
|
@tag role: :admin
|
||||||
test "admin can delete all cycles via UI and cycles are removed", %{conn: conn} do
|
test "admin can delete all cycles via UI and cycles are removed", %{conn: conn} do
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue