mirror of
https://github.com/meineerde/redmine.git
synced 2025-12-19 15:01:14 +00:00
Security notifications when password or email adress is changed (#21421).
Patch by Jan Schulz-Hofen. git-svn-id: http://svn.redmine.org/redmine/trunk@15145 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
40e6a74d48
commit
5d70fce6ce
@ -73,6 +73,12 @@ class AccountController < ApplicationController
|
|||||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||||
if @user.save
|
if @user.save
|
||||||
@token.destroy
|
@token.destroy
|
||||||
|
Mailer.security_notification(@user,
|
||||||
|
message: :mail_body_security_notification_change,
|
||||||
|
field: :field_password,
|
||||||
|
title: :button_change_password,
|
||||||
|
url: {controller: 'my', action: 'password'}
|
||||||
|
).deliver
|
||||||
flash[:notice] = l(:notice_account_password_updated)
|
flash[:notice] = l(:notice_account_password_updated)
|
||||||
redirect_to signin_path
|
redirect_to signin_path
|
||||||
return
|
return
|
||||||
|
|||||||
@ -133,6 +133,8 @@ class ApplicationController < ActionController::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
# store current ip address in user object ephemerally
|
||||||
|
user.remote_ip = request.remote_ip if user
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -105,6 +105,12 @@ class MyController < ApplicationController
|
|||||||
if @user.save
|
if @user.save
|
||||||
# The session token was destroyed by the password change, generate a new one
|
# The session token was destroyed by the password change, generate a new one
|
||||||
session[:tk] = @user.generate_session_token
|
session[:tk] = @user.generate_session_token
|
||||||
|
Mailer.security_notification(@user,
|
||||||
|
message: :mail_body_security_notification_change,
|
||||||
|
field: :field_password,
|
||||||
|
title: :button_change_password,
|
||||||
|
url: {controller: 'my', action: 'password'}
|
||||||
|
).deliver
|
||||||
flash[:notice] = l(:notice_account_password_updated)
|
flash[:notice] = l(:notice_account_password_updated)
|
||||||
redirect_to my_account_path
|
redirect_to my_account_path
|
||||||
end
|
end
|
||||||
|
|||||||
@ -19,8 +19,9 @@ class EmailAddress < ActiveRecord::Base
|
|||||||
belongs_to :user
|
belongs_to :user
|
||||||
attr_protected :id
|
attr_protected :id
|
||||||
|
|
||||||
after_update :destroy_tokens
|
after_create :deliver_security_notification_create
|
||||||
after_destroy :destroy_tokens
|
after_update :destroy_tokens, :deliver_security_notification_update
|
||||||
|
after_destroy :destroy_tokens, :deliver_security_notification_destroy
|
||||||
|
|
||||||
validates_presence_of :address
|
validates_presence_of :address
|
||||||
validates_format_of :address, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
|
validates_format_of :address, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
|
||||||
@ -42,6 +43,58 @@ class EmailAddress < ActiveRecord::Base
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# send a security notification to user that a new email address was added
|
||||||
|
def deliver_security_notification_create
|
||||||
|
# only deliver if this isn't the only address.
|
||||||
|
# in that case, the user is just being created and
|
||||||
|
# should not receive this email.
|
||||||
|
if user.mails != [address]
|
||||||
|
deliver_security_notification(user,
|
||||||
|
message: :mail_body_security_notification_add,
|
||||||
|
field: :field_mail,
|
||||||
|
value: address
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# send a security notification to user that an email has been changed (notified/not notified)
|
||||||
|
def deliver_security_notification_update
|
||||||
|
if address_changed?
|
||||||
|
recipients = [user, address_was]
|
||||||
|
options = {
|
||||||
|
message: :mail_body_security_notification_change_to,
|
||||||
|
field: :field_mail,
|
||||||
|
value: address
|
||||||
|
}
|
||||||
|
elsif notify_changed?
|
||||||
|
recipients = [user, address]
|
||||||
|
options = {
|
||||||
|
message: notify_was ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
|
||||||
|
value: address
|
||||||
|
}
|
||||||
|
end
|
||||||
|
deliver_security_notification(recipients, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
# send a security notification to user that an email address was deleted
|
||||||
|
def deliver_security_notification_destroy
|
||||||
|
deliver_security_notification([user, address],
|
||||||
|
message: :mail_body_security_notification_remove,
|
||||||
|
field: :field_mail,
|
||||||
|
value: address
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# generic method to send security notifications for email addresses
|
||||||
|
def deliver_security_notification(recipients, options={})
|
||||||
|
Mailer.security_notification(recipients,
|
||||||
|
options.merge(
|
||||||
|
title: :label_my_account,
|
||||||
|
url: {controller: 'my', action: 'account'}
|
||||||
|
)
|
||||||
|
).deliver
|
||||||
|
end
|
||||||
|
|
||||||
# Delete all outstanding password reset tokens on email change.
|
# Delete all outstanding password reset tokens on email change.
|
||||||
# This helps to keep the account secure in case the associated email account
|
# This helps to keep the account secure in case the associated email account
|
||||||
# was compromised.
|
# was compromised.
|
||||||
|
|||||||
@ -318,6 +318,20 @@ class Mailer < ActionMailer::Base
|
|||||||
:subject => l(:mail_subject_register, Setting.app_title)
|
:subject => l(:mail_subject_register, Setting.app_title)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def security_notification(recipients, options={})
|
||||||
|
redmine_headers 'Sender' => User.current.login
|
||||||
|
@user = Array(recipients).detect{|r| r.is_a? User }
|
||||||
|
set_language_if_valid(@user.try :language)
|
||||||
|
@message = l(options[:message],
|
||||||
|
field: (options[:field] && l(options[:field])),
|
||||||
|
value: options[:value]
|
||||||
|
)
|
||||||
|
@title = options[:title] && l(options[:title])
|
||||||
|
@url = options[:url] && (options[:url].is_a?(Hash) ? url_for(options[:url]) : options[:url])
|
||||||
|
mail :to => recipients,
|
||||||
|
:subject => l(:mail_subject_security_notification)
|
||||||
|
end
|
||||||
|
|
||||||
def test_email(user)
|
def test_email(user)
|
||||||
set_language_if_valid(user.language)
|
set_language_if_valid(user.language)
|
||||||
@url = url_for(:controller => 'welcome')
|
@url = url_for(:controller => 'welcome')
|
||||||
|
|||||||
@ -97,6 +97,8 @@ class User < Principal
|
|||||||
|
|
||||||
attr_accessor :password, :password_confirmation, :generate_password
|
attr_accessor :password, :password_confirmation, :generate_password
|
||||||
attr_accessor :last_before_login_on
|
attr_accessor :last_before_login_on
|
||||||
|
attr_accessor :remote_ip
|
||||||
|
|
||||||
# Prevents unauthorized assignments
|
# Prevents unauthorized assignments
|
||||||
attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
|
attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
|
||||||
|
|
||||||
|
|||||||
13
app/views/mailer/security_notification.html.erb
Normal file
13
app/views/mailer/security_notification.html.erb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<p><%= @message %><br />
|
||||||
|
<% if @url && @title -%>
|
||||||
|
<%= link_to @title, @url -%>
|
||||||
|
<% elsif @url -%>
|
||||||
|
<%= link_to @url -%>
|
||||||
|
<% elsif @title -%>
|
||||||
|
<%= content_tag :h1, @title -%>
|
||||||
|
<% end %></p>
|
||||||
|
|
||||||
|
<p><%= l(:field_user) %>: <strong><%= User.current.login %></strong><br/>
|
||||||
|
<%= l(:field_remote_ip) %>: <strong><%= User.current.remote_ip %></strong><br/>
|
||||||
|
<%= l(:label_date) %>: <strong><%= format_time Time.now, true, @user %></strong></p>
|
||||||
|
|
||||||
8
app/views/mailer/security_notification.text.erb
Normal file
8
app/views/mailer/security_notification.text.erb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<%= @message %>
|
||||||
|
|
||||||
|
<%= @url || @title %>
|
||||||
|
|
||||||
|
<%= l(:field_user) %>: <%= User.current.login %>
|
||||||
|
<%= l(:field_remote_ip) %>: <%= User.current.remote_ip %>
|
||||||
|
<%= l(:label_date) %>: <%= format_time Time.now, true, @user %>
|
||||||
|
|
||||||
@ -848,6 +848,13 @@ de:
|
|||||||
mail_subject_reminder: "%{count} Tickets müssen in den nächsten %{days} Tagen abgegeben werden"
|
mail_subject_reminder: "%{count} Tickets müssen in den nächsten %{days} Tagen abgegeben werden"
|
||||||
mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefügt"
|
mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefügt"
|
||||||
mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
|
mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
|
||||||
|
mail_subject_security_notification: "Sicherheitshinweis"
|
||||||
|
mail_body_security_notification_change: "%{field} wurde geändert."
|
||||||
|
mail_body_security_notification_change_to: "%{field} wurde geändert zu %{value}."
|
||||||
|
mail_body_security_notification_add: "%{field} %{value} wurde hinzugefügt."
|
||||||
|
mail_body_security_notification_remove: "%{field} %{value} wurde entfernt."
|
||||||
|
mail_body_security_notification_notify_enabled: "E-Mail-Adresse %{value} erhält nun Benachrichtigungen."
|
||||||
|
mail_body_security_notification_notify_disabled: "E-Mail-Adresse %{value} erhält keine Benachrichtigungen mehr."
|
||||||
|
|
||||||
notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden.
|
notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden.
|
||||||
notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelöscht.
|
notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelöscht.
|
||||||
@ -1148,6 +1155,7 @@ de:
|
|||||||
error_password_expired: Your password has expired or the administrator requires you
|
error_password_expired: Your password has expired or the administrator requires you
|
||||||
to change it.
|
to change it.
|
||||||
field_time_entries_visibility: Time logs visibility
|
field_time_entries_visibility: Time logs visibility
|
||||||
|
field_remote_ip: IP-Adresse
|
||||||
label_parent_task_attributes: Parent tasks attributes
|
label_parent_task_attributes: Parent tasks attributes
|
||||||
label_parent_task_attributes_derived: Calculated from subtasks
|
label_parent_task_attributes_derived: Calculated from subtasks
|
||||||
label_parent_task_attributes_independent: Independent of subtasks
|
label_parent_task_attributes_independent: Independent of subtasks
|
||||||
|
|||||||
@ -228,6 +228,13 @@ en:
|
|||||||
mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
|
mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
|
||||||
mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
|
mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
|
||||||
mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
|
mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
|
||||||
|
mail_subject_security_notification: "Security notification"
|
||||||
|
mail_body_security_notification_change: "%{field} was changed."
|
||||||
|
mail_body_security_notification_change_to: "%{field} was changed to %{value}."
|
||||||
|
mail_body_security_notification_add: "%{field} %{value} was added."
|
||||||
|
mail_body_security_notification_remove: "%{field} %{value} was removed."
|
||||||
|
mail_body_security_notification_notify_enabled: "Email address %{value} now receives notifications."
|
||||||
|
mail_body_security_notification_notify_disabled: "Email address %{value} no longer receives notifications."
|
||||||
|
|
||||||
field_name: Name
|
field_name: Name
|
||||||
field_description: Description
|
field_description: Description
|
||||||
@ -352,6 +359,7 @@ en:
|
|||||||
field_time_entries_visibility: Time logs visibility
|
field_time_entries_visibility: Time logs visibility
|
||||||
field_total_estimated_hours: Total estimated time
|
field_total_estimated_hours: Total estimated time
|
||||||
field_default_version: Default version
|
field_default_version: Default version
|
||||||
|
field_remote_ip: IP address
|
||||||
|
|
||||||
setting_app_title: Application title
|
setting_app_title: Application title
|
||||||
setting_app_subtitle: Application subtitle
|
setting_app_subtitle: Application subtitle
|
||||||
|
|||||||
@ -400,6 +400,7 @@ class AccountControllerTest < ActionController::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_post_lost_password_with_token_should_change_the_user_password
|
def test_post_lost_password_with_token_should_change_the_user_password
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
user = User.find(2)
|
user = User.find(2)
|
||||||
token = Token.create!(:action => 'recovery', :user => user)
|
token = Token.create!(:action => 'recovery', :user => user)
|
||||||
|
|
||||||
@ -408,6 +409,10 @@ class AccountControllerTest < ActionController::TestCase
|
|||||||
user.reload
|
user.reload
|
||||||
assert user.check_password?('newpass123')
|
assert user.check_password?('newpass123')
|
||||||
assert_nil Token.find_by_id(token.id), "Token was not deleted"
|
assert_nil Token.find_by_id(token.id), "Token was not deleted"
|
||||||
|
assert_not_nil (mail = ActionMailer::Base.deliveries.last)
|
||||||
|
assert_select_email do
|
||||||
|
assert_select 'a[href^=?]', 'http://localhost:3000/my/password', :text => 'Change password'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_post_lost_password_with_token_for_non_active_user_should_fail
|
def test_post_lost_password_with_token_for_non_active_user_should_fail
|
||||||
|
|||||||
@ -92,6 +92,22 @@ class EmailAddressesControllerTest < ActionController::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_create_should_send_security_notification
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
|
post :create, :user_id => 2, :email_address => {:address => 'something@example.fr'}
|
||||||
|
|
||||||
|
assert_not_nil (mail = ActionMailer::Base.deliveries.last)
|
||||||
|
assert_mail_body_match '0.0.0.0', mail
|
||||||
|
assert_mail_body_match I18n.t(:mail_body_security_notification_add, field: I18n.t(:field_mail), value: 'something@example.fr'), mail
|
||||||
|
assert_select_email do
|
||||||
|
assert_select 'a[href^=?]', 'http://localhost:3000/my/account', :text => 'My account'
|
||||||
|
end
|
||||||
|
# The old email address should be notified about a new address for security purposes
|
||||||
|
assert [mail.bcc, mail.cc].flatten.include?(User.find(2).mail)
|
||||||
|
assert [mail.bcc, mail.cc].flatten.include?('something@example.fr')
|
||||||
|
end
|
||||||
|
|
||||||
def test_update
|
def test_update
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||||
@ -112,6 +128,21 @@ class EmailAddressesControllerTest < ActionController::TestCase
|
|||||||
assert_equal false, email.reload.notify
|
assert_equal false, email.reload.notify
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_should_send_security_notification
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||||
|
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
|
xhr :put, :update, :user_id => 2, :id => email.id, :notify => '0'
|
||||||
|
|
||||||
|
assert_not_nil (mail = ActionMailer::Base.deliveries.last)
|
||||||
|
assert_mail_body_match I18n.t(:mail_body_security_notification_notify_disabled, value: 'another@somenet.foo'), mail
|
||||||
|
|
||||||
|
# The changed address should be notified for security purposes
|
||||||
|
assert [mail.bcc, mail.cc].flatten.include?('another@somenet.foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def test_destroy
|
def test_destroy
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||||
@ -141,4 +172,18 @@ class EmailAddressesControllerTest < ActionController::TestCase
|
|||||||
assert_response 404
|
assert_response 404
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_destroy_should_send_security_notification
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||||
|
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
|
xhr :delete, :destroy, :user_id => 2, :id => email.id
|
||||||
|
|
||||||
|
assert_not_nil (mail = ActionMailer::Base.deliveries.last)
|
||||||
|
assert_mail_body_match I18n.t(:mail_body_security_notification_remove, field: I18n.t(:field_mail), value: 'another@somenet.foo'), mail
|
||||||
|
|
||||||
|
# The removed address should be notified for security purposes
|
||||||
|
assert [mail.bcc, mail.cc].flatten.include?('another@somenet.foo')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -117,6 +117,24 @@ class MyControllerTest < ActionController::TestCase
|
|||||||
assert user.groups.empty?
|
assert user.groups.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_account_should_send_security_notification
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
|
post :account,
|
||||||
|
:user => {
|
||||||
|
:mail => 'foobar@example.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_not_nil (mail = ActionMailer::Base.deliveries.last)
|
||||||
|
assert_mail_body_match '0.0.0.0', mail
|
||||||
|
assert_mail_body_match I18n.t(:mail_body_security_notification_change_to, field: I18n.t(:field_mail), value: 'foobar@example.com'), mail
|
||||||
|
assert_select_email do
|
||||||
|
assert_select 'a[href^=?]', 'http://localhost:3000/my/account', :text => 'My account'
|
||||||
|
end
|
||||||
|
# The old email address should be notified about the change for security purposes
|
||||||
|
assert [mail.bcc, mail.cc].flatten.include?(User.find(2).mail)
|
||||||
|
assert [mail.bcc, mail.cc].flatten.include?('foobar@example.com')
|
||||||
|
end
|
||||||
|
|
||||||
def test_my_account_should_show_destroy_link
|
def test_my_account_should_show_destroy_link
|
||||||
get :account
|
get :account
|
||||||
assert_select 'a[href="/my/account/destroy"]'
|
assert_select 'a[href="/my/account/destroy"]'
|
||||||
@ -193,6 +211,19 @@ class MyControllerTest < ActionController::TestCase
|
|||||||
assert_redirected_to '/my/account'
|
assert_redirected_to '/my/account'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_change_password_should_send_security_notification
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
|
post :password, :password => 'jsmith',
|
||||||
|
:new_password => 'secret123',
|
||||||
|
:new_password_confirmation => 'secret123'
|
||||||
|
|
||||||
|
assert_not_nil (mail = ActionMailer::Base.deliveries.last)
|
||||||
|
assert_mail_body_no_match 'secret123', mail # just to be sure: pw should never be sent!
|
||||||
|
assert_select_email do
|
||||||
|
assert_select 'a[href^=?]', 'http://localhost:3000/my/password', :text => 'Change password'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_page_layout
|
def test_page_layout
|
||||||
get :page_layout
|
get :page_layout
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|||||||
@ -666,6 +666,51 @@ class MailerTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_security_notification
|
||||||
|
set_language_if_valid User.find(1).language
|
||||||
|
with_settings :emails_footer => "footer without link" do
|
||||||
|
User.current.remote_ip = '192.168.1.1'
|
||||||
|
assert Mailer.security_notification(User.find(1), message: :notice_account_password_updated).deliver
|
||||||
|
mail = last_email
|
||||||
|
assert_not_nil mail
|
||||||
|
assert_mail_body_match '192.168.1.1', mail
|
||||||
|
assert_mail_body_match I18n.t(:notice_account_password_updated), mail
|
||||||
|
assert_select_email do
|
||||||
|
assert_select "h1", false
|
||||||
|
assert_select "a", false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_security_notification_should_include_title
|
||||||
|
set_language_if_valid User.find(2).language
|
||||||
|
with_settings :emails_footer => "footer without link" do
|
||||||
|
assert Mailer.security_notification(User.find(2),
|
||||||
|
message: :notice_account_password_updated,
|
||||||
|
title: :label_my_account
|
||||||
|
).deliver
|
||||||
|
assert_select_email do
|
||||||
|
assert_select "a", false
|
||||||
|
assert_select "h1", :text => I18n.t(:label_my_account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_security_notification_should_include_link
|
||||||
|
set_language_if_valid User.find(3).language
|
||||||
|
with_settings :emails_footer => "footer without link" do
|
||||||
|
assert Mailer.security_notification(User.find(3),
|
||||||
|
message: :notice_account_password_updated,
|
||||||
|
title: :label_my_account,
|
||||||
|
url: {controller: 'my', action: 'account'}
|
||||||
|
).deliver
|
||||||
|
assert_select_email do
|
||||||
|
assert_select "h1", false
|
||||||
|
assert_select 'a[href=?]', 'http://mydomain.foo/my/account', :text => I18n.t(:label_my_account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_mailer_should_not_change_locale
|
def test_mailer_should_not_change_locale
|
||||||
# Set current language to italian
|
# Set current language to italian
|
||||||
set_language_if_valid 'it'
|
set_language_if_valid 'it'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user