Skip to content

Commit

Permalink
fixup! Allow the application to configure Turbo::StreamChannel’s inhe…
Browse files Browse the repository at this point in the history
…ritance

`ApplicationCable::Connection` allows the application to apply
authentication to all streams method, including those from
`Turbo::Broadcastable`.

By allowing `Turbo::StreamsChannel` to inherit from
`ApplicationCable::Channel` we open up a symmetrical path for
authorization.

In the spirit of being secure by default we should be moving towards
making `Turbo.base_stream_channel_class` default to
`"ApplicationCable::Channel"` but doing so without warning would break
applications relying on `ApplicationCable::Connection#authorized?` for
non-turbo broadcastable streams only.

Once we deem it safe we can remove the awkward initialiser and hard code
`ApplicationCable::Channel` as the super class. If people needs
different super classes for `Turbo::StreamsChannel` and custom channels
they can simply add another super class to inherit from in their
application.


To-dos:
- [ ] Generate the initializer on rails new
- [ ] Add a commented out method in the rails new / channel generator 
      to encourage authorization.
- [ ] Decide on a roll out plan for making inheriting from
      `ApplicationCable::Channel` the default.
  • Loading branch information
ramhoj committed Oct 22, 2024
1 parent 7de73e2 commit 4cf8a7a
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 20 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ In multi-tenancy apps it's often important to authorize your subscriptions:
config.turbo.base_stream_channel_class = "ApplicationCable::Channel"
```

You can now implement your domain authorization:
You can now implement your domain authorization which will be used by `Turbo::StreamsChannel` and any other Channel inheriting from `ApplicationCable::Channel`:

```rb
# app/channels/application_cable/channel.rb
Expand Down
11 changes: 4 additions & 7 deletions app/channels/turbo/streams_channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
# If the signed stream name cannot be verified, the subscription is rejected.
#
# It's important to understand that while stream names are signed, <tt>Turbo::StreamsChannel</tt> doesn't authenticate connections or
# authorize subscriptions. You can configure <tt>Turbo::StreamChannel</tt> to use e.g your <tt>ApplicationCable::Channel</tt> to
# implement authorization:
# authorize subscriptions. You can configure <tt>Turbo::StreamsChannel</tt> to use e.g your <tt>ApplicationCable::Channel</tt> to
# implement authorization in your config/application.rb:
#
# # config/initializers/turbo.rb
# Rails.application.config.to_prepare do
# Turbo.base_stream_channel_class = "ApplicationCable::Channel"
# end
# config.turbo.base_stream_channel_class = "ApplicationCable::Channel"
#
# You can also choose which channel to use via:
# <%= turbo_stream_from "room", channel: CustomChannel %>
# <%= turbo_stream_from "room", channel: CustomChannel %>
#
# Note that any channel that listens to a <tt>Turbo::Broadcastable</tt> compatible stream name
# (e.g <tt>verified_stream_name_from_params</tt>) can also be subscribed to via <tt>Turbo::StreamsChannel</tt>. Meaning that you should
Expand Down
1 change: 0 additions & 1 deletion lib/turbo-rails.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require "turbo/engine"
require "turbo/railtie"
require "active_support/core_ext/module/attribute_accessors_per_thread"

module Turbo
Expand Down
6 changes: 6 additions & 0 deletions lib/turbo/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ class Engine < Rails::Engine
end
end

initializer "turbo.configure" do |app|
if base_class = app.config.turbo&.base_stream_channel_class
Turbo.base_stream_channel_class = base_class
end
end

initializer "turbo.helpers", before: :load_config_initializers do
ActiveSupport.on_load(:action_controller_base) do
include Turbo::Streams::TurboStreamsTagBuilder, Turbo::Frames::FrameRequest, Turbo::Native::Navigation
Expand Down
11 changes: 0 additions & 11 deletions lib/turbo/railtie.rb

This file was deleted.

0 comments on commit 4cf8a7a

Please sign in to comment.