FEATURE: new 'maximum new user accounts per registration IP' site setting
This commit is contained in:
parent
78f6cea16c
commit
7641d88224
|
@ -227,8 +227,7 @@ class UsersController < ApplicationController
|
||||||
authentication = UserAuthenticator.new(user, session)
|
authentication = UserAuthenticator.new(user, session)
|
||||||
|
|
||||||
if !authentication.has_authenticator? && !SiteSetting.enable_local_logins
|
if !authentication.has_authenticator? && !SiteSetting.enable_local_logins
|
||||||
render nothing: true, status: 500
|
return render nothing: true, status: 500
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|
||||||
authentication.start
|
authentication.start
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# receive, their trust level, etc.
|
# receive, their trust level, etc.
|
||||||
class SpamRulesEnforcer
|
class SpamRulesEnforcer
|
||||||
|
|
||||||
# The exclamation point means that this method may make big changes to posts and users.
|
|
||||||
def self.enforce!(arg)
|
def self.enforce!(arg)
|
||||||
SpamRulesEnforcer.new(arg).enforce!
|
SpamRulesEnforcer.new(arg).enforce!
|
||||||
end
|
end
|
||||||
|
@ -13,12 +12,8 @@ class SpamRulesEnforcer
|
||||||
end
|
end
|
||||||
|
|
||||||
def enforce!
|
def enforce!
|
||||||
if @user
|
SpamRule::AutoBlock.new(@user).perform if @user
|
||||||
SpamRule::AutoBlock.new(@user).perform
|
SpamRule::FlagSockpuppets.new(@post).perform if @post
|
||||||
end
|
|
||||||
if @post
|
|
||||||
SpamRule::FlagSockpuppets.new(@post).perform
|
|
||||||
end
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class UserAuthenticator
|
class UserAuthenticator
|
||||||
|
|
||||||
def initialize(user, session, authenticator_finder = Users::OmniauthCallbacksController)
|
def initialize(user, session, authenticator_finder = Users::OmniauthCallbacksController)
|
||||||
@user = user
|
@user = user
|
||||||
@session = session[:authentication]
|
@session = session[:authentication]
|
||||||
|
@ -18,10 +19,7 @@ class UserAuthenticator
|
||||||
end
|
end
|
||||||
|
|
||||||
def finish
|
def finish
|
||||||
if authenticator
|
authenticator.after_create_account(@user, @session) if authenticator
|
||||||
authenticator.after_create_account(@user, @session)
|
|
||||||
end
|
|
||||||
|
|
||||||
@session = nil
|
@session = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,4 +38,5 @@ class UserAuthenticator
|
||||||
def authenticator_name
|
def authenticator_name
|
||||||
@session && @session[:authenticator_name]
|
@session && @session[:authenticator_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -941,6 +941,7 @@ en:
|
||||||
staff_like_weight: "How much extra weighting factor to give staff likes."
|
staff_like_weight: "How much extra weighting factor to give staff likes."
|
||||||
|
|
||||||
levenshtein_distance_spammer_emails: "When matching spammer emails, number of characters difference that will still allow a fuzzy match."
|
levenshtein_distance_spammer_emails: "When matching spammer emails, number of characters difference that will still allow a fuzzy match."
|
||||||
|
max_new_accounts_per_registration_ip: "If there are already (n) trust level 0 accounts from this IP, stop accepting new signups from that IP."
|
||||||
|
|
||||||
reply_by_email_enabled: "Enable replying to topics via email."
|
reply_by_email_enabled: "Enable replying to topics via email."
|
||||||
reply_by_email_address: "Template for reply by email incoming email address, for example: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com"
|
reply_by_email_address: "Template for reply by email incoming email address, for example: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com"
|
||||||
|
|
|
@ -576,6 +576,7 @@ spam:
|
||||||
default: 2
|
default: 2
|
||||||
min: 0
|
min: 0
|
||||||
max: 3
|
max: 3
|
||||||
|
max_new_accounts_per_registration_ip: 3
|
||||||
|
|
||||||
rate_limits:
|
rate_limits:
|
||||||
unique_posts_mins:
|
unique_posts_mins:
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
class SpamHandler
|
||||||
|
|
||||||
|
def self.should_prevent_registration_from_ip?(ip_address)
|
||||||
|
return false if SiteSetting.max_new_accounts_per_registration_ip <= 0
|
||||||
|
|
||||||
|
tl0_accounts_with_same_ip = User.unscoped
|
||||||
|
.where(trust_level: TrustLevel[0])
|
||||||
|
.where("ip_address = ?", ip_address.to_s)
|
||||||
|
.count
|
||||||
|
|
||||||
|
tl0_accounts_with_same_ip >= SiteSetting.max_new_accounts_per_registration_ip
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,9 +1,14 @@
|
||||||
|
require_dependency "spam_handler"
|
||||||
|
|
||||||
class AllowedIpAddressValidator < ActiveModel::EachValidator
|
class AllowedIpAddressValidator < ActiveModel::EachValidator
|
||||||
|
|
||||||
def validate_each(record, attribute, value)
|
def validate_each(record, attribute, value)
|
||||||
if record.ip_address and ScreenedIpAddress.should_block?(record.ip_address)
|
if record.ip_address
|
||||||
record.errors.add(attribute, options[:message] || I18n.t('user.ip_address.blocked'))
|
if ScreenedIpAddress.should_block?(record.ip_address) ||
|
||||||
|
(record.trust_level == TrustLevel[0] && SpamHandler.should_prevent_registration_from_ip?(record.ip_address))
|
||||||
|
record.errors.add(attribute, options[:message] || I18n.t('user.ip_address.blocked'))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
require "spec_helper"
|
||||||
|
require "spam_handler"
|
||||||
|
|
||||||
|
describe SpamHandler do
|
||||||
|
|
||||||
|
describe "#should_prevent_registration_from_ip?" do
|
||||||
|
|
||||||
|
it "works" do
|
||||||
|
# max_new_accounts_per_registration_ip = 0 disables the check
|
||||||
|
SiteSetting.stubs(:max_new_accounts_per_registration_ip).returns(0)
|
||||||
|
|
||||||
|
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[1])
|
||||||
|
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0])
|
||||||
|
|
||||||
|
# only prevents registration for TL0
|
||||||
|
SiteSetting.stubs(:max_new_accounts_per_registration_ip).returns(2)
|
||||||
|
|
||||||
|
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[1])
|
||||||
|
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0])
|
||||||
|
|
||||||
|
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[1])
|
||||||
|
-> { Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0]) }.should raise_error(ActiveRecord::RecordInvalid)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe AllowedIpAddressValidator do
|
describe AllowedIpAddressValidator do
|
||||||
|
|
||||||
let(:record) { Fabricate.build(:user, ip_address: '99.232.23.123') }
|
let(:record) { Fabricate.build(:user, trust_level: TrustLevel[0], ip_address: '99.232.23.123') }
|
||||||
let(:validator) { described_class.new({attributes: :ip_address}) }
|
let(:validator) { described_class.new({attributes: :ip_address}) }
|
||||||
subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) }
|
subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) }
|
||||||
|
|
||||||
|
@ -14,6 +14,14 @@ describe AllowedIpAddressValidator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "ip address isn't allowed for registration" do
|
||||||
|
it 'should add an error' do
|
||||||
|
SpamHandler.stubs(:should_prevent_registration_from_ip?).returns(true)
|
||||||
|
validate
|
||||||
|
record.errors[:ip_address].should be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "ip address should not be blocked" do
|
context "ip address should not be blocked" do
|
||||||
it "shouldn't add an error" do
|
it "shouldn't add an error" do
|
||||||
ScreenedIpAddress.stubs(:should_block?).returns(false)
|
ScreenedIpAddress.stubs(:should_block?).returns(false)
|
||||||
|
@ -31,4 +39,4 @@ describe AllowedIpAddressValidator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue