diff --git a/app/models/email_address.rb b/app/models/email_address.rb
index 4cd9c5dfd..85b77fc3a 100644
--- a/app/models/email_address.rb
+++ b/app/models/email_address.rb
@@ -36,6 +36,7 @@ class EmailAddress < ActiveRecord::Base
validates_length_of :address, :maximum => User::MAIL_LENGTH_LIMIT, :allow_nil => true
validates_uniqueness_of :address, :case_sensitive => false,
:if => Proc.new {|email| email.address_changed? && email.address.present?}
+ validate :validate_domain, :if => Proc.new{|email| email.errors[:address].blank? && email.address.present?}
safe_attributes 'address'
@@ -117,4 +118,29 @@ class EmailAddress < ActiveRecord::Base
Token.where(:user_id => user_id, :action => tokens).delete_all
end
end
+
+ def validate_domain
+ denied, allowed =
+ [:email_domains_denied, :email_domains_allowed].map do |setting|
+ Setting.__send__(setting)
+ end
+ invalid = false
+ domain = address.sub(/\A.*@/, '')
+ if denied.present? && domain_in?(domain, denied)
+ invalid = true
+ end
+ if allowed.present? && !domain_in?(domain, allowed)
+ invalid = true
+ end
+ errors.add(:address, l(:error_domain_not_allowed, :domain => domain)) if invalid
+ end
+
+ def domain_in?(addr, domains)
+ domain = addr.downcase.sub(/\A.*@/, '')
+ unless domains.is_a?(Array)
+ domains = domains.to_s.split(/[\s,]+/)
+ end
+ domains = domains.map{|s| s.downcase.sub(/\A.*@/, '')}.reject(&:blank?)
+ domains.include?(domain)
+ end
end
diff --git a/app/views/settings/_users.html.erb b/app/views/settings/_users.html.erb
index ab61d7c21..8d446317a 100644
--- a/app/views/settings/_users.html.erb
+++ b/app/views/settings/_users.html.erb
@@ -4,6 +4,12 @@
<%= setting_text_field :max_additional_emails, :size => 6 %>
<%= setting_check_box :unsubscribe %>
+
+ <%= setting_text_area :email_domains_allowed %>
+ <%= l(:text_comma_separated) %> <%= l(:label_example) %>: foo.example.com, bar.example.org
+
+ <%= setting_text_area :email_domains_denied %>
+ <%= l(:text_comma_separated) %> <%= l(:label_example) %>: baz.example.net, qux.example.biz