Add `InetContainer` with scopes of `containing` and `contained` (#32802)

pull/2894/head
Matt Jankowski 2024-11-08 05:08:36 -05:00 committed by GitHub
parent df54196a14
commit bde0f1239a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 18 additions and 6 deletions

View File

@ -16,6 +16,6 @@ module RegistrationHelper
end end
def ip_blocked?(remote_ip) def ip_blocked?(remote_ip)
IpBlock.where(severity: :sign_up_block).exists?(['ip >>= ?', remote_ip.to_s]) IpBlock.where(severity: :sign_up_block).containing(remote_ip.to_s).exists?
end end
end end

View File

@ -19,7 +19,7 @@ class SuspiciousSignInDetector
end end
def previously_seen_ip?(request) def previously_seen_ip?(request)
@user.ips.exists?(['ip <<= ?', masked_ip(request)]) @user.ips.contained_by(masked_ip(request)).exists?
end end
def freshly_signed_up? def freshly_signed_up?

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
module InetContainer
extend ActiveSupport::Concern
included do
scope :containing, ->(value) { where('ip >>= ?', value) }
scope :contained_by, ->(value) { where('ip <<= ?', value) }
end
end

View File

@ -17,6 +17,7 @@ class IpBlock < ApplicationRecord
CACHE_KEY = 'blocked_ips' CACHE_KEY = 'blocked_ips'
include Expireable include Expireable
include InetContainer
include Paginable include Paginable
enum :severity, { enum :severity, {

View File

@ -125,7 +125,7 @@ class User < ApplicationRecord
scope :signed_in_recently, -> { where(current_sign_in_at: ACTIVE_DURATION.ago..) } scope :signed_in_recently, -> { where(current_sign_in_at: ACTIVE_DURATION.ago..) }
scope :not_signed_in_recently, -> { where(current_sign_in_at: ...ACTIVE_DURATION.ago) } scope :not_signed_in_recently, -> { where(current_sign_in_at: ...ACTIVE_DURATION.ago) }
scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) } scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) }
scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value).group('users.id') } scope :matches_ip, ->(value) { left_joins(:ips).merge(IpBlock.contained_by(value)).group('users.id') }
before_validation :sanitize_role before_validation :sanitize_role
before_create :set_approved before_create :set_approved
@ -444,7 +444,7 @@ class User < ApplicationRecord
end end
def sign_up_from_ip_requires_approval? def sign_up_from_ip_requires_approval?
sign_up_ip.present? && IpBlock.severity_sign_up_requires_approval.exists?(['ip >>= ?', sign_up_ip.to_s]) sign_up_ip.present? && IpBlock.severity_sign_up_requires_approval.containing(sign_up_ip.to_s).exists?
end end
def sign_up_email_requires_approval? def sign_up_email_requires_approval?

View File

@ -11,6 +11,7 @@
class UserIp < ApplicationRecord class UserIp < ApplicationRecord
include DatabaseViewRecord include DatabaseViewRecord
include InetContainer
self.primary_key = :user_id self.primary_key = :user_id

View File

@ -80,9 +80,9 @@ module Mastodon::CLI
end end
ip_blocks = if options[:force] ip_blocks = if options[:force]
IpBlock.where('ip >>= ?', address) IpBlock.containing(address)
else else
IpBlock.where('ip <<= ?', address) IpBlock.contained_by(address)
end end
if ip_blocks.empty? if ip_blocks.empty?