diff --git a/app/controllers/concerns/identifiable.rb b/app/controllers/concerns/identifiable.rb index 047f26c71..6cfe879c0 100644 --- a/app/controllers/concerns/identifiable.rb +++ b/app/controllers/concerns/identifiable.rb @@ -9,8 +9,10 @@ module Identifiable end def load_current_user - token = request.headers['Authorization'] - return if token.blank? + header = request.headers['Authorization']&.strip + return if header.blank? + + token = extract_token(header) @current_user = User.from_token(token:) return if @current_user.blank? @@ -19,4 +21,8 @@ def load_current_user RequestStore.store[:safeguarding_flag_users_by_token] ||= {} RequestStore.store[:safeguarding_flag_users_by_token][token] = @current_user end + + def extract_token(header) + header.sub(/^Bearer\s+/i, '') + end end diff --git a/spec/controllers/concerns/identifiable_spec.rb b/spec/controllers/concerns/identifiable_spec.rb new file mode 100644 index 000000000..a9487242d --- /dev/null +++ b/spec/controllers/concerns/identifiable_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Identifiable do + subject(:extract_token) { identifiable.extract_token(header) } + + let(:identifiable) { Class.new(ActionController::API) { include Identifiable }.new } + + context 'when the header is a raw token' do + let(:header) { 'secret-token' } + + it { is_expected.to eq('secret-token') } + end + + context 'when the header is Bearer-prefixed' do + let(:header) { 'Bearer secret-token' } + + it { is_expected.to eq('secret-token') } + end + + context 'when the header uses a lowercase bearer prefix' do + let(:header) { 'bearer secret-token' } + + it { is_expected.to eq('secret-token') } + end + + context 'when the header is Bearer with no token' do + let(:header) { 'Bearer ' } + + it { is_expected.to eq('') } + end +end