Harden NoActor check with runtime environment guard

Add Mix.env() check to match?/3 for defense in depth.
Document NoActor pattern in CODE_GUIDELINES.md.
This commit is contained in:
Moritz 2026-01-22 21:36:09 +01:00
parent 5506b5b2dc
commit 93216f3ee6
3 changed files with 128 additions and 1 deletions

View file

@ -0,0 +1,67 @@
defmodule Mv.Authorization.Checks.NoActorTest do
@moduledoc """
Tests for the NoActor Ash Policy Check.
This check allows actions without an actor ONLY in test environment.
In production/dev, all operations without an actor are denied.
"""
use ExUnit.Case, async: true
alias Mv.Authorization.Checks.NoActor
describe "match?/3" do
test "returns true when actor is nil in test environment" do
# In test environment, NoActor should allow operations
result = NoActor.match?(nil, %{}, [])
assert result == true
end
test "returns false when actor is present" do
actor = %{id: "user-123"}
result = NoActor.match?(actor, %{}, [])
assert result == false
end
test "has compile-time guard preventing production use" do
# The @allow_no_actor_bypass module attribute is set at compile time
# In test: true, in prod/dev: false
# This test verifies the guard exists (compile-time check)
# Runtime check is verified by the fact that match? checks Mix.env()
result = NoActor.match?(nil, %{}, [])
# In test environment, should allow
if Mix.env() == :test do
assert result == true
else
# In other environments, should deny
assert result == false
end
end
test "has runtime guard preventing production use" do
# The match? function checks Mix.env() at runtime
# This provides defense in depth against config drift
result = NoActor.match?(nil, %{}, [])
# Should match compile-time guard
if Mix.env() == :test do
assert result == true
else
assert result == false
end
end
end
describe "describe/1" do
test "returns description based on environment" do
description = NoActor.describe([])
assert is_binary(description)
if Mix.env() == :test do
assert description =~ "test environment"
else
assert description =~ "production/dev"
end
end
end
end