2013-08-14 11:05:53 -04:00
|
|
|
require_dependency 'screening_model'
|
|
|
|
|
|
|
|
# A ScreenedEmail record represents an email address that is being watched,
|
|
|
|
# typically when creating a new User account. If the email of the signup form
|
|
|
|
# (or some other form) matches a ScreenedEmail record, an action can be
|
|
|
|
# performed based on the action_type.
|
|
|
|
class ScreenedEmail < ActiveRecord::Base
|
|
|
|
|
|
|
|
include ScreeningModel
|
|
|
|
|
|
|
|
default_action :block
|
|
|
|
|
|
|
|
validates :email, presence: true, uniqueness: true
|
|
|
|
|
|
|
|
def self.block(email, opts={})
|
2013-08-22 19:04:17 -04:00
|
|
|
find_by_email(email) || create(opts.slice(:action_type, :ip_address).merge({email: email}))
|
2013-08-14 11:05:53 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.should_block?(email)
|
2014-07-11 09:09:46 -04:00
|
|
|
levenshtein_distance = SiteSetting.levenshtein_distance_spammer_emails
|
|
|
|
|
|
|
|
sql = <<-SQL
|
|
|
|
JOIN (
|
|
|
|
SELECT email, levenshtein_less_equal(email, :email, :levenshtein_distance) AS distance
|
|
|
|
FROM screened_emails
|
|
|
|
ORDER BY created_at DESC
|
|
|
|
LIMIT 100
|
|
|
|
) AS sed ON sed.email = screened_emails.email
|
|
|
|
SQL
|
|
|
|
|
|
|
|
screened_emails_distance = ScreenedEmail.sql_fragment(sql, email: email, levenshtein_distance: levenshtein_distance)
|
|
|
|
|
|
|
|
screened_email = ScreenedEmail.joins(screened_emails_distance)
|
|
|
|
.where("sed.distance <= ?", levenshtein_distance)
|
|
|
|
.order("sed.distance ASC")
|
|
|
|
.limit(1)
|
|
|
|
.first
|
|
|
|
|
2013-08-14 11:05:53 -04:00
|
|
|
screened_email.record_match! if screened_email
|
2014-07-11 09:09:46 -04:00
|
|
|
|
2013-08-14 11:05:53 -04:00
|
|
|
screened_email && screened_email.action_type == actions[:block]
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
2013-08-27 20:42:58 -04:00
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: screened_emails
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# email :string(255) not null
|
|
|
|
# action_type :integer not null
|
|
|
|
# match_count :integer default(0), not null
|
|
|
|
# last_match_at :datetime
|
2014-05-27 21:49:50 -04:00
|
|
|
# created_at :datetime
|
|
|
|
# updated_at :datetime
|
2013-12-05 01:40:35 -05:00
|
|
|
# ip_address :inet
|
2013-08-27 20:42:58 -04:00
|
|
|
#
|
|
|
|
# Indexes
|
|
|
|
#
|
2014-05-27 21:49:50 -04:00
|
|
|
# index_screened_emails_on_email (email) UNIQUE
|
|
|
|
# index_screened_emails_on_last_match_at (last_match_at)
|
2013-08-27 20:42:58 -04:00
|
|
|
#
|