Module: Mbeditor::ChannelAuthentication
- Included in:
- CollaborationChannel, EditorChannel
- Defined in:
- app/channels/mbeditor/channel_authentication.rb
Overview
Runs the configured authenticate_with hook on the WebSocket handshake (at
channel subscribe) and rejects the subscription when it denies. This is the
same proc the engine runs as a controller before_action; on the cable side
there is no controller, so it is evaluated against a probe that mirrors the
surface the hook relies on (session, cookies, redirect_to/render/
head). A hook that halts — or raises — denies the socket (fail-closed).
The probe reads cookies/session from the upgrade request env when available; because the cable mount can bypass host middleware, hooks that depend on request-scoped state may see less than they do over HTTP. Restricting network exposure (trusted tunnel / LAN) and securing the host's ActionCable connection remain the primary controls — see the README pairing section.
Defined Under Namespace
Classes: AuthProbe
Instance Method Summary collapse
-
#mbeditor_auth_hook ⇒ Object
cable_authenticate_withwhen set, otherwise the HTTP hook. -
#mbeditor_authenticated? ⇒ Boolean
True when the connection is allowed (or no hook is configured); otherwise rejects the subscription and returns false.
- #mbeditor_log_denial(reason) ⇒ Object
Instance Method Details
#mbeditor_auth_hook ⇒ Object
cable_authenticate_with when set, otherwise the HTTP hook. A hook that
depends on controller filters cannot work here at all, and asking people to
write one proc that straddles both contexts is worse than letting them
supply the cable one explicitly.
48 49 50 51 |
# File 'app/channels/mbeditor/channel_authentication.rb', line 48 def mbeditor_auth_hook Mbeditor.configuration.cable_authenticate_with || Mbeditor.configuration.authenticate_with end |
#mbeditor_authenticated? ⇒ Boolean
True when the connection is allowed (or no hook is configured); otherwise rejects the subscription and returns false.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'app/channels/mbeditor/channel_authentication.rb', line 21 def mbeditor_authenticated? hook = mbeditor_auth_hook return true unless hook probe = AuthProbe.new(mbeditor_connection_env) probe.instance_exec(&hook) return true unless probe.denied? # Both denial paths used to be completely silent, which is what makes this # so hard to diagnose: pairing simply never works and nothing anywhere says # why. The commonest cause is a hook that reads state a controller filter # populates — Current.user, an Authlogic session — because a WebSocket # subscribe runs no controller, so that state is nil or raises here while # working perfectly over HTTP. mbeditor_log_denial("the authenticate_with hook denied the connection") mbeditor_reject_subscription false rescue StandardError => e mbeditor_log_denial("the authenticate_with hook raised #{e.class}: #{e.}") mbeditor_reject_subscription false end |
#mbeditor_log_denial(reason) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 |
# File 'app/channels/mbeditor/channel_authentication.rb', line 53 def mbeditor_log_denial(reason) Rails.logger&.warn( "[mbeditor] WebSocket subscription rejected: #{reason}. " \ "Realtime collaboration will not work. A WebSocket subscribe runs no " \ "controller, so Current.*, Authlogic sessions and other request-scoped " \ "state set by before_actions are unavailable here — resolve the user " \ "from `session` instead, or set config.cable_authenticate_with." ) rescue StandardError # Logging must never be the thing that breaks the socket. end |