summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/settings_controller.rb5
-rw-r--r--app/models/mailer.rb16
-rw-r--r--app/models/setting.rb17
-rw-r--r--app/views/mailer/settings_updated.html.erb14
-rw-r--r--app/views/mailer/settings_updated.text.erb12
-rw-r--r--config/locales/en.yml1
-rw-r--r--config/locales/fr.yml1
-rw-r--r--config/settings.yml16
-rw-r--r--test/functional/settings_controller_test.rb38
9 files changed, 116 insertions, 4 deletions
diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb
index 5ca5d1dab..c7741c053 100644
--- a/app/controllers/settings_controller.rb
+++ b/app/controllers/settings_controller.rb
@@ -33,10 +33,7 @@ class SettingsController < ApplicationController
def edit
@notifiables = Redmine::Notifiable.all
if request.post? && params[:settings] && params[:settings].is_a?(Hash)
- settings = (params[:settings] || {}).dup.symbolize_keys
- settings.each do |name, value|
- Setting.set_from_params name, value
- end
+ Setting.set_all_from_params(params[:settings])
flash[:notice] = l(:notice_successful_update)
redirect_to settings_path(:tab => params[:tab])
else
diff --git a/app/models/mailer.rb b/app/models/mailer.rb
index a803a35c2..4891ff5bf 100644
--- a/app/models/mailer.rb
+++ b/app/models/mailer.rb
@@ -332,6 +332,22 @@ class Mailer < ActionMailer::Base
:subject => l(:mail_subject_security_notification)
end
+ def settings_updated(recipients, changes)
+ redmine_headers 'Sender' => User.current.login
+ @changes = changes
+ @url = url_for(controller: 'settings', action: 'index')
+ mail :to => recipients,
+ :subject => l(:mail_subject_security_notification)
+ end
+
+ # Notifies admins about settings changes
+ def self.security_settings_updated(changes)
+ return unless changes.present?
+
+ users = User.active.where(admin: true).to_a
+ Mailer.settings_updated(users, changes).deliver
+ end
+
def test_email(user)
set_language_if_valid(user.language)
@url = url_for(:controller => 'welcome')
diff --git a/app/models/setting.rb b/app/models/setting.rb
index 2574649f3..bbcdfc72a 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -118,6 +118,23 @@ class Setting < ActiveRecord::Base
setting.value
end
+ # Updates multiple settings from params and sends a security notification if needed
+ def self.set_all_from_params(settings)
+ settings = (settings || {}).dup.symbolize_keys
+ changes = []
+ settings.each do |name, value|
+ previous_value = Setting[name]
+ set_from_params name, value
+ if available_settings[name.to_s]['security_notifications'] && Setting[name] != previous_value
+ changes << name
+ end
+ end
+ if changes.any?
+ Mailer.security_settings_updated(changes)
+ end
+ true
+ end
+
# Sets a setting value from params
def self.set_from_params(name, params)
params = params.dup
diff --git a/app/views/mailer/settings_updated.html.erb b/app/views/mailer/settings_updated.html.erb
new file mode 100644
index 000000000..8596089a2
--- /dev/null
+++ b/app/views/mailer/settings_updated.html.erb
@@ -0,0 +1,14 @@
+<p><%= l(:mail_body_settings_updated) %></p>
+
+<ul>
+<% @changes.each do |name| %>
+ <li><%= l("setting_#{name}") %></li>
+<% end %>
+</ul>
+
+<%= link_to @url, @url %>
+
+<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 %></strong></p>
+
diff --git a/app/views/mailer/settings_updated.text.erb b/app/views/mailer/settings_updated.text.erb
new file mode 100644
index 000000000..51a2a8f6a
--- /dev/null
+++ b/app/views/mailer/settings_updated.text.erb
@@ -0,0 +1,12 @@
+<%= l(:mail_body_settings_updated) %>
+
+<% @changes.each do |name| %>
+ * <%= l("setting_#{name}") %>
+<% end %>
+
+<%= @url %>
+
+<%= l(:field_user) %>: <%= User.current.login %>
+<%= l(:field_remote_ip) %>: <%= User.current.remote_ip %>
+<%= l(:label_date) %>: <%= format_time Time.now, true %>
+
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 8a314511a..a2ac47903 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -235,6 +235,7 @@ en:
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."
+ mail_body_settings_updated: "The following settings were changed:"
field_name: Name
field_description: Description
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 90984c871..41cfd55c9 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -248,6 +248,7 @@ fr:
mail_body_wiki_content_added: "La page wiki '%{id}' a été ajoutée par %{author}."
mail_subject_wiki_content_updated: "Page wiki '%{id}' mise à jour"
mail_body_wiki_content_updated: "La page wiki '%{id}' a été mise à jour par %{author}."
+ mail_body_settings_updated: "Les paramètres suivants ont été modifiés :"
field_name: Nom
field_description: Description
diff --git a/config/settings.yml b/config/settings.yml
index 5031b68d3..49e1edcd3 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -27,19 +27,24 @@ welcome_text:
default:
login_required:
default: 0
+ security_notifications: 1
self_registration:
default: '2'
+ security_notifications: 1
lost_password:
default: 1
+ security_notifications: 1
unsubscribe:
default: 1
password_min_length:
format: int
default: 8
+ security_notifications: 1
# Maximum password age in days
password_max_age:
format: int
default: 0
+ security_notifications: 1
# Maximum number of additional email addresses per user
max_additional_emails:
format: int
@@ -48,10 +53,12 @@ max_additional_emails:
session_lifetime:
format: int
default: 0
+ security_notifications: 1
# User session timeout in minutes
session_timeout:
format: int
default: 0
+ security_notifications: 1
attachment_max_size:
format: int
default: 5120
@@ -91,6 +98,7 @@ host_name:
default: localhost:3000
protocol:
default: http
+ security_notifications: 1
feeds_limit:
format: int
default: 15
@@ -114,12 +122,15 @@ enabled_scm:
- Cvs
- Bazaar
- Git
+ security_notifications: 1
autofetch_changesets:
default: 1
sys_api_enabled:
default: 0
+ security_notifications: 1
sys_api_key:
default: ''
+ security_notifications: 1
commit_cross_project_ref:
default: 0
commit_ref_keywords:
@@ -173,8 +184,10 @@ mail_handler_excluded_filenames:
default: ''
mail_handler_api_enabled:
default: 0
+ security_notifications: 1
mail_handler_api_key:
default:
+ security_notifications: 1
issue_list_default_columns:
serialized: true
default:
@@ -237,14 +250,17 @@ gravatar_enabled:
default: 0
openid:
default: 0
+ security_notifications: 1
gravatar_default:
default: ''
start_of_week:
default: ''
rest_api_enabled:
default: 0
+ security_notifications: 1
jsonp_enabled:
default: 0
+ security_notifications: 1
default_notification_option:
default: 'only_my_events'
emails_header:
diff --git a/test/functional/settings_controller_test.rb b/test/functional/settings_controller_test.rb
index de5fddd8a..139eb7845 100644
--- a/test/functional/settings_controller_test.rb
+++ b/test/functional/settings_controller_test.rb
@@ -136,6 +136,44 @@ class SettingsControllerTest < ActionController::TestCase
], Setting.commit_update_keywords)
end
+ def test_post_edit_should_send_security_notification_for_notified_settings
+ ActionMailer::Base.deliveries.clear
+ post :edit, :settings => {
+ :login_required => 1
+ }
+
+ assert_not_nil (mail = ActionMailer::Base.deliveries.last)
+ assert_mail_body_match '0.0.0.0', mail
+ assert_mail_body_match I18n.t(:setting_login_required), mail
+ assert_select_email do
+ assert_select 'a[href^=?]', 'http://localhost:3000/settings'
+ end
+ # All admins should receive this
+ recipients = [mail.bcc, mail.cc].flatten
+ User.active.where(admin: true).each do |admin|
+ assert_include admin.mail, recipients
+ end
+ end
+
+ def test_post_edit_should_not_send_security_notification_for_non_notified_settings
+ ActionMailer::Base.deliveries.clear
+ post :edit, :settings => {
+ :app_title => 'MineRed'
+ }
+
+ assert_nil (mail = ActionMailer::Base.deliveries.last)
+ end
+
+ def test_post_edit_should_not_send_security_notification_for_unchanged_settings
+ ActionMailer::Base.deliveries.clear
+ post :edit, :settings => {
+ :login_required => 0
+ }
+
+ assert_nil (mail = ActionMailer::Base.deliveries.last)
+ end
+
+
def test_get_plugin_settings
ActionController::Base.append_view_path(File.join(Rails.root, "test/fixtures/plugins"))
Redmine::Plugin.register :foo do