Skip to content

Commit

Permalink
chore: added minor guard to prevent users without profile from gettin…
Browse files Browse the repository at this point in the history
…g stuck
  • Loading branch information
endoooo committed Jan 24, 2024
1 parent 4d3d735 commit 89c7f57
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 28 deletions.
58 changes: 39 additions & 19 deletions lib/lanttern_web/user_auth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule LantternWeb.UserAuth do
import Phoenix.Controller

alias Lanttern.Identity
alias Lanttern.Identity.User

# Make the remember me cookie valid for 60 days.
# If you want bump or reduce this value, also change
Expand All @@ -24,35 +25,43 @@ defmodule LantternWeb.UserAuth do
so LiveView sessions are identified and automatically
disconnected on log out. The line can be safely removed
if you are not using LiveView.
For the specific case when there's no profile
linked to the user, we log the user out.
"""
def log_in_user(conn, user, params \\ %{}) do
user = check_current_profile(user)

token = Identity.generate_user_session_token(user)
user_return_to = get_session(conn, :user_return_to)
with {:ok, user} <- check_current_profile(user) do
token = Identity.generate_user_session_token(user)
user_return_to = get_session(conn, :user_return_to)

conn
|> renew_session()
|> put_token_in_session(token)
|> maybe_write_remember_me_cookie(token, params)
|> redirect(to: user_return_to || signed_in_path(conn))
conn
|> renew_session()
|> put_token_in_session(token)
|> maybe_write_remember_me_cookie(token, params)
|> redirect(to: user_return_to || signed_in_path(conn))
else
:error ->
conn
|> put_flash(
:error,
"There's no profile linked to your user. Check with your Lanttern admin."
)
|> log_out_user()
end
end

defp check_current_profile(%{current_profile_id: nil} = user) do
defp check_current_profile(%{current_profile_id: nil, is_root_admin: false} = user) do
# if there's no current_profile_id, list profiles and use first result
case Identity.list_profiles(user_id: user.id) do
[profile | _rest] ->
{:ok, user_with_profile} =
Identity.update_user_current_profile_id(user, profile.id)

user_with_profile
Identity.update_user_current_profile_id(user, profile.id)

[] ->
user
:error
end
end

defp check_current_profile(user), do: user
defp check_current_profile(user), do: {:ok, user}

defp maybe_write_remember_me_cookie(conn, token, %{"remember_me" => "true"}) do
put_resp_cookie(conn, @remember_me_cookie, token, @remember_me_options)
Expand Down Expand Up @@ -109,9 +118,20 @@ defmodule LantternWeb.UserAuth do
def fetch_current_user(conn, _opts) do
{user_token, conn} = ensure_user_token(conn)

user = user_token && Identity.get_user_by_session_token(user_token)

assign(conn, :current_user, user)
case user_token && Identity.get_user_by_session_token(user_token) do
# if for some reason we reach this point
# without a user profile, log out
%User{current_profile: nil, is_root_admin: false} ->
conn
|> put_flash(
:error,
"There's no profile linked to your user. Check with your Lanttern admin."
)
|> log_out_user()

user ->
assign(conn, :current_user, user)
end
end

defp ensure_user_token(conn) do
Expand Down
16 changes: 10 additions & 6 deletions test/lanttern_web/controllers/user_session_controller_test.exs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
defmodule LantternWeb.UserSessionControllerTest do
use LantternWeb.ConnCase, async: true

import Lanttern.IdentityFixtures
# import Lanttern.IdentityFixtures

setup do
%{user: user_fixture()}
end
# setup do
# %{user: user_fixture()}
# end

# describe "POST /users/log_in" do
# test "logs the user in", %{conn: conn, user: user} do
Expand Down Expand Up @@ -96,8 +96,12 @@ defmodule LantternWeb.UserSessionControllerTest do
# end

describe "DELETE /users/log_out" do
test "logs the user out", %{conn: conn, user: user} do
conn = conn |> log_in_user(user) |> delete(~p"/users/log_out")
test "logs the user out", %{conn: conn} do
conn =
register_and_log_in_user(%{conn: conn})
|> Map.get(:conn)
|> delete(~p"/users/log_out")

assert redirected_to(conn) == ~p"/"
refute get_session(conn, :user_token)
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "Logged out successfully"
Expand Down
6 changes: 3 additions & 3 deletions test/lanttern_web/live/user_login_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule LantternWeb.UserLoginLiveTest do
use LantternWeb.ConnCase

import Phoenix.LiveViewTest
import Lanttern.IdentityFixtures
# import Lanttern.IdentityFixtures

describe "Log in page" do
# test "renders log in page", %{conn: conn} do
Expand All @@ -22,8 +22,8 @@ defmodule LantternWeb.UserLoginLiveTest do

test "redirects if already logged in", %{conn: conn} do
result =
conn
|> log_in_user(user_fixture())
register_and_log_in_user(%{conn: conn})
|> Map.get(:conn)
|> live(~p"/users/log_in")
|> follow_redirect(conn, "/dashboard")

Expand Down

0 comments on commit 89c7f57

Please sign in to comment.