diff --git a/app/models/email_address.rb b/app/models/email_address.rb
index b27cf6e58..31bdf02fa 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_email_domain, :if => proc {|email| email.errors[:address].blank? && email.address.present?}
safe_attributes 'address'
@@ -51,6 +52,28 @@ class EmailAddress < ActiveRecord::Base
end
end
+ # Returns true if the email domain is allowed regarding allowed/denied
+ # domains defined in application settings, otherwise false
+ def self.valid_domain?(domain_or_email)
+ denied, allowed =
+ [:email_domains_denied, :email_domains_allowed].map do |setting|
+ Setting.__send__(setting)
+ end
+ domain = domain_or_email.split('@').last
+ return false if denied.present? && domain_in?(domain, denied)
+ return false if allowed.present? && !domain_in?(domain, allowed)
+ true
+ end
+
+ # Returns true if domain belongs to domains list.
+ def self.domain_in?(domain, domains)
+ domain = domain.downcase
+ domains = domains.to_s.split(/[\s,]+/) unless domains.is_a?(Array)
+ domains.reject(&:blank?).map(&:downcase).any? do |s|
+ s.start_with?('.') ? domain.end_with?(s) : domain == s
+ end
+ end
+
private
# send a security notification to user that a new email address was added
@@ -117,4 +140,11 @@ class EmailAddress < ActiveRecord::Base
Token.where(:user_id => user_id, :action => tokens).delete_all
end
end
+
+ def validate_email_domain
+ domain = address.split('@').last
+ unless self.class.valid_domain?(domain)
+ errors.add(:address, :disallowed_domain, :domain => domain)
+ end
+ end
end
diff --git a/app/views/settings/_users.html.erb b/app/views/settings/_users.html.erb
index ab61d7c21..846fe2586 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) %>: example.com, example.org
+
+ <%= setting_text_area :email_domains_denied %>
+ <%= l(:text_comma_separated) %> <%= l(:label_example) %>: .example.com, foo.example.org, example.net