Hello world,
So I am setting up a Phoenix server with authentication via Ueberauth & Auth0. When I run the server it boots up just fine (everything compiles). But, when I run mix test, one of my controllers fails to build. The failure looks like this:
Compiling 24 files (.ex)
== Compilation error in file lib/onward_web/controllers/auth_controller.ex ==
** (FunctionClauseError) no function clause matching in Keyword.pop/3
The following arguments were given to Keyword.pop/3:
# 1
nil
# 2
:base_path
# 3
"/auth"
Attempted function clauses (showing 1 out of 1):
def pop(keywords, key, default) when is_list(keywords)
(elixir) lib/keyword.ex:964: Keyword.pop/3
lib/ueberauth.ex:177: Ueberauth.init/1
(plug) lib/plug/builder.ex:302: Plug.Builder.init_module_plug/4
(plug) lib/plug/builder.ex:286: anonymous fn/5 in Plug.Builder.compile/3
(elixir) lib/enum.ex:1925: Enum."-reduce/3-lists^foldl/2-0-"/3
(plug) lib/plug/builder.ex:284: Plug.Builder.compile/3
(phoenix) expanding macro: Phoenix.Controller.Pipeline.__before_compile__/1
lib/onward_web/controllers/auth_controller.ex:1: OnwardWeb.AuthController (module)
Seeing as the arguments given to the failing function include "auth", this suggests to me that the router.ex file may be the problem (as this is where the “auth” route is defined). Below, I’ll include the auth_controller.ex and the router.ex files.
Note: I realize that the code won’t run properly as is. I was in the middle of adding support for tokens when I discovered this build error.
router.ex
defmodule OnwardWeb.Router do
use OnwardWeb, :router
require Ueberauth
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :auth do
plug :add_token_to_conn
end
scope "/", OnwardWeb do
pipe_through [:browser, :auth]
get "/", PageController, :index
end
scope "/auth", OnwardWeb do
pipe_through :browser
get "/logout", AuthController, :logout
get "/:provider", AuthController, :request
get "/:provider/callback", AuthController, :callback
end
defp add_token_to_conn(conn, _params) do
token = get_session(conn, :token)
case token do
nil ->
conn
|> redirect(to: "/auth/auth0")
|> halt
token ->
conn
|> assign(:token, token)
end
end
end
auth_controller.ex
defmodule OnwardWeb.AuthController do
use OnwardWeb, :controller
plug Ueberauth
alias Onward.Accounts.User
alias Onward.Repo
alias Ueberauth.Auth
def logout(conn, _params) do
conn
|> configure_session(drop: true)
|> redirect(to: "/")
end
def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
{:ok, user} = get_or_create(auth)
conn
|> put_session(:current_user, user)
|> redirect(to: "/")
end
defp get_or_create(%Auth{} = auth) do
info = info_from(auth)
case Repo.get_by(User, email: info.email) do
nil -> %User{}
user -> user
end
|> User.changeset(info)
|> Repo.insert_or_update
end
defp info_from(%Auth{} = auth),
do: %{
first_name: first_name_from(auth),
last_name: last_name_from(auth),
phone: phone_from(auth),
email: email_from(auth)
}
defp first_name_from(%Auth{info: %{first_name: first_name}}),
do: first_name
defp last_name_from(%Auth{info: %{last_name: last_name}}),
do: last_name
defp phone_from(%Auth{info: %{phone: phone}}),
do: phone
defp email_from(%Auth{info: %{email: email}}),
do: email
end






















