From b6ae957ac2d01e866ccc6e4181d3c0ad6c623a70 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Fri, 28 Aug 2020 11:41:38 +0200 Subject: [PATCH] Fixes #3167: Active Google channels cause Email channels to loose email addresses. --- app/models/channel.rb | 10 +++++++++- spec/requests/integration/gmail_spec.rb | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/models/channel.rb b/app/models/channel.rb index 1dade53bc..7f91cfeca 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -346,7 +346,15 @@ get instance of channel driver options[:inbound][:options][:password] = result[:access_token] options[:outbound][:options][:password] = result[:access_token] - save! + return if new_record? + + # ATTENTION: We don't want to execute any other callbacks here + # because `after_initialize` leaks the current scope of the Channel class + # as described here: https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-new + # which leads to unexpected effects like: + # Channel.where(area: 'Google::Account').limit(1).find_each { |c| puts Channel.all.to_sql } + # => "SELECT "channels".* FROM "channels" WHERE "channels"."area" = 'Google::Account'" + update_column(:options, options) # rubocop:disable Rails/SkipsModelValidations rescue => e logger.error e raise "Failed to refresh XOAUTH2 access_token of provider '#{options[:auth][:provider]}'! #{e.inspect}" diff --git a/spec/requests/integration/gmail_spec.rb b/spec/requests/integration/gmail_spec.rb index b98685814..ddf61acf3 100644 --- a/spec/requests/integration/gmail_spec.rb +++ b/spec/requests/integration/gmail_spec.rb @@ -62,4 +62,17 @@ RSpec.describe 'Gmail XOAUTH2' do # rubocop:disable RSpec/DescribeClass expect(result[:result]).to eq('ok') end end + + context 'when non-Google channels are present' do + + let!(:email_address) { create(:email_address, channel: create(:channel, area: 'Some::Other')) } + + before do + channel + end + + it "doesn't remove email address assignments" do + expect { Channel.where(area: 'Google::Account').find_each {} }.not_to change { email_address.reload.channel_id } + end + end end