email.split("@").last
end
- if blocked = Acl.no_account_creation(request.remote_ip, domain)
+ mx_servers = if domain.nil?
+ nil
+ else
+ domain_mx_servers(domain)
+ end
+
+ if blocked = Acl.no_account_creation(request.remote_ip, :domain => domain, :mx => mx_servers)
logger.info "Blocked signup from #{request.remote_ip} for #{email}"
render :action => "blocked"
!blocked
end
+ ##
+ # get list of MX servers for a domains
+ def domain_mx_servers(domain)
+ Resolv::DNS.open do |dns|
+ dns.getresources(domain, Resolv::DNS::Resource::IN::MX).collect(&:exchange).collect(&:to_s)
+ end
+ end
+
##
# check if this user has a gravatar and set the user pref is true
def gravatar_enable(user)
# k :string not null
# v :string
# domain :string
+# mx :string
#
# Indexes
#
# acls_k_idx (k)
# index_acls_on_address (address) USING gist
# index_acls_on_domain (domain)
+# index_acls_on_mx (mx)
#
class Acl < ActiveRecord::Base
validates :k, :presence => true
- def self.match(address, domain = nil)
- if domain
- Acl.where("address >>= ? OR domain = ?", address, domain)
- else
- Acl.where("address >>= ?", address)
- end
+ def self.match(address, options = {})
+ acls = Acl.where("address >>= ?", address)
+
+ acls = acls.or(Acl.where(:domain => options[:domain])) if options[:domain]
+ acls = acls.or(Acl.where(:mx => options[:mx])) if options[:mx]
+
+ acls
end
- def self.no_account_creation(address, domain = nil)
- match(address, domain).where(:k => "no_account_creation").exists?
+ def self.no_account_creation(address, options = {})
+ match(address, options).where(:k => "no_account_creation").exists?
end
def self.no_note_comment(address, domain = nil)
- match(address, domain).where(:k => "no_note_comment").exists?
+ match(address, :domain => domain).where(:k => "no_note_comment").exists?
end
def self.no_trace_download(address, domain = nil)
- match(address, domain).where(:k => "no_trace_download").exists?
+ match(address, :domain => domain).where(:k => "no_trace_download").exists?
end
end
--- /dev/null
+class AddMxAcls < ActiveRecord::Migration[5.2]
+ def change
+ add_column :acls, :mx, :string
+
+ safety_assured do
+ add_index :acls, :mx
+ end
+ end
+end
address inet,
k character varying NOT NULL,
v character varying,
- domain character varying
+ domain character varying,
+ mx character varying
);
CREATE INDEX index_acls_on_domain ON public.acls USING btree (domain);
+--
+-- Name: index_acls_on_mx; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE INDEX index_acls_on_mx ON public.acls USING btree (mx);
+
+
--
-- Name: index_changeset_comments_on_created_at; Type: INDEX; Schema: public; Owner: -
--
('20181020114000'),
('20181031113522'),
('20190518115041'),
+('20190623093642'),
('21'),
('22'),
('23'),
end
def test_no_account_creation_by_domain
- assert_not Acl.no_account_creation("192.168.1.1", "example.com")
+ assert_not Acl.no_account_creation("192.168.1.1", :domain => "example.com")
create(:acl, :domain => "example.com", :k => "no_account_creation")
- assert Acl.no_account_creation("192.168.1.1", "example.com")
+ assert Acl.no_account_creation("192.168.1.1", :domain => "example.com")
+ end
+
+ def test_no_account_creation_by_mx
+ assert_not Acl.no_account_creation("192.168.1.1", :mx => "mail.example.com")
+ create(:acl, :mx => "mail.example.com", :k => "no_account_creation")
+ assert Acl.no_account_creation("192.168.1.1", :mx => "mail.example.com")
end
end