Files
firezone/elixir/apps/api/lib/api/client/socket.ex
Andrew Dryga a211f96109 feat(portal): Broadcast state changes to connected clients and gateways (#2240)
# Gateways
- [x] When Gateway Group is deleted all gateways should be disconnected
- [x] When Gateway Group is updated (eg. routing) broadcast to all
affected gateway to disconnect all the clients
- [x] When Gateway is deleted it should be disconnected
- [x] When Gateway Token is revoked all gateways that use it should be
disconnected

# Relays
- [x] When Relay Group is deleted all relays should be disconnected
- [x] When Relay is deleted it should be disconnected
- [x] When Relay Token is revoked all gateways that use it should be
disconnected

# Clients
- [x] Remove Delete Client button, show clients using the token on the
Actors page (#2669)
- [x] When client is deleted disconnect it
- [ ] ~When Gateway is offline broadcast to the Clients connected to it
it's status~
- [x] Persist `last_used_token_id` in Clients and show it in tokens UI

# Resources
- [x] When Resource is deleted it should be removed from all gateways
and clients
- [x] When Resource connection is removed it should be deleted from
removed gateway groups
- [x] When Resource is updated (eg. traffic filters) all it's
authorizations should removed

# Authentication
- [x] When Token is deleted related sessions are terminated
- [x] When an Actor is deleted or disabled it should be disconnected
from browser and client
- [x] When Identity is deleted it's sessions should be disconnected from
browser and client
- [x] ^ Ensure the same happens for identities during IdP sync
- [x] When IdP is disabled act like all actors for it are disabled?
- [x] When IdP is deleted act like all actors for it are deleted?

# Authorization
- [x] When Policy is created clients that gain access to a resource
should get an update
- [x] When Policy is deleted we need to all authorizations it's made
- [x] When Policy is disabled we need to all authorizations it's made
- [x] When Actor Group adds or removes a user, related policies should
be re-evaluated
- [x] ^ Ensure the same happens for identities during IdP sync

# Settings
- [x] Re-send init message to Client when DNS settings change

# Code
- [x] Crear way to see all available topics and messages, do not use
binary topics any more

---------

Co-authored-by: conectado <gabrielalejandro7@gmail.com>
2024-02-01 11:02:13 -06:00

59 lines
1.8 KiB
Elixir

defmodule API.Client.Socket do
use Phoenix.Socket
alias Domain.{Auth, Tokens, Clients}
require Logger
require OpenTelemetry.Tracer
## Channels
channel "client", API.Client.Channel
## Authentication
@impl true
def connect(%{"token" => token} = attrs, socket, connect_info) do
:otel_propagator_text_map.extract(connect_info.trace_context_headers)
OpenTelemetry.Tracer.with_span "client.connect" do
context = API.Sockets.auth_context(connect_info, :client)
with {:ok, subject} <- Auth.authenticate(token, context),
{:ok, client} <- Clients.upsert_client(attrs, subject) do
OpenTelemetry.Tracer.set_attributes(%{
token_id: subject.token_id,
client_id: client.id,
lat: client.last_seen_remote_ip_location_lat,
lon: client.last_seen_remote_ip_location_lon,
version: client.last_seen_version,
account_id: subject.account.id
})
socket =
socket
|> assign(:subject, subject)
|> assign(:client, client)
|> assign(:opentelemetry_span_ctx, OpenTelemetry.Tracer.current_span_ctx())
|> assign(:opentelemetry_ctx, OpenTelemetry.Ctx.get_current())
{:ok, socket}
else
{:error, :unauthorized} ->
OpenTelemetry.Tracer.set_status(:error, "unauthorized")
{:error, :invalid_token}
{:error, reason} ->
OpenTelemetry.Tracer.set_status(:error, inspect(reason))
Logger.debug("Error connecting client websocket: #{inspect(reason)}")
{:error, reason}
end
end
end
def connect(_params, _socket, _connect_info) do
{:error, :missing_token}
end
@impl true
def id(socket), do: Tokens.socket_id(socket.assigns.subject.token_id)
end