Hi,
Just went through the getting started tutorial of Ueberauth Guardian, https://github.com/ueberauth/guardian/blob/master/guides/tutorial/start-tutorial.md and getting the following error:
[debug] Processing with AuthMeWeb.SessionController.login/2
Parameters: %{"_csrf_token" => "ED8hNV01HAoVJgUNJgFUCE01d0NPLhVfvMNv9rRLwB2Fyv-cxE8q6Zzo", "_utf8" => "✓", "user" => %{"password" => "[FILTERED]", "username" => "me"}}
Pipelines: [:browser, :auth]
[debug] QUERY OK source="users" db=0.4ms
SELECT u0."id", u0."email", u0."password", u0."username", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."username" = $1) ["me"]
[info] Sent 500 in 332ms
[error] #PID<0.494.0> running AuthMeWeb.Endpoint (connection #PID<0.486.0>, stream id 4) terminated
Server: localhost:4000 (http)
Request: POST /login
** (exit) an exception was raised:
** (Protocol.UndefinedError) protocol Enumerable not implemented for %AuthMe.UserManager.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, email: "me@me.com", id: 1, inserted_at: ~N[2019-07-27 10:02:07], password: "$argon2id$v=19$m=131072,t=8,p=4$/U8dnLAcxhvQWu3uNrQmGw$FBsHeET8o9+ecOrr2s7y+I3JRneZJUP1r5QJg66usKY", updated_at: ~N[2019-07-27 10:02:07], username: "me"}. This protocol is implemented for: Ecto.Adapters.SQL.Stream, Postgrex.Stream, DBConnection.Stream, DBConnection.PrepareStream, HashSet, Range, Map, Function, List, Stream, Date.Range, HashDict, GenEvent.Stream, MapSet, File.Stream, IO.Stream
(elixir) /private/tmp/elixir-20190202-21222-1ilp2g0/elixir-1.8.1/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) /private/tmp/elixir-20190202-21222-1ilp2g0/elixir-1.8.1/lib/elixir/lib/enum.ex:141: Enumerable.reduce/3
(elixir) lib/enum.ex:3015: Enum.reverse/1
(elixir) lib/enum.ex:2647: Enum.to_list/1
(elixir) lib/map.ex:181: Map.new_from_enum/1
(guardian) lib/guardian.ex:573: Guardian.encode_and_sign/4
(guardian) lib/guardian/plug.ex:208: Guardian.Plug.sign_in/5
(auth_me) lib/auth_me_web/controllers/session_controller.ex:30: AuthMeWeb.SessionController.login_reply/2
(auth_me) lib/auth_me_web/controllers/session_controller.ex:1: AuthMeWeb.SessionController.action/2
(auth_me) lib/auth_me_web/controllers/session_controller.ex:1: AuthMeWeb.SessionController.phoenix_controller_pipeline/2
(phoenix) lib/phoenix/router.ex:288: Phoenix.Router.__call__/2
(auth_me) lib/auth_me_web/endpoint.ex:1: AuthMeWeb.Endpoint.plug_builder_call/2
(auth_me) lib/plug/debugger.ex:122: AuthMeWeb.Endpoint."call (overridable 3)"/2
(auth_me) lib/auth_me_web/endpoint.ex:1: AuthMeWeb.Endpoint.call/2
(phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:40: Phoenix.Endpoint.Cowboy2Handler.init/2
(cowboy) /Users/bigbassroller2017/Sites/space-rocket-phx/auth_me/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
(cowboy) /Users/bigbassroller2017/Sites/space-rocket-phx/auth_me/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
(cowboy) /Users/bigbassroller2017/Sites/space-rocket-phx/auth_me/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
lib/auth_me_web/controllers/session_controller.ex
defmodule AuthMeWeb.SessionController do
use AuthMeWeb, :controller
alias AuthMe.{UserManager, UserManager.User, UserManager.Guardian}
def new(conn, _) do
changeset = UserManager.change_user(%User{})
maybe_user = Guardian.Plug.current_resource(conn)
if maybe_user do
redirect(conn, to: "/secret")
else
render(conn, "new.html", changeset: changeset, action: Routes.session_path(conn, :login))
end
end
def login(conn, %{"user" => %{"username" => username, "password" => password}}) do
UserManager.authenticate_user(username, password)
|> login_reply(conn)
end
def logout(conn, _) do
conn
|> Guardian.Plug.sign_out(Guardian, _opts = [])
|> redirect(to: "/login")
end
defp login_reply({:ok, user}, conn) do
conn
|> put_flash(:info, "Welcome back!")
|> Guardian.Plug.sign_in(Guardian, user)
|> redirect(to: "/protected")
end
defp login_reply({:error, reason}, conn) do
conn
|> put_flash(:error, to_string(reason))
|> new(%{})
end
end
lib/auth_me/user_manager/guardian.ex
defmodule AuthMe.UserManager.Guardian do
use Guardian, otp_app: :auth_me
alias AuthMe.UserManager
def subject_for_token(user, _claims) do
{:ok, to_string(user.id)}
end
def resource_from_claims(%{"sub" => id}) do
case UserManager.get_user(id) do
nil -> {:error, :resource_not_found}
user -> {:ok, user}
end
end
end
I am not sure what the issue is. It sounds like the struct is in the wrong format.
I put the code up on a repo along with revised tutorial here: https://github.com/bigbassroller/auth-me
Any help very appreciated!