Project

General

Profile

Feature #21421 » 0004-Send-a-security-notification-when-a-user-s-email-add.patch

Jan from Planio www.plan.io, 2015-12-12 14:30

View differences:

app/models/email_address.rb
19 19
  belongs_to :user
20 20
  attr_protected :id
21
  after_update :destroy_tokens
22
  after_destroy :destroy_tokens
21
  after_create :deliver_security_notification_create
22
  after_update :destroy_tokens, :deliver_security_notification_update
23
  after_destroy :destroy_tokens, :deliver_security_notification_destroy
23 24
  validates_presence_of :address
24 25
  validates_format_of :address, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
......
42 43
  private
44
  # send a security notification to user that a new email address was added
45
  def deliver_security_notification_create
46
    # only deliver if this isn't the only address.
47
    # in that case, the user is just being created and
48
    # should not receive this email.
49
    if user.mails != [address]
50
      deliver_security_notification(user,
51
        message: :mail_body_security_notification_add,
52
        field: :field_mail,
53
        value: address
54
      )
55
    end
56
  end
57

  
58
  # send a security notification to user that an email has been changed (notified/not notified)
59
  def deliver_security_notification_update
60
    if address_changed?
61
      recipients = [user, address_was]
62
      options = {
63
        message: :mail_body_security_notification_change_to,
64
        field: :field_mail,
65
        value: address
66
      }
67
    elsif notify_changed?
68
      recipients = [user, address]
69
      options = {
70
        message: notify_was ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
71
        value: address
72
      }
73
    end
74
    deliver_security_notification(recipients, options)
75
  end
76

  
77
  # send a security notification to user that an email address was deleted
78
  def deliver_security_notification_destroy
79
    deliver_security_notification([user, address],
80
      message: :mail_body_security_notification_remove,
81
      field: :field_mail,
82
      value: address
83
    )
84
  end
85

  
86
  # generic method to send security notifications for email addresses
87
  def deliver_security_notification(recipients, options={})
88
    Mailer.security_notification(recipients,
89
      options.merge(
90
        title: :label_my_account,
91
        url: {controller: 'my', action: 'account'}
92
      )
93
    ).deliver
94
  end
95

  
43 96
  # Delete all outstanding password reset tokens on email change.
44 97
  # This helps to keep the account secure in case the associated email account
45 98
  # was compromised.
config/locales/de.yml
853 853
  mail_body_security_notification_change_to: "%{field} wurde geändert zu %{value}."
854 854
  mail_body_security_notification_add: "%{field} %{value} wurde hinzugefügt."
855 855
  mail_body_security_notification_remove: "%{field} %{value} wurde entfernt."
856
  mail_body_security_notification_notify_enabled: "E-Mail-Adresse %{value} erhält nun Benachrichtigungen."
857
  mail_body_security_notification_notify_disabled: "E-Mail-Adresse %{value} erhält keine Benachrichtigungen mehr."
856 858
  notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden.
857 859
  notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelöscht.
config/locales/en.yml
232 232
  mail_body_security_notification_change_to: "%{field} was changed to %{value}."
233 233
  mail_body_security_notification_add: "%{field} %{value} was added."
234 234
  mail_body_security_notification_remove: "%{field} %{value} was removed."
235
  mail_body_security_notification_notify_enabled: "Email address %{value} now receives notifications."
236
  mail_body_security_notification_notify_disabled: "Email address %{value} no longer receives notifications."
235 237
  field_name: Name
236 238
  field_description: Description
test/functional/email_addresses_controller_test.rb
92 92
    end
93 93
  end
94
  def test_create_should_send_security_notification
95
    @request.session[:user_id] = 2
96
    ActionMailer::Base.deliveries.clear
97
    post :create, :user_id => 2, :email_address => {:address => 'something@example.fr'}
98

  
99
    assert_not_nil (mail = ActionMailer::Base.deliveries.last)
100
    assert_mail_body_match '0.0.0.0', mail
101
    assert_mail_body_match I18n.t(:mail_body_security_notification_add, field: I18n.t(:field_mail), value: 'something@example.fr'), mail
102
    assert_select_email do
103
      assert_select 'a[href^=?]', 'http://localhost:3000/my/account', :text => 'My account'
104
    end
105
    # The old email address should be notified about a new address for security purposes
106
    assert [mail.bcc, mail.cc].flatten.include?(User.find(2).mail)
107
    assert [mail.bcc, mail.cc].flatten.include?('something@example.fr')
108
  end
109

  
94 110
  def test_update
95 111
    @request.session[:user_id] = 2
96 112
    email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
......
112 128
    assert_equal false, email.reload.notify
113 129
  end
130
  def test_update_should_send_security_notification
131
    @request.session[:user_id] = 2
132
    email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
133

  
134
    ActionMailer::Base.deliveries.clear
135
    xhr :put, :update, :user_id => 2, :id => email.id, :notify => '0'
136

  
137
    assert_not_nil (mail = ActionMailer::Base.deliveries.last)
138
    assert_mail_body_match I18n.t(:mail_body_security_notification_notify_disabled, value: 'another@somenet.foo'), mail
139

  
140
    # The changed address should be notified for security purposes
141
    assert [mail.bcc, mail.cc].flatten.include?('another@somenet.foo')
142
  end
143

  
144

  
114 145
  def test_destroy
115 146
    @request.session[:user_id] = 2
116 147
    email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
......
141 172
      assert_response 404
142 173
    end
143 174
  end
175

  
176
  def test_destroy_should_send_security_notification
177
    @request.session[:user_id] = 2
178
    email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
179

  
180
    ActionMailer::Base.deliveries.clear
181
    xhr :delete, :destroy, :user_id => 2, :id => email.id
182

  
183
    assert_not_nil (mail = ActionMailer::Base.deliveries.last)
184
    assert_mail_body_match I18n.t(:mail_body_security_notification_remove, field: I18n.t(:field_mail), value: 'another@somenet.foo'), mail
185

  
186
    # The removed address should be notified for security purposes
187
    assert [mail.bcc, mail.cc].flatten.include?('another@somenet.foo')
188
  end
144 189
end
test/functional/my_controller_test.rb
117 117
    assert user.groups.empty?
118 118
  end
119
  def test_update_account_should_send_security_notification
120
    ActionMailer::Base.deliveries.clear
121
    post :account,
122
      :user => {
123
        :mail => 'foobar@example.com'
124
      }
125

  
126
    assert_not_nil (mail = ActionMailer::Base.deliveries.last)
127
    assert_mail_body_match '0.0.0.0', mail
128
    assert_mail_body_match I18n.t(:mail_body_security_notification_change_to, field: I18n.t(:field_mail), value: 'foobar@example.com'), mail
129
    assert_select_email do
130
      assert_select 'a[href^=?]', 'http://localhost:3000/my/account', :text => 'My account'
131
    end
132
    # The old email address should be notified about the change for security purposes
133
    assert [mail.bcc, mail.cc].flatten.include?(User.find(2).mail)
134
    assert [mail.bcc, mail.cc].flatten.include?('foobar@example.com')
135
  end
136

  
119 137
  def test_my_account_should_show_destroy_link
120 138
    get :account
121 139
    assert_select 'a[href="/my/account/destroy"]'
(5-5/9)