From ea417c0362da1e17ead97aa26b8f3269b21555de Mon Sep 17 00:00:00 2001 From: Jan Schulz-Hofen Date: Wed, 2 Dec 2015 18:31:53 +0800 Subject: [PATCH 2/7] Add Mailer#security_notification The idea is to deliver a Mailer#security_notification whenever changes are made that could impact the security of users or the entire Redmine installation. --- app/models/mailer.rb | 14 ++++++++ app/views/mailer/security_notification.html.erb | 13 +++++++ app/views/mailer/security_notification.text.erb | 8 +++++ config/locales/de.yml | 5 +++ config/locales/en.yml | 5 +++ test/unit/mailer_test.rb | 45 +++++++++++++++++++++++++ 6 files changed, 90 insertions(+) create mode 100644 app/views/mailer/security_notification.html.erb create mode 100644 app/views/mailer/security_notification.text.erb diff --git a/app/models/mailer.rb b/app/models/mailer.rb index ac4cc3a..a803a35 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -318,6 +318,20 @@ class Mailer < ActionMailer::Base :subject => l(:mail_subject_register, Setting.app_title) 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) set_language_if_valid(user.language) @url = url_for(:controller => 'welcome') diff --git a/app/views/mailer/security_notification.html.erb b/app/views/mailer/security_notification.html.erb new file mode 100644 index 0000000..53bf0a0 --- /dev/null +++ b/app/views/mailer/security_notification.html.erb @@ -0,0 +1,13 @@ +

<%= @message %>
+<% if @url && @title -%> +<%= link_to @title, @url -%> +<% elsif @url -%> +<%= link_to @url -%> +<% elsif @title -%> +<%= content_tag :h1, @title -%> +<% end %>

+ +

<%= l(:field_user) %>: <%= User.current.login %>
+<%= l(:field_remote_ip) %>: <%= User.current.remote_ip %>
+<%= l(:label_date) %>: <%= format_time Time.now, true, @user %>

+ diff --git a/app/views/mailer/security_notification.text.erb b/app/views/mailer/security_notification.text.erb new file mode 100644 index 0000000..17fd6ef --- /dev/null +++ b/app/views/mailer/security_notification.text.erb @@ -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 %> + diff --git a/config/locales/de.yml b/config/locales/de.yml index 0278273..e827e3d 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -848,6 +848,11 @@ de: 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_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." notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden. notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelöscht. diff --git a/config/locales/en.yml b/config/locales/en.yml index 23d2b55..0b74c2e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -227,6 +227,11 @@ en: 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_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." field_name: Name field_description: Description diff --git a/test/unit/mailer_test.rb b/test/unit/mailer_test.rb index f3742c2..16b0bec 100644 --- a/test/unit/mailer_test.rb +++ b/test/unit/mailer_test.rb @@ -666,6 +666,51 @@ class MailerTest < ActiveSupport::TestCase 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 # Set current language to italian set_language_if_valid 'it' -- 2.4.0