From c0057a9d2ffe8d73d5bf0cf8ef7024f4f6352716 Mon Sep 17 00:00:00 2001
From: Pavel Shutsin <pshutsin@gitlab.com>
Date: Tue, 28 Nov 2023 18:05:21 +0100
Subject: [PATCH] Add bearer authorization to ActionCable

It can be used for API access when
session is not available
---
 app/channels/application_cable/connection.rb       |  3 ++-
 spec/channels/application_cable/connection_spec.rb | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb
index bdd9d00ca7f0d..0bb9ed2fe2f04 100644
--- a/app/channels/application_cable/connection.rb
+++ b/app/channels/application_cable/connection.rb
@@ -3,13 +3,14 @@
 module ApplicationCable
   class Connection < ActionCable::Connection::Base
     include Logging
+    include Gitlab::Auth::AuthFinders
 
     identified_by :current_user
 
     public :request
 
     def connect
-      self.current_user = find_user_from_session_store
+      self.current_user = find_user_from_bearer_token || find_user_from_session_store
     end
 
     private
diff --git a/spec/channels/application_cable/connection_spec.rb b/spec/channels/application_cable/connection_spec.rb
index 4943669bde034..fa2518e19706f 100644
--- a/spec/channels/application_cable/connection_spec.rb
+++ b/spec/channels/application_cable/connection_spec.rb
@@ -43,6 +43,16 @@
     end
   end
 
+  context 'when bearer header is provided' do
+    let(:user_pat) { create(:personal_access_token) }
+
+    it 'finds user by PAT' do
+      connect(ActionCable.server.config.mount_path, headers: { Authorization: "Bearer #{user_pat.token}" })
+
+      expect(connection.current_user).to eq(user_pat.user)
+    end
+  end
+
   context 'when session cookie is not set' do
     it 'sets current_user to nil' do
       connect
-- 
GitLab