defmodule Carny.Statement do @moduledoc """ Associates a bucket of resources with an :allow or :deny. On their own not so useful main use is to be composed into Policies. """ alias __MODULE__ alias Carny.Identifier defstruct effect: :allow, resources: [], privileges: [] @doc """ Checks if an identifier passes a statement. ## Examples iex> Carny.Statement.passes?("start", %Carny.Identifier{}, %Carny.Statement{privileges: ["start"], resources: [%Carny.Identifier{}]}) true """ def passes?( privilege, %Identifier{} = identifier, %Statement{resources: resources, privileges: privileges, effect: :allow} ) when length(resources) > 0 do case privilege in privileges do true -> Enum.reduce_while(resources, true, fn resource, true -> {:cont, Identifier.validate_against(identifier, resource)} _resource, false -> {:halt, false} end) false -> false end end def passes?( %Identifier{} = identifier, %Statement{resources: resources, effect: :deny} = statement ) when length(resources) > 0 do not passes?(identifier, statement) end def passes?(_, _), do: false end