Skip to content

Commit

Permalink
Merge branch 'email_2fa_conditions' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
zephyranthes03 committed Jan 31, 2025
2 parents 145946d + fb041b1 commit 4c76b84
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 133 deletions.
2 changes: 0 additions & 2 deletions lib/recognizer/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,6 @@ defmodule Recognizer.Accounts do
end
end



@doc """
Deletes cached settings.
"""
Expand Down
11 changes: 0 additions & 11 deletions lib/recognizer_web/authentication.ex
Original file line number Diff line number Diff line change
Expand Up @@ -204,27 +204,16 @@ defmodule RecognizerWeb.Authentication do

def valid_token?(preference, token, counter, two_factor_seed) do
if preference in [:app, "app"] do
IO.inspect("app", label: "valid_token?")
valid_token_app?(token, two_factor_seed)
else
IO.inspect("email", label: "valid_token?")
valid_token_external?(token, two_factor_seed, counter)
end
end

def valid_token_app?(token, two_factor_seed), do: :pot.valid_totp(token, two_factor_seed, interval: 30)

def valid_token_external?(token, two_factor_seed, counter) do
IO.inspect(two_factor_seed, label: "two_factor_seed from valid_token_external")
IO.inspect(token, label: "token from valid_token_external")
IO.inspect(counter, label: "counter from valid_token_external")
IO.inspect(:pot.hotp(two_factor_seed, counter), label: "hotp from valid_token_external")
IO.inspect(:pot.hotp(two_factor_seed, counter), label: "hotp from valid_token_external")
IO.inspect(:pot.hotp(two_factor_seed, counter), label: "hotp from valid_token_external")
IO.inspect(:pot.hotp(two_factor_seed, counter), label: "hotp from valid_token_external")
IO.inspect(token == :pot.hotp(two_factor_seed, counter))
token == :pot.hotp(two_factor_seed, counter)
# :pot.valid_hotp(two_factor_seed, counter, token)
end

defp config(key) do
Expand Down
91 changes: 13 additions & 78 deletions lib/recognizer_web/controllers/accounts/user_settings_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
end

def resend(conn, _params) do
conn = conn
|> put_session(:two_factor_sent, false)
|> put_session(:two_factor_issue_time, System.system_time(:second))
conn =
conn
|> put_session(:two_factor_sent, false)
|> put_session(:two_factor_issue_time, System.system_time(:second))

conn
|> put_flash(:info, "Two factor code has been resent")
Expand All @@ -48,14 +49,7 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
def two_factor_init(conn, _params) do
user = Authentication.fetch_current_user(conn)
current_user = Accounts.get_new_two_factor_settings(user)
IO.inspect(current_user, label: "current_user from two_factor_init")
IO.inspect(user, label: "user from two_factor_init")
# %{two_factor_seed: seed, notification_preference: %{two_factor: method}} = user
{:ok, %{two_factor_seed: seed, notification_preference: %{two_factor: method}} = setting_user } =
current_user #Accounts.get_new_two_factor_settings(user)

# {:ok, %{two_factor_seed: seed, notification_preference: %{two_factor: method}}} =
# Accounts.get_new_two_factor_settings(user)
{:ok, %{two_factor_seed: seed, notification_preference: %{two_factor: method}} = setting_user} = current_user

method_atom = normalize_to_atom(method)

Expand All @@ -65,24 +59,21 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
totp_app_url: Authentication.get_totp_app_url(user, seed)
)
else
# conn = put_session(conn, :two_factor_issue_time, current_time)

conn =
if get_session(conn, :two_factor_issue_time) == nil do
IO.inspect("checkpoint 1")
put_session(conn, :two_factor_issue_time, System.system_time(:second))
else
conn
end

two_factor_sent = get_session(conn, :two_factor_sent)
IO.inspect(two_factor_sent, label: "two_factor_sent from two_factor_init")

conn =
if two_factor_sent do
conn
else
conn = put_session(conn, :two_factor_sent, true)
IO.inspect(setting_user.two_factor_seed, label: "two_factor_seed from two_factor_init")

conn
|> send_two_factor_notification(setting_user, user, method_atom)
end
Expand All @@ -96,44 +87,23 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
"""
def two_factor_confirm(conn, params) do
user = Authentication.fetch_current_user(conn)
IO.inspect(user, label: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!user from two_factor_confirm")
current_user = Accounts.get_new_two_factor_settings(user)

# IO.inspect(user, label: "user from two_factor_confirm")

two_factor_code = Map.get(params, "two_factor_code")
# %{two_factor_seed: seed, notification_preference: %{two_factor: method}} = setting_user = user
{:ok, %{two_factor_seed: seed, notification_preference: %{two_factor: method}} = setting_user } =
current_user #Accounts.get_new_two_factor_settings(user)

# case Accounts.get_new_two_factor_settings(user) do
# {:ok, %{two_factor_seed: seed, notification_preference: %{two_factor: method}} = _settings} ->

IO.inspect("two_factor_confirm", label: "two_factor_confirm")
IO.inspect(seed, label: "seed")
IO.inspect(user.two_factor_seed, label: "user - seed")
IO.inspect(setting_user.two_factor_seed, label: "current_user - seed")
IO.inspect(method, label: "method")
IO.inspect(user.notification_preference.two_factor, label: "user - method")
IO.inspect(setting_user.notification_preference.two_factor, label: "current_user - method")
IO.inspect(two_factor_code, label: "two_factor_code")
{:ok, %{notification_preference: %{two_factor: method}} = setting_user} = current_user

current_time = System.system_time(:second)
conn = ensure_two_factor_issue_time(conn, current_time)

two_factor_issue_time = get_session(conn, :two_factor_issue_time)
method_atom = normalize_to_atom(method)

IO.inspect("checkpoint 2")
IO.inspect(method_atom)
IO.inspect(two_factor_code)
IO.inspect(two_factor_issue_time)
IO.inspect(user.two_factor_seed)
if Authentication.valid_token?(method_atom, two_factor_code, two_factor_issue_time, setting_user.two_factor_seed) do
if current_time - two_factor_issue_time > 900 do
conn = conn
|> put_session(:two_factor_issue_time, current_time)
IO.inspect("checkpoint 3")
conn =
conn
|> put_session(:two_factor_issue_time, current_time)

conn
|> send_two_factor_notification(setting_user, user, method_atom)
|> put_flash(
Expand All @@ -142,36 +112,15 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
)
|> redirect(to: Routes.user_settings_path(conn, :two_factor_confirm))
else
IO.inspect("checkpoint 4")
handle_two_factor_settings(conn, user, two_factor_code, method_atom)

end
else
IO.inspect("checkpoint 8")
conn
|> put_flash(:error, "Two factor code is invalid")
|> redirect(to: Routes.user_settings_path(conn, :two_factor_confirm))
end
end



# {:ok, nil} ->
# IO.inspect("checkpoint 1-1")

# conn
# |> put_flash(:error, "Two factor code is invalid")
# |> redirect(to: Routes.user_settings_path(conn, :two_factor_confirm))

# {:error, reason} ->
# IO.inspect("checkpoint 1-2")

# conn
# |> put_flash(:error, "Error: #{inspect(reason)}")
# |> redirect(to: Routes.user_settings_path(conn, :two_factor_confirm))
# end
# end

defp ensure_two_factor_issue_time(conn, current_time) do
if get_session(conn, :two_factor_issue_time) == nil do
put_session(conn, :two_factor_issue_time, current_time)
Expand All @@ -181,20 +130,12 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
end

defp handle_two_factor_settings(conn, user, two_factor_code, method) do
# user = Authentication.fetch_current_user(conn)
two_factor_issue_time = get_session(conn, :two_factor_issue_time)
IO.inspect("checkpoint 5")
IO.inspect(user, label: "two_factor_seed from handle_two_factor_settings")
IO.inspect(method, label: "two_factor_method from handle_two_factor_settings")

case Accounts.confirm_and_save_two_factor_settings(two_factor_code, two_factor_issue_time, user, method) do
{:ok, updated_user} ->

IO.inspect("checkpoint 6")
IO.inspect(updated_user, label: "updated_user from handle_two_factor_settings")
{:ok, _updated_user} ->
Accounts.clear_two_factor_settings(user)

IO.inspect("checkpoint 7")
conn
|> put_flash(:info, "Two factor code verified")
|> redirect(to: Routes.user_settings_path(conn, :edit))
Expand All @@ -206,7 +147,6 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
end
end


def normalize_to_atom(input) do
cond do
is_atom(input) -> input
Expand Down Expand Up @@ -299,7 +239,6 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
|> put_flash(:error, "Phone number required for text and voice two-factor methods")
|> redirect(to: Routes.user_settings_path(conn, :edit))
else
IO.inspect(preference, label: "preference from update")
Accounts.generate_and_cache_new_two_factor_settings(user, preference)
redirect(conn, to: Routes.user_settings_path(conn, :review))
end
Expand Down Expand Up @@ -375,11 +314,7 @@ defmodule RecognizerWeb.Accounts.UserSettingsController do
if method in ["app", :app] do
conn
else
IO.inspect(user.two_factor_seed, label: "two_factor_seed from deliver_and_update_token")
token = Authentication.generate_token(method, issue_time, user.two_factor_seed)
IO.inspect(issue_time, label: "issue_time from deliver_and_update_token")
IO.inspect(System.system_time(:second), label: "now from deliver_and_update_token")
IO.inspect(token, label: "token from deliver_and_update_token")

conn
|> tap(fn _conn -> Account.deliver_two_factor_token(current_user, token, method) end)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,6 @@ defmodule RecognizerWeb.Accounts.UserSettingsControllerTest do
describe "POST /users/settings/two-factor App (confirm)" do
test "confirm saves and clears cache", %{conn: conn, user: user} do
settings = Accounts.generate_and_cache_new_two_factor_settings(user, :app)
# Accounts.get_new_two_factor_settings(user)
IO.inspect(Accounts.get_new_two_factor_settings(user), label: "get_new_two_factor_settings")

IO.inspect(settings, label: "settings181")

token = Authentication.generate_token(:app, 0, settings)
params = %{"two_factor_code" => token}
Expand All @@ -198,45 +194,22 @@ defmodule RecognizerWeb.Accounts.UserSettingsControllerTest do
|> Repo.get(user.id)
|> Repo.preload(:recovery_codes)

refute Enum.empty?(recovery_codes)
refute Enum.empty?(recovery_codes)

assert {:ok, nil} = Accounts.get_new_two_factor_settings(user)
end

test "confirm redirects without cached settings", %{conn: conn, user: user} do
settings = Accounts.generate_and_cache_new_two_factor_settings(user, :app)
token = Authentication.generate_token(:app, 0, settings)
conn = put_session(conn, :two_factor_issue_time, nil)
conn = put_session(conn, :two_factor_sent, false)
IO.inspect(user, label: "###################################user")
IO.inspect(settings, label: "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@settings")

Accounts.clear_two_factor_settings(user)
params = %{"two_factor_code" => token}

IO.inspect(user, label: "%%%%%%%%%###################################user")
IO.inspect(settings, label: "%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@settings")

conn = post(conn, Routes.user_settings_path(conn, :two_factor_confirm), params)
assert redirected_to(conn) =~ "/two-factor"
assert Flash.get(conn.assigns.flash, :error) =~ "Two factor code is invalid"
end
end

describe "POST /users/settings/two-factor Email (confirm)" do
test "confirm take timeout genereated token with expire_time", %{conn: conn, user: user} do
settings = Accounts.generate_and_cache_new_two_factor_settings(user, :email)
Accounts.get_new_two_factor_settings(user)
IO.inspect(Accounts.get_new_two_factor_settings(user), label: "get_new_two_factor_settings")
IO.inspect(settings, label: "settings213")
expired_time = System.system_time(:second) - 901
conn = put_session(conn, :two_factor_issue_time, expired_time)
conn = put_session(conn, :two_factor_sent, true)

token = Authentication.generate_token(:email, expired_time, settings)
IO.inspect(token, label: "token")
params = %{"two_factor_code" => token}
IO.inspect(params, label: "params")
conn = post(conn, Routes.user_settings_path(conn, :two_factor_confirm), params)

assert redirected_to(conn) =~ "/two-factor"
Expand Down Expand Up @@ -269,19 +242,5 @@ defmodule RecognizerWeb.Accounts.UserSettingsControllerTest do

assert {:ok, nil} = Accounts.get_new_two_factor_settings(user)
end

test "confirm redirects without cached settings", %{conn: conn, user: user} do
current_time = System.system_time(:second)
conn = put_session(conn, :two_factor_issue_time, nil)
conn = put_session(conn, :two_factor_sent, false)

settings = Accounts.generate_and_cache_new_two_factor_settings(user, :email)
token = Authentication.generate_token(:app, 0, settings)
Accounts.clear_two_factor_settings(user)
params = %{"two_factor_code" => token}
conn = post(conn, Routes.user_settings_path(conn, :two_factor_confirm), params)
assert redirected_to(conn) =~ "/two-factor"
assert Flash.get(conn.assigns.flash, :error) =~ "Two factor code is invalid"
end
end
end

0 comments on commit 4c76b84

Please sign in to comment.