Current section

Files

Jump to
conductor lib conductor.ex
Raw

lib/conductor.ex

defmodule Conductor do
@moduledoc false
defmacro __using__(_opts) do
quote do
Module.register_attribute(__MODULE__, :conductor_marks, accumulate: true)
@before_compile Conductor
@on_definition Conductor
end
end
def __on_definition__(env, _kind, name, _args, _guards, _body) do
authorize = Module.get_attribute(env.module, :authorize)
if authorize do
mark = %Conductor.Mark{action: name, scope: authorize[:scope]}
Module.put_attribute(env.module, :conductor_marks, mark)
Module.delete_attribute(env.module, :authorize)
end
end
defmacro __before_compile__(env) do
marks = Module.get_attribute(env.module, :conductor_marks)
plugs =
Enum.reduce(marks, [handle_not_marked(marks)], fn(mark, acc) ->
[handle_mark(mark) | acc]
end)
quote do
unquote(plugs)
end
end
defp handle_mark(%Conductor.Mark{action: action, scope: scope}) do
quote do
plug Conductor.Plugs.Authorize, unquote(scope) when var!(action) in [unquote(action)]
end
end
defp handle_not_marked(marks) do
marked_actions = Enum.map(marks, &Map.get(&1, :action))
quote do
plug Conductor.Plugs.Authorize, nil when not var!(action) in unquote(marked_actions)
end
end
end