defmodule AsciinemaWeb.SessionController do use AsciinemaWeb, :controller import AsciinemaWeb.UserView, only: [profile_path: 1] alias Asciinema.Users alias AsciinemaWeb.Auth alias Asciinema.Users.User def new(conn, %{"t" => login_token}) do conn |> put_session(:login_token, login_token) |> redirect(to: session_path(conn, :new)) end def new(conn, _params) do render(conn, "new.html") end def create(conn, %{"api_token" => api_token}) do case Users.get_user_with_api_token(api_token) do {:ok, user} -> login_via_api_token(conn, user) {:error, :token_invalid} -> conn |> put_rails_flash(:alert, "Invalid token. Make sure you pasted the URL correctly.") |> redirect(to: "/") {:error, :token_revoked} -> conn |> put_rails_flash(:alert, "This token has been revoked.") |> redirect(to: "/") end end def create(conn, _params) do login_token = get_session(conn, :login_token) conn = delete_session(conn, :login_token) case Users.verify_login_token(login_token) do {:ok, user} -> conn |> Auth.log_in(user) |> put_rails_flash(:notice, "Welcome back!") |> redirect_to_profile {:error, :token_invalid} -> conn |> put_flash(:error, "Invalid login link.") |> redirect(to: login_path(conn, :new)) {:error, :token_expired} -> conn |> put_flash(:error, "This login link has expired, sorry.") |> redirect(to: login_path(conn, :new)) {:error, :user_not_found} -> conn |> put_flash(:error, "This account has been removed.") |> redirect(to: login_path(conn, :new)) end end defp login_via_api_token(conn, logging_user) do current_user = conn.assigns.current_user case {current_user, logging_user} do {nil, %User{email: nil}} -> conn |> Auth.log_in(logging_user) |> put_rails_flash(:notice, "Welcome! Setting username and email will help you with logging in later.") |> redirect_to_edit_profile {nil, %User{}} -> conn |> Auth.log_in(logging_user) |> put_rails_flash(:notice, "Welcome back!") |> redirect_to_profile {%User{id: id, email: nil}, %User{id: id}} -> conn |> put_rails_flash(:notice, "Setting username and email will help you with logging in later.") |> redirect_to_edit_profile {%User{email: nil}, %User{email: nil}} -> Users.merge!(current_user, logging_user) conn |> put_rails_flash(:notice, "Setting username and email will help you with logging in later.") |> redirect_to_edit_profile {%User{email: nil}, %User{}} -> Users.merge!(logging_user, current_user) conn |> Auth.log_in(logging_user) |> put_rails_flash(:notice, "Recorder token has been added to your account.") |> redirect_to_profile {%User{}, %User{email: nil}} -> Users.merge!(current_user, logging_user) conn |> put_rails_flash(:notice, "Recorder token has been added to your account.") |> redirect_to_profile {%User{id: id}, %User{id: id}} -> conn |> put_rails_flash(:notice, "You're already logged in.") |> redirect_to_profile {%User{}, %User{}} -> conn |> put_rails_flash(:alert, "This recorder token belongs to a different user.") |> redirect_to_profile # TODO offer merging end end defp redirect_to_profile(conn) do path = case conn.assigns.current_user do %User{username: nil} -> "/username/new" %User{} = user -> profile_path(user) end redirect(conn, to: path) end defp redirect_to_edit_profile(conn) do redirect(conn, to: user_path(conn, :edit)) end end