Commit 5c921809 authored by Ruben Davila's avatar Ruben Davila

Bugfix: Always use the default language when generating emails.

There was a race condition issue when the application was generating an
email and was using a language that was previously being used in other
request.
parent d07e85e1
...@@ -275,11 +275,7 @@ class ApplicationController < ActionController::Base ...@@ -275,11 +275,7 @@ class ApplicationController < ActionController::Base
request.base_url request.base_url
end end
def set_locale def set_locale(&block)
Gitlab::I18n.set_locale(current_user) Gitlab::I18n.with_user_locale(current_user, &block)
yield
ensure
Gitlab::I18n.reset_locale
end end
end end
class BaseMailer < ActionMailer::Base class BaseMailer < ActionMailer::Base
around_action :render_with_default_locale
helper ApplicationHelper helper ApplicationHelper
helper MarkupHelper helper MarkupHelper
...@@ -14,6 +16,10 @@ class BaseMailer < ActionMailer::Base ...@@ -14,6 +16,10 @@ class BaseMailer < ActionMailer::Base
private private
def render_with_default_locale(&block)
Gitlab::I18n.with_default_locale(&block)
end
def default_sender_address def default_sender_address
address = Mail::Address.new(Gitlab.config.gitlab.email_from) address = Mail::Address.new(Gitlab.config.gitlab.email_from)
address.display_name = Gitlab.config.gitlab.email_display_name address.display_name = Gitlab.config.gitlab.email_display_name
......
FastGettext.add_text_domain 'gitlab', path: File.join(Rails.root, 'locale'), type: :po FastGettext.add_text_domain 'gitlab', path: File.join(Rails.root, 'locale'), type: :po
FastGettext.default_text_domain = 'gitlab' FastGettext.default_text_domain = 'gitlab'
FastGettext.default_available_locales = Gitlab::I18n.available_locales FastGettext.default_available_locales = Gitlab::I18n.available_locales
FastGettext.default_locale = :en
I18n.available_locales = Gitlab::I18n.available_locales I18n.available_locales = Gitlab::I18n.available_locales
...@@ -45,9 +45,9 @@ module API ...@@ -45,9 +45,9 @@ module API
end end
before { allow_access_with_scope :api } before { allow_access_with_scope :api }
before { Gitlab::I18n.set_locale(current_user) } before { Gitlab::I18n.locale = current_user&.preferred_language }
after { Gitlab::I18n.reset_locale } after { Gitlab::I18n.use_default_locale }
rescue_from Gitlab::Access::AccessDeniedError do rescue_from Gitlab::Access::AccessDeniedError do
rack_response({ 'message' => '403 Forbidden' }.to_json, 403) rack_response({ 'message' => '403 Forbidden' }.to_json, 403)
......
...@@ -12,15 +12,36 @@ module Gitlab ...@@ -12,15 +12,36 @@ module Gitlab
AVAILABLE_LANGUAGES.keys AVAILABLE_LANGUAGES.keys
end end
def set_locale(current_user) def locale
requested_locale = current_user&.preferred_language || ::I18n.default_locale FastGettext.locale
locale = FastGettext.set_locale(requested_locale)
::I18n.locale = locale
end end
def reset_locale def locale=(locale_string)
requested_locale = locale_string || ::I18n.default_locale
new_locale = FastGettext.set_locale(requested_locale)
::I18n.locale = new_locale
end
def use_default_locale
FastGettext.set_locale(::I18n.default_locale) FastGettext.set_locale(::I18n.default_locale)
::I18n.locale = ::I18n.default_locale ::I18n.locale = ::I18n.default_locale
end end
def with_locale(locale_string)
original_locale = locale
self.locale = locale_string
yield
ensure
self.locale = original_locale
end
def with_user_locale(user, &block)
with_locale(user&.preferred_language, &block)
end
def with_default_locale(&block)
with_locale(::I18n.default_locale, &block)
end
end end
end end
require 'spec_helper' require 'spec_helper'
module Gitlab describe Gitlab::I18n, lib: true do
describe I18n, lib: true do let(:user) { create(:user, preferred_language: 'es') }
let(:user) { create(:user, preferred_language: 'es') }
describe '.set_locale' do describe '.locale=' do
it 'sets the locale based on current user preferred language' do after { described_class.use_default_locale }
Gitlab::I18n.set_locale(user)
expect(FastGettext.locale).to eq('es') it 'sets the locale based on current user preferred language' do
expect(::I18n.locale).to eq(:es) described_class.locale = user.preferred_language
end
expect(FastGettext.locale).to eq('es')
expect(::I18n.locale).to eq(:es)
end end
end
describe '.reset_locale' do describe '.use_default_locale' do
it 'resets the locale to the default language' do it 'resets the locale to the default language' do
Gitlab::I18n.set_locale(user) described_class.locale = user.preferred_language
Gitlab::I18n.reset_locale described_class.use_default_locale
expect(FastGettext.locale).to eq('en') expect(FastGettext.locale).to eq('en')
expect(::I18n.locale).to eq(:en) expect(::I18n.locale).to eq(:en)
end
end end
end end
end end
...@@ -128,6 +128,15 @@ describe Notify do ...@@ -128,6 +128,15 @@ describe Notify do
is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue)) is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
end end
end end
context 'with a preferred language' do
before { Gitlab::I18n.locale = :es }
after { Gitlab::I18n.use_default_locale }
it 'always generates the email using the default language' do
is_expected.to have_body_text('foo, bar, and baz')
end
end
end end
describe 'status changed' do describe 'status changed' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment