defmodule DevServer.TestPage do @moduledoc """ Displays a very basic login form according to the currently configured Überauth providers. """ @behaviour Plug alias AshAuthentication.{Info, Strategy} alias Plug.Conn require EEx EEx.function_from_file(:defp, :render, String.replace(__ENV__.file, ".ex", ".html.eex"), [ :assigns ]) @doc false @impl true @spec init(keyword) :: keyword def init(opts), do: opts @doc false @spec call(Conn.t(), any) :: Conn.t() @impl true def call(conn, _opts) do resources = :ash_authentication |> AshAuthentication.authenticated_resources() |> Enum.map(&{&1, Info.authentication_options(&1), Info.authentication_strategies(&1)}) current_users = conn.assigns |> Stream.filter(fn {key, _value} -> key |> to_string() |> String.starts_with?("current_") end) |> Map.new() payload = render(resources: resources, current_users: current_users) Conn.send_resp(conn, 200, payload) end defp render_strategy(strategy, phase, options) when strategy.provider == :password and phase == :register do EEx.eval_string( ~s"""
Register with <%= @strategy.name %>

<%= if @strategy.confirmation_required? do %>
<% end %>
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, options) when strategy.provider == :password and phase == :sign_in do EEx.eval_string( ~s"""
Sign in with <%= @strategy.name %>

""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, options) when strategy.provider == :password and phase == :reset_request do EEx.eval_string( ~s"""
<%= @strategy.name %> reset request
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, options) when strategy.provider == :password and phase == :reset do EEx.eval_string( ~s"""
<%= @strategy.name %> reset request

<%= if @strategy.confirmation_required? do %>
<% end %>
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, _) when strategy.provider == :password and phase == :sign_in_with_token, do: "" defp render_strategy(strategy, phase, options) when strategy.provider == :confirmation and phase == :confirm do EEx.eval_string( ~s"""
<%= @strategy.name %>
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, _options) when strategy.provider == :oauth2 and phase == :request do EEx.eval_string( ~s""" Sign in with <%= @strategy.name %> """, assigns: [ strategy: strategy, route: route_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, :callback, _) when strategy.provider == :oauth2, do: "" defp render_strategy(strategy, :sign_in, _options) when is_struct(strategy, Example.OnlyMartiesAtTheParty) do EEx.eval_string( ~s"""
Sign in a Marty
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, :sign_in), method: Strategy.method_for_phase(strategy, :sign_in) ] ) end defp render_strategy(strategy, phase, options) when is_struct(strategy, Strategy.MagicLink) and phase == :request do EEx.eval_string( ~s"""
<%= @strategy.name %> request
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, options) when is_struct(strategy, Strategy.MagicLink) and phase == :sign_in do EEx.eval_string( ~s"""
<%= @strategy.name %> sign in
""", assigns: [ strategy: strategy, route: route_for_phase(strategy, phase), options: options, method: Strategy.method_for_phase(strategy, phase) ] ) end defp render_strategy(strategy, phase, _options) do inspect({strategy, phase}) end defp route_for_phase(strategy, phase) do path = strategy |> Strategy.routes() |> Enum.find(&(elem(&1, 1) == phase)) |> elem(0) Path.join("/auth", path) end end