defmodule ABAC.PDP do require ABAC require BPE require KVS require Record def policy(request, ABAC.policy(rules: r, combining: c)) do fold = fn ABAC.rule_ref(id: i) -> rule(request, :erlang.element(2, :kvs.get(:rule, i, KVS.kvs(mod: :kvs_mnesia)))) end :erlang.apply(:lists, c, [fold, r]) end def policy(_, _), do: false def rule( ABAC.request(endpoint: e, resources: resources) = request, ABAC.rule(api_endpoint: e, type: :permit, object: o, condition: c, resource_match: rm) = rule ) do f = fn ^o -> true _ -> false end x = :lists.filter(f, resources) fold = fn _ -> :erlang.apply(:"Elixir.ABAC.Condition", c, [request, rule]) end x != [] and :erlang.apply(:lists, rm, [fold, x]) end def rule(_, _), do: false def match(x, acc) do case :kvs.index_match(x, :object, KVS.kvs(mod: :kvs_mnesia)) do [ABAC.policy() | _] = p -> p ++ acc _ -> acc end end # PDP def decision(request) do {new_request, policy} = ABAC.Attributes.request(request) x = :lists.foldl(fn x, acc -> match(x, acc) end, [], policy) x != [] and :lists.all(&policy(new_request, &1), x) end end