Packages
pow
1.0.29
1.0.39
1.0.38
1.0.37
1.0.36
1.0.35
1.0.34
1.0.33
1.0.32
1.0.31
1.0.30
1.0.29
1.0.28
1.0.27
1.0.26
1.0.25
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.1.0-rc.1
0.1.0-alpha.8
0.1.0-alpha.7
retired
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha
Robust user authentication solution
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/pow/extension/base.ex
defmodule Pow.Extension.Base do
@moduledoc """
Used to set up extensions to enable parts of extension for auto-discovery.
This exists to prevent unnecessary `Code.ensure_compiled/1` calls, and will
let the extension define what modules it has.
## Usage
defmodule MyCustomExtension do
use Pow.Extension.Base
@impl true
def ecto_schema?(), do: true
end
"""
@callback ecto_schema?() :: boolean()
@callback use_ecto_schema?() :: boolean()
@callback phoenix_controller_callbacks?() :: boolean()
@callback phoenix_messages?() :: boolean()
@callback phoenix_router?() :: boolean()
@callback phoenix_templates() :: [{binary(), [binary()]}]
@doc false
defmacro __using__(_opts) do
quote do
@behaviour unquote(__MODULE__)
@doc false
@impl true
def ecto_schema?(), do: false
@doc false
@impl true
def use_ecto_schema?(), do: false
@doc false
@impl true
def phoenix_controller_callbacks?(), do: false
@doc false
@impl true
def phoenix_messages?(), do: false
@doc false
@impl true
def phoenix_router?(), do: false
@doc false
@impl true
def phoenix_templates(), do: []
defoverridable unquote(__MODULE__)
end
end
@doc """
Checks whether an extension has a certain module.
If a base extension module doesn't exist, or is configured improperly,
`Code.ensure_compiled/1` will be used instead to see whether the module
exists for the extension.
"""
@spec has?(atom(), [any()]) :: boolean()
def has?(extension, module_list) do
try do
has_extension_module?(extension, module_list)
rescue
# TODO: Remove or refactor by 1.1.0
_e in UndefinedFunctionError ->
IO.warn("no #{inspect extension} base module to check for #{inspect module_list} support found, please use #{inspect __MODULE__} to implement it")
[extension]
|> Kernel.++(module_list)
|> Module.concat()
|> ensure_compiled?()
end
end
defp ensure_compiled?(module), do: match?({:module, ^module}, Code.ensure_compiled(module))
defp has_extension_module?(extension, ["Ecto", "Schema"]), do: extension.ecto_schema?()
defp has_extension_module?(extension, ["Phoenix", "ControllerCallbacks"]), do: extension.phoenix_controller_callbacks?()
defp has_extension_module?(extension, ["Phoenix", "Messages"]), do: extension.phoenix_messages?()
defp has_extension_module?(extension, ["Phoenix", "Router"]), do: extension.phoenix_router?()
@doc """
Checks whether an extension has a certain module that has a `__using__/1`
macro.
This calls `has?/2` first, If a base extension module doesn't exist, or is
configured improperly, `Kernel.macro_exported?/3` will be used instead to
check if the module has a `__using__/1` macro.
"""
@spec use?(atom(), [any()]) :: boolean()
def use?(extension, module_list) do
case has?(extension, module_list) do
true ->
try do
use_extension_module?(extension, module_list)
rescue
# TODO: Remove or refactor by 1.1.0
_e in UndefinedFunctionError ->
IO.warn("#{inspect extension} has been configured improperly")
[extension]
|> Kernel.++(module_list)
|> Module.concat()
|> Kernel.macro_exported?(:__using__, 1)
end
false ->
false
end
end
defp use_extension_module?(extension, ["Ecto", "Schema"]), do: extension.use_ecto_schema?()
end