87 lines
2.4 KiB
Elixir
87 lines
2.4 KiB
Elixir
defmodule FrenzyWeb.LoginController do
|
|
use FrenzyWeb, :controller
|
|
alias Frenzy.{Repo, User}
|
|
alias FrenzyWeb.Endpoint
|
|
|
|
if Frenzy.oidc_enabled?() do
|
|
plug Ueberauth
|
|
end
|
|
|
|
def login(conn, params) do
|
|
conn
|
|
|> put_session(:continue_path, Map.get(params, "continue"))
|
|
|> render("login.html", %{
|
|
oidc_enabled?: Frenzy.oidc_enabled?()
|
|
})
|
|
end
|
|
|
|
def login_post(conn, %{"username" => username, "password" => password} = params) do
|
|
user = Repo.get_by(User, username: username)
|
|
|
|
case Bcrypt.check_pass(user, password) do
|
|
{:ok, user} ->
|
|
put_user_and_redirect(conn, user)
|
|
|
|
{:error, _reason} ->
|
|
conn
|
|
|> put_flash(:error, "Invalid username or password.")
|
|
|> redirect(to: Routes.login_path(Endpoint, :login, continue: continue_path(conn)))
|
|
end
|
|
end
|
|
|
|
def logout(conn, _params) do
|
|
conn
|
|
|> put_flash(:info, "Logged out.")
|
|
|> clear_session()
|
|
|> redirect(to: "/")
|
|
end
|
|
|
|
def ueberauth_callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
|
|
conn
|
|
|> put_flash(:error, "Failed to authenticate.")
|
|
|> redirect(to: Routes.login_path(Endpoint, :login, continue: continue_path(conn)))
|
|
end
|
|
|
|
def ueberauth_callback(
|
|
%{assigns: %{ueberauth_auth: %{credentials: %{other: %{user_info: %{"sub" => subject}}}}}} =
|
|
conn,
|
|
_params
|
|
) do
|
|
case Repo.get_by(User, oidc_subject: subject) do
|
|
nil ->
|
|
conn = FrenzyWeb.Plug.Authenticate.call(conn, nil)
|
|
|
|
case conn.assigns.user do
|
|
%User{} = user ->
|
|
changeset = User.set_oidc_subject_changeset(user, %{oidc_subject: subject})
|
|
{:ok, user} = Repo.update(changeset)
|
|
|
|
conn
|
|
|> put_flash(:info, "Successfully linked OIDC.")
|
|
|> redirect(to: continue_path(conn))
|
|
|
|
_ ->
|
|
# TODO: register new user for subject
|
|
conn
|
|
|> put_flash(:error, "No matching OIDC subject.")
|
|
|> redirect(to: Routes.login_path(Endpoint, :login, continue: continue_path(conn)))
|
|
end
|
|
|
|
user ->
|
|
put_user_and_redirect(conn, user)
|
|
end
|
|
end
|
|
|
|
defp continue_path(conn) do
|
|
get_session(conn, :continue_path) || Routes.group_path(Endpoint, :index)
|
|
end
|
|
|
|
defp put_user_and_redirect(conn, user) do
|
|
user_token = Phoenix.Token.sign(Endpoint, "user token", user.id)
|
|
|
|
conn
|
|
|> put_session(:user_token, user_token)
|
|
|> redirect(to: continue_path(conn))
|
|
end
|
|
end
|