totp debugging
This commit is contained in:
parent
27c8a2324a
commit
fd4f8b2342
3 changed files with 84 additions and 33 deletions
|
|
@ -196,13 +196,29 @@ defmodule Towerops.Accounts do
|
|||
Verifies a TOTP code against a secret.
|
||||
|
||||
Returns true if the code is valid within the time window, false otherwise.
|
||||
Allows for +/- 1 time step (30 seconds) to handle clock drift.
|
||||
Allows for +/- 4 time steps (120 seconds / 2 minutes) to handle clock drift.
|
||||
"""
|
||||
def verify_totp(secret, code) when is_binary(secret) and is_binary(code) do
|
||||
current_time = System.system_time(:second)
|
||||
|
||||
# NimbleTOTP.valid? by default checks current time +/- 1 time step (30s)
|
||||
result = NimbleTOTP.valid?(secret, code)
|
||||
# Check multiple time windows to handle clock drift
|
||||
# Check ±4 time steps (±120 seconds / 2 minutes)
|
||||
time_windows = [
|
||||
current_time,
|
||||
current_time - 30,
|
||||
current_time + 30,
|
||||
current_time - 60,
|
||||
current_time + 60,
|
||||
current_time - 90,
|
||||
current_time + 90,
|
||||
current_time - 120,
|
||||
current_time + 120
|
||||
]
|
||||
|
||||
result =
|
||||
Enum.any?(time_windows, fn time ->
|
||||
NimbleTOTP.valid?(secret, code, time: time)
|
||||
end)
|
||||
|
||||
if !result do
|
||||
require Logger
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
|
||||
@impl true
|
||||
def handle_params(%{"id" => id} = params, _, socket) do
|
||||
# Check if device exists before setting up subscriptions
|
||||
organization = socket.assigns.current_organization
|
||||
|
||||
# Check if device exists and verify organization access
|
||||
case Devices.get_device(id) do
|
||||
nil ->
|
||||
{:noreply,
|
||||
|
|
@ -49,19 +51,29 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
|||
|> put_flash(:error, "Device not found")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
|
||||
_device ->
|
||||
_ =
|
||||
if connected?(socket) do
|
||||
_ = Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{id}")
|
||||
Process.send_after(self(), :refresh_data, 10_000)
|
||||
end
|
||||
device ->
|
||||
# Preload site and organization to check access
|
||||
device = Repo.preload(device, site: :organization)
|
||||
|
||||
tab = Map.get(params, "tab", "overview")
|
||||
if device.site.organization_id == organization.id do
|
||||
_ =
|
||||
if connected?(socket) do
|
||||
_ = Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{id}")
|
||||
Process.send_after(self(), :refresh_data, 10_000)
|
||||
end
|
||||
|
||||
socket
|
||||
|> load_equipment_data(id)
|
||||
|> assign(:active_tab, tab)
|
||||
|> then(&{:noreply, &1})
|
||||
tab = Map.get(params, "tab", "overview")
|
||||
|
||||
socket
|
||||
|> load_equipment_data(id)
|
||||
|> assign(:active_tab, tab)
|
||||
|> then(&{:noreply, &1})
|
||||
else
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "You don't have access to this device")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Monitoring
|
||||
alias Towerops.Repo
|
||||
alias Towerops.Snmp
|
||||
|
||||
@impl true
|
||||
|
|
@ -13,27 +14,49 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
|
||||
@impl true
|
||||
def handle_params(%{"id" => device_id, "sensor_type" => sensor_type} = params, _, socket) do
|
||||
_ =
|
||||
if connected?(socket) do
|
||||
Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device_id}")
|
||||
end
|
||||
organization = socket.assigns.current_organization
|
||||
|
||||
range = Map.get(params, "range", "24h")
|
||||
interface_id = Map.get(params, "interface_id")
|
||||
sensor_id = Map.get(params, "sensor_id")
|
||||
storage_id = Map.get(params, "storage_id")
|
||||
# Verify device exists and user has access
|
||||
case Devices.get_device(device_id) do
|
||||
nil ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "Device not found")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:device_id, device_id)
|
||||
|> assign(:sensor_type, sensor_type)
|
||||
|> assign(:range, range)
|
||||
|> assign(:interface_id, interface_id)
|
||||
|> assign(:sensor_id, sensor_id)
|
||||
|> assign(:storage_id, storage_id)
|
||||
|> load_graph_data()
|
||||
device ->
|
||||
# Preload site and organization to check access
|
||||
device = Repo.preload(device, site: :organization)
|
||||
|
||||
{:noreply, socket}
|
||||
if device.site.organization_id == organization.id do
|
||||
_ =
|
||||
if connected?(socket) do
|
||||
Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device_id}")
|
||||
end
|
||||
|
||||
range = Map.get(params, "range", "24h")
|
||||
interface_id = Map.get(params, "interface_id")
|
||||
sensor_id = Map.get(params, "sensor_id")
|
||||
storage_id = Map.get(params, "storage_id")
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:device_id, device_id)
|
||||
|> assign(:sensor_type, sensor_type)
|
||||
|> assign(:range, range)
|
||||
|> assign(:interface_id, interface_id)
|
||||
|> assign(:sensor_id, sensor_id)
|
||||
|> assign(:storage_id, storage_id)
|
||||
|> load_graph_data()
|
||||
|
||||
{:noreply, socket}
|
||||
else
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "You don't have access to this device")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue