mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
feat(portal): send account_slug in gateway init (#9653)
Adds the `account_slug` to the gateway's `init` message. When the account slug is changed, the gateway's socket is disconnected using the same mechanism as gateway deletion, which causes the gateway to reconnect immediately and receive a new `init`. Related: #9545
This commit is contained in:
@@ -48,7 +48,10 @@ defmodule API.Gateway.Channel do
|
||||
:ok = Enum.each(relays, &Domain.Relays.subscribe_to_relay_presence/1)
|
||||
:ok = maybe_subscribe_for_relays_presence(relays, socket)
|
||||
|
||||
account = Domain.Accounts.fetch_account_by_id!(socket.assigns.gateway.account_id)
|
||||
|
||||
push(socket, "init", %{
|
||||
account_slug: account.slug,
|
||||
interface: Views.Interface.render(socket.assigns.gateway),
|
||||
relays: Views.Relay.render_many(relays, relay_credentials_expire_at),
|
||||
config: %{
|
||||
|
||||
@@ -58,17 +58,23 @@ defmodule API.Gateway.ChannelTest do
|
||||
assert is_number(online_at)
|
||||
end
|
||||
|
||||
test "sends list of resources after join", %{
|
||||
test "sends init message after join", %{
|
||||
account: account,
|
||||
gateway: gateway
|
||||
} do
|
||||
assert_push "init", %{
|
||||
account_slug: account_slug,
|
||||
interface: interface,
|
||||
relays: relays,
|
||||
config: %{
|
||||
ipv4_masquerade_enabled: true,
|
||||
ipv6_masquerade_enabled: true
|
||||
}
|
||||
}
|
||||
|
||||
assert account_slug == account.slug
|
||||
assert relays == []
|
||||
|
||||
assert interface == %{
|
||||
ipv4: gateway.ipv4,
|
||||
ipv6: gateway.ipv6
|
||||
|
||||
@@ -6,6 +6,17 @@ defmodule Domain.Events.Hooks.Accounts do
|
||||
@impl true
|
||||
def on_insert(_data), do: :ok
|
||||
|
||||
# Account slug changed - disconnect gateways for updated init
|
||||
|
||||
@impl true
|
||||
def on_update(%{"slug" => old_slug}, %{"slug" => slug, "id" => account_id} = _data)
|
||||
when old_slug != slug do
|
||||
# Technically we could push a :slug_changed message to the Gateways here,
|
||||
# but at the time of writing, disconnecting and reconnecting is safer to ensure
|
||||
# all relevant state on the Gateway is updated correctly.
|
||||
PubSub.Account.Gateways.disconnect(account_id)
|
||||
end
|
||||
|
||||
# Account disabled - disconnect clients
|
||||
@impl true
|
||||
def on_update(
|
||||
|
||||
@@ -10,6 +10,7 @@ defmodule Domain.Gateways.Presence do
|
||||
with {:ok, _} <- __MODULE__.Group.track(gateway.group_id, gateway.id),
|
||||
{:ok, _} <- __MODULE__.Account.track(gateway.account_id, gateway.id) do
|
||||
:ok = PubSub.Gateway.subscribe(gateway.id)
|
||||
:ok = PubSub.Account.Gateways.subscribe(gateway.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -84,6 +84,24 @@ defmodule Domain.PubSub do
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Gateways do
|
||||
def subscribe(account_id) do
|
||||
account_id
|
||||
|> topic()
|
||||
|> Domain.PubSub.subscribe()
|
||||
end
|
||||
|
||||
def disconnect(account_id) do
|
||||
account_id
|
||||
|> topic()
|
||||
|> Domain.PubSub.broadcast("disconnect")
|
||||
end
|
||||
|
||||
defp topic(account_id) do
|
||||
Atom.to_string(__MODULE__) <> ":" <> account_id
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Policies do
|
||||
def subscribe(account_id) do
|
||||
account_id
|
||||
|
||||
@@ -13,10 +13,25 @@ defmodule Domain.Events.Hooks.AccountsTest do
|
||||
end
|
||||
|
||||
describe "update/2" do
|
||||
test "disconnects gateways if slug changes" do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
gateway = Fixtures.Gateways.create_gateway(account: account)
|
||||
:ok = Domain.Gateways.Presence.connect(gateway)
|
||||
|
||||
old_data = %{"slug" => "old"}
|
||||
data = %{"slug" => "new", "id" => account.id}
|
||||
|
||||
assert :ok == on_update(old_data, data)
|
||||
|
||||
assert_receive "disconnect"
|
||||
end
|
||||
|
||||
test "sends :config_changed if config changes" do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
gateway = Fixtures.Gateways.create_gateway(account: account)
|
||||
|
||||
:ok = Domain.PubSub.Account.subscribe(account.id)
|
||||
:ok = Domain.Gateways.Presence.connect(gateway)
|
||||
|
||||
old_data = %{
|
||||
"id" => account.id,
|
||||
@@ -33,6 +48,7 @@ defmodule Domain.Events.Hooks.AccountsTest do
|
||||
|
||||
assert :ok == on_update(old_data, data)
|
||||
assert_receive :config_changed
|
||||
refute_receive "disconnect"
|
||||
end
|
||||
|
||||
test "does not send :config_changed if config does not change" do
|
||||
|
||||
Reference in New Issue
Block a user