From 680a560c06f9542cd77b3708cfec4704c72cf218 Mon Sep 17 00:00:00 2001 From: Ryan Lue Date: Wed, 11 Jul 2018 17:01:54 +0800 Subject: [PATCH 1/2] Convert HttpLog request/response attrs to UTF8 before saving (fixes #2100) --- app/models/http_log.rb | 9 +++++++++ spec/factories/http_log.rb | 12 ++++++++++++ spec/models/http_log_spec.rb | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 spec/factories/http_log.rb create mode 100644 spec/models/http_log_spec.rb diff --git a/app/models/http_log.rb b/app/models/http_log.rb index 26474c812..51f29687e 100644 --- a/app/models/http_log.rb +++ b/app/models/http_log.rb @@ -4,6 +4,9 @@ class HttpLog < ApplicationModel store :request store :response + # See https://github.com/zammad/zammad/issues/2100 + before_save :messages_to_utf8 + =begin cleanup old http logs @@ -21,4 +24,10 @@ optional you can put the max oldest chat entries as argument true end + private + + def messages_to_utf8 + request.transform_values! { |v| v.try(:utf8_encode) || v } + response.transform_values! { |v| v.try(:utf8_encode) || v } + end end diff --git a/spec/factories/http_log.rb b/spec/factories/http_log.rb new file mode 100644 index 000000000..24ddee7ad --- /dev/null +++ b/spec/factories/http_log.rb @@ -0,0 +1,12 @@ +FactoryBot.define do + factory :http_log do + direction 'in' + facility 'cti' + add_attribute(:method) { 'post' } + url 'https://zammad.fqdn.com/api/v1/integration/cti/log' + request { { content: 'foo' } } + response { { content: 'bar' } } + created_by_id 1 + updated_by_id 1 + end +end diff --git a/spec/models/http_log_spec.rb b/spec/models/http_log_spec.rb new file mode 100644 index 000000000..3fff8aaa9 --- /dev/null +++ b/spec/models/http_log_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +RSpec.describe HttpLog do + let(:subject) { build(:http_log) } + + describe 'callbacks' do + # See https://github.com/zammad/zammad/issues/2100 + it 'converts request/response message data to UTF-8 before saving' do + subject.request[:content] = 'foo'.force_encoding('ascii-8bit') + subject.response[:content] = 'bar'.force_encoding('ascii-8bit') + + # rubocop:disable Layout/MultilineMethodCallIndentation + expect { subject.save } + .to change { subject.request[:content].encoding.name }.from('ASCII-8BIT').to('UTF-8') + .and change { subject.response[:content].encoding.name }.from('ASCII-8BIT').to('UTF-8') + # rubocop:enable Layout/MultilineMethodCallIndentation + end + end +end From f041fef7ff50083416827b7bc2f7f9697547f7ea Mon Sep 17 00:00:00 2001 From: Ryan Lue Date: Wed, 11 Jul 2018 17:01:54 +0800 Subject: [PATCH 2/2] Add migration to retroactively convert HttpLogs to UTF8 --- ...20180711080554_issue_2100_utf8_encode_http_logs.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 db/migrate/20180711080554_issue_2100_utf8_encode_http_logs.rb diff --git a/db/migrate/20180711080554_issue_2100_utf8_encode_http_logs.rb b/db/migrate/20180711080554_issue_2100_utf8_encode_http_logs.rb new file mode 100644 index 000000000..cb25522e3 --- /dev/null +++ b/db/migrate/20180711080554_issue_2100_utf8_encode_http_logs.rb @@ -0,0 +1,11 @@ +class Issue2100Utf8EncodeHttpLogs < ActiveRecord::Migration[5.1] + def up + HttpLog.where('request LIKE :enctag OR response LIKE :enctag', enctag: '%content: !binary |%') + .limit(100_000) + .order(created_at: :desc) + .find_each do |log| + log.update(request: log.request.transform_values(&:utf8_encode), + response: log.response.transform_values(&:utf8_encode)) + end + end +end