diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 635c02b..3c41232 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,9 @@ jobs: - name: Install dependencies run: mix deps.get + - name: Check code formatting + run: mix format --check-formatted + - name: Compile dependencies run: mix deps.compile diff --git a/lib/acx/persist/ecto_adapter.ex b/lib/acx/persist/ecto_adapter.ex index adc1105..e5fc1d4 100644 --- a/lib/acx/persist/ecto_adapter.ex +++ b/lib/acx/persist/ecto_adapter.ex @@ -173,7 +173,7 @@ defmodule Acx.Persist.EctoAdapter do defp build_filtered_query(filter) do import Ecto.Query base_query = from(r in CasbinRule) - + Enum.reduce(filter, base_query, fn {field, value}, query -> add_where_clause(query, field, value) end) @@ -182,7 +182,7 @@ defmodule Acx.Persist.EctoAdapter do # Helper function to add WHERE clause for a single filter condition defp add_where_clause(query, field, values) when is_list(values) do import Ecto.Query - + case field do :ptype -> where(query, [r], r.ptype in ^values) :v0 -> where(query, [r], r.v0 in ^values) @@ -198,7 +198,7 @@ defmodule Acx.Persist.EctoAdapter do defp add_where_clause(query, field, value) do import Ecto.Query - + case field do :ptype -> where(query, [r], r.ptype == ^value) :v0 -> where(query, [r], r.v0 == ^value) diff --git a/test/persist/readonly_file_adapter_filtered_test.exs b/test/persist/readonly_file_adapter_filtered_test.exs index 921f00c..1fe7b66 100644 --- a/test/persist/readonly_file_adapter_filtered_test.exs +++ b/test/persist/readonly_file_adapter_filtered_test.exs @@ -16,6 +16,7 @@ defmodule Acx.Persist.ReadonlyFileAdapterFilteredTest do # Should only have policies with domain1 assert length(policies) == 2 + assert Enum.all?(policies, fn [_ptype, _subj, domain, _obj, _act] -> domain == "domain1" end) end @@ -38,22 +39,25 @@ defmodule Acx.Persist.ReadonlyFileAdapterFilteredTest do # Should only have p rules with domain2 assert length(policies) == 2 + assert Enum.all?(policies, fn [ptype, _subj, domain, _obj, _act] -> - ptype == "p" && domain == "domain2" - end) + ptype == "p" && domain == "domain2" + end) end test "filters policies by list of values" do adapter = ReadonlyFileAdapter.new(@pfile) # Load policies for domain1 OR domain2 (domain is at v1 position) - {:ok, policies} = PersistAdapter.load_filtered_policy(adapter, %{v1: ["domain1", "domain2"]}) + {:ok, policies} = + PersistAdapter.load_filtered_policy(adapter, %{v1: ["domain1", "domain2"]}) # Should have policies with domain1 or domain2 assert length(policies) == 4 + assert Enum.all?(policies, fn [_ptype, _subj, domain, _obj, _act] -> - domain in ["domain1", "domain2"] - end) + domain in ["domain1", "domain2"] + end) end test "returns empty list when policy file is nil" do @@ -78,17 +82,18 @@ defmodule Acx.Persist.ReadonlyFileAdapterFilteredTest do e = Enforcer.set_persist_adapter(e, adapter) # Load only policies for domain1 (domain is at v1 position) - e = Enforcer.load_filtered_policies!(e, %{v1: "domain1"}) - |> Enforcer.load_mapping_policies!() + e = + Enforcer.load_filtered_policies!(e, %{v1: "domain1"}) + |> Enforcer.load_mapping_policies!() # Should only have domain1 policies policies = Enforcer.list_policies(e) assert length(policies) == 2 - + # Domain1 requests should work assert Enforcer.allow?(e, ["alice", "domain1", "data1", "read"]) === true assert Enforcer.allow?(e, ["alice", "domain1", "data1", "write"]) === true - + # Domain2 requests should not work (policies not loaded) assert Enforcer.allow?(e, ["alice", "domain2", "data2", "read"]) === false assert Enforcer.allow?(e, ["bob", "domain2", "data2", "read"]) === false @@ -104,7 +109,7 @@ defmodule Acx.Persist.ReadonlyFileAdapterFilteredTest do policies = Enforcer.list_policies(e) assert length(policies) == 5 - + # Without role mappings loaded, role-based permissions should not work mapping_policies = Enforcer.list_mapping_policies(e) assert length(mapping_policies) == 0