Current section
Files
Jump to
Current section
Files
lib/policy.ex
defmodule Carny.Policy do
@moduledoc """
Policies are lists of statements that you can validate an identifier against.
"""
alias __MODULE__
alias Carny.{Statement, Identifier}
defstruct statements: []
@doc ~S"""
Adds a statement to a given policy
## Examples
iex> Carny.Policy.add_statement(%Carny.Policy{statements: [%Carny.Statement{effect: :deny}]}, %Carny.Statement{})
%Carny.Policy{statements: [%Carny.Statement{}, %Carny.Statement{effect: :deny}]}
"""
def add_statement(%Policy{} = policy, %Statement{} = statement) do
Map.update!(policy, :statements, fn statements ->
[statement | statements]
end)
end
@doc """
Does the id pass a specific policy? The use case here is we have
already looked up a policy for our given resource and want to make
sure that it has access to some other resource (id).
## Examples
iex> Carny.Policy.authorized?(%Carny.Identifier{}, %Carny.Policy{statements: [%Carny.Statement{resources: [%Carny.Identifier{}]}]})
true
"""
def authorized?(%Identifier{} = id, %Policy{} = policy) do
# As soon as we reach a "true" value then halt
# because we know it should have access
Enum.reduce_while(policy.statements, false, fn
statement, false ->
{:cont, Statement.passes?(id, statement)}
_statement, true ->
{:halt, true}
end)
end
end