PacketFlow.DSL.Capability (packetflow v0.1.0)

DSL for defining PacketFlow capabilities with implication hierarchies and grants

Summary

Functions

Define a capability with implication hierarchies and grants

Define a simple capability with basic operations

Functions

defcapability(name, list)

(macro)

Define a capability with implication hierarchies and grants

Example

defcapability FileSystemCap do
  @implications [
    {FileSystemCap.admin, [FileSystemCap.read, FileSystemCap.write, FileSystemCap.delete]},
    {FileSystemCap.delete, [FileSystemCap.read, FileSystemCap.write]}
  ]

  @grants [
    {FileSystemCap.admin, [FileSystemCap.read(:any), FileSystemCap.write(:any), FileSystemCap.delete(:any)]},
    {FileSystemCap.delete, [FileSystemCap.read(:any), FileSystemCap.write(:any)]}
  ]

  def read(path), do: {:read, path}
  def write(path), do: {:write, path}
  def delete(path), do: {:delete, path}
  def admin(), do: {:admin}

  def implies?(cap1, cap2) do
    implications = @implications
    |> Enum.find(fn {cap, _} -> cap == cap1 end)
    |> case do
      {^cap1, implied_caps} -> Enum.any?(implied_caps, &(&1 == cap2))
      _ -> cap1 == cap2
    end
  end

  def compose(caps) when is_list(caps) do
    caps
    |> Enum.reduce(MapSet.new(), fn cap, acc ->
      granted = grants(cap)
      MapSet.union(acc, MapSet.new([cap | granted]))
    end)
  end

  def grants(capability) do
    grants_map = Map.new(@grants)
    Map.get(grants_map, capability, [])
  end
end

defsimple_capability(name, operations, list)

(macro)

Define a simple capability with basic operations

Example

defsimple_capability UserCap, [:basic, :admin] do
  @implications [
    {UserCap.admin, [UserCap.basic]}
  ]
end