Project

General

Profile

Feature #3369 » 3369-restrict-domains.patch

Yuichi HARADA, 2020-03-12 06:28

View differences:

app/models/email_address.rb
36 36
  validates_length_of :address, :maximum => User::MAIL_LENGTH_LIMIT, :allow_nil => true
37 37
  validates_uniqueness_of :address, :case_sensitive => false,
38 38
    :if => Proc.new {|email| email.address_changed? && email.address.present?}
39
  validate :validate_domain, :if => Proc.new{|email| email.errors[:address].blank? && email.address.present?}
39 40

  
40 41
  safe_attributes 'address'
41 42

  
......
117 118
      Token.where(:user_id => user_id, :action => tokens).delete_all
118 119
    end
119 120
  end
121

  
122
  def validate_domain
123
    denied, allowed =
124
      [:email_domains_denied, :email_domains_allowed].map do |setting|
125
        Setting.__send__(setting)
126
      end
127
    invalid = false
128
    domain = address.sub(/\A.*@/, '')
129
    if denied.present? && domain_in?(domain, denied)
130
      invalid = true
131
    end
132
    if allowed.present? && !domain_in?(domain, allowed)
133
      invalid = true
134
    end
135
    errors.add(:address, l(:error_domain_not_allowed, :domain => domain)) if invalid
136
  end
137

  
138
  def domain_in?(addr, domains)
139
    domain = addr.downcase.sub(/\A.*@/, '')
140
    unless domains.is_a?(Array)
141
      domains = domains.to_s.split(/[\s,]+/)
142
    end
143
    domains = domains.map{|s| s.downcase.sub(/\A.*@/, '')}.reject(&:blank?)
144
    domains.include?(domain)
145
  end
120 146
end
app/views/settings/_users.html.erb
4 4
    <p><%= setting_text_field :max_additional_emails, :size => 6 %></p>
5 5

  
6 6
    <p><%= setting_check_box :unsubscribe %></p>
7

  
8
    <p><%= setting_text_area :email_domains_allowed %>
9
    <em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: foo.example.com, bar.example.org</em></p>
10

  
11
    <p><%= setting_text_area :email_domains_denied %>
12
    <em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: baz.example.net, qux.example.biz</em></p>
7 13
  </div>
8 14

  
9 15
  <fieldset class="box tabular settings">
config/locales/en.yml
232 232
  error_can_not_delete_auth_source: "This authentication mode is in use and cannot be deleted."
233 233
  error_spent_on_future_date: "Cannot log time on a future date"
234 234
  error_not_allowed_to_log_time_for_other_users: "You are not allowed to log time for other users"
235
  error_domain_not_allowed: "Domain %{domain} is not allowed"
235 236

  
236 237
  mail_subject_lost_password: "Your %{value} password"
237 238
  mail_body_lost_password: 'To change your password, click on the following link:'
......
476 477
  setting_force_default_language_for_loggedin: Force default language for logged-in users
477 478
  setting_link_copied_issue: Link issues on copy
478 479
  setting_max_additional_emails: Maximum number of additional email addresses
480
  setting_email_domains_allowed: Allowed email domains
481
  setting_email_domains_denied: Disallowed email domains
479 482
  setting_search_results_per_page: Search results per page
480 483
  setting_attachment_extensions_allowed: Allowed extensions
481 484
  setting_attachment_extensions_denied: Disallowed extensions
config/settings.yml
53 53
max_additional_emails:
54 54
  format: int
55 55
  default: 5
56
email_domains_allowed:
57
  default:
58
email_domains_denied:
59
  default:
56 60
# Maximum lifetime of user sessions in minutes
57 61
session_lifetime:
58 62
  format: int
test/functional/email_addresses_controller_test.rb
118 118
    end
119 119
  end
120 120

  
121
  def test_create_with_disallowed_domain_should_failure
122
    @request.session[:user_id] = 2
123

  
124
    with_settings :email_domains_denied => "example.com, Somenet.Foo\r\nlocalhost.localdomain" do
125
      assert_no_difference 'EmailAddress.count' do
126
        post :create, :params => {
127
            :user_id => 2,
128
            :email_address => {
129
              :address => 'another@somenet.foo'
130
            }
131
          }
132
        assert_response :success
133
        assert_select_error /Email Domain somenet.foo is not allowed/
134
      end
135
    end
136

  
137
    with_settings :email_domains_allowed => "example.com, Somenet.Foo\r\nlocalhost.localdomain" do
138
      assert_no_difference 'EmailAddress.count' do
139
        post :create, :params => {
140
            :user_id => 2,
141
            :email_address => {
142
              :address => 'something@example.fr'
143
            }
144
          }
145
        assert_response :success
146
        assert_select_error /Email Domain example.fr is not allowed/
147
      end
148
    end
149
  end
150

  
121 151
  def test_create_should_send_security_notification
122 152
    @request.session[:user_id] = 2
123 153
    ActionMailer::Base.deliveries.clear
test/unit/user_test.rb
225 225
    assert_include "Email #{I18n.translate('activerecord.errors.messages.taken')}", u.errors.full_messages
226 226
  end
227 227

  
228
  def test_mail_with_disallowed_domain
229
    with_settings :email_domains_denied => "example.com, Somenet.Foo\r\nlocalhost.localdomain" do
230
      assert_difference 'User.count' do
231
        assert_difference 'EmailAddress.count' do
232
          u = User.new(
233
            :login => 'newuser1', :firstname => 'new', :lastname => 'user',
234
            :mail => 'newuser@example.net'
235
          )
236
          assert u.save
237
        end
238
      end
239

  
240
      assert_no_difference 'User.count' do
241
        assert_no_difference 'EmailAddress.count' do
242
          u = User.new(
243
            :login => 'newuser2', :firstname => 'new', :lastname => 'user',
244
            :mail => 'newuser@somenet.foo'
245
          )
246
          assert !u.save
247
          assert_include 'Email Domain somenet.foo is not allowed', u.errors.full_messages
248
        end
249
      end
250
    end
251
  end
252

  
253
  def test_mail_with_allowed_domain
254
    with_settings :email_domains_allowed => "example.com, Somenet.Foo\r\nlocalhost.localdomain" do
255
      assert_difference 'User.count' do
256
        assert_difference 'EmailAddress.count' do
257
          u = User.new(
258
            :login => 'newuser1', :firstname => 'new', :lastname => 'user',
259
            :mail => 'newuser@somenet.foo'
260
          )
261
          assert u.save
262
        end
263
      end
264

  
265
      assert_no_difference 'User.count' do
266
        assert_no_difference 'EmailAddress.count' do
267
          u = User.new(
268
            :login => 'newuser2', :firstname => 'new', :lastname => 'user',
269
            :mail => 'newuser@example.net'
270
          )
271
          assert !u.save
272
          assert_include 'Email Domain example.net is not allowed', u.errors.full_messages
273
        end
274
      end
275
    end
276
  end
277

  
228 278
  def test_update
229 279
    assert_equal "admin", @admin.login
230 280
    @admin.login = "john"
(2-2/4)