From bde0f1239ab016a6dfc8229ba579c5e2cf96a8e6 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 8 Nov 2024 05:08:36 -0500 Subject: [PATCH] Add `InetContainer` with scopes of `containing` and `contained` (#32802) --- app/helpers/registration_helper.rb | 2 +- app/lib/suspicious_sign_in_detector.rb | 2 +- app/models/concerns/inet_container.rb | 10 ++++++++++ app/models/ip_block.rb | 1 + app/models/user.rb | 4 ++-- app/models/user_ip.rb | 1 + lib/mastodon/cli/ip_blocks.rb | 4 ++-- 7 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 app/models/concerns/inet_container.rb diff --git a/app/helpers/registration_helper.rb b/app/helpers/registration_helper.rb index ef5462ac88..0f141c4359 100644 --- a/app/helpers/registration_helper.rb +++ b/app/helpers/registration_helper.rb @@ -16,6 +16,6 @@ module RegistrationHelper end 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 diff --git a/app/lib/suspicious_sign_in_detector.rb b/app/lib/suspicious_sign_in_detector.rb index 74f49aa558..60e5fdad4f 100644 --- a/app/lib/suspicious_sign_in_detector.rb +++ b/app/lib/suspicious_sign_in_detector.rb @@ -19,7 +19,7 @@ class SuspiciousSignInDetector end def previously_seen_ip?(request) - @user.ips.exists?(['ip <<= ?', masked_ip(request)]) + @user.ips.contained_by(masked_ip(request)).exists? end def freshly_signed_up? diff --git a/app/models/concerns/inet_container.rb b/app/models/concerns/inet_container.rb new file mode 100644 index 0000000000..da03bcc5d7 --- /dev/null +++ b/app/models/concerns/inet_container.rb @@ -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 diff --git a/app/models/ip_block.rb b/app/models/ip_block.rb index 5ed4d2a846..416ae38382 100644 --- a/app/models/ip_block.rb +++ b/app/models/ip_block.rb @@ -17,6 +17,7 @@ class IpBlock < ApplicationRecord CACHE_KEY = 'blocked_ips' include Expireable + include InetContainer include Paginable enum :severity, { diff --git a/app/models/user.rb b/app/models/user.rb index 8827a8fbd6..9a215669b9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -125,7 +125,7 @@ class User < ApplicationRecord 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 :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_create :set_approved @@ -444,7 +444,7 @@ class User < ApplicationRecord end 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 def sign_up_email_requires_approval? diff --git a/app/models/user_ip.rb b/app/models/user_ip.rb index a6da2c0740..25aa81ccd4 100644 --- a/app/models/user_ip.rb +++ b/app/models/user_ip.rb @@ -11,6 +11,7 @@ class UserIp < ApplicationRecord include DatabaseViewRecord + include InetContainer self.primary_key = :user_id diff --git a/lib/mastodon/cli/ip_blocks.rb b/lib/mastodon/cli/ip_blocks.rb index ef24f2e047..f1f40c99ce 100644 --- a/lib/mastodon/cli/ip_blocks.rb +++ b/lib/mastodon/cli/ip_blocks.rb @@ -80,9 +80,9 @@ module Mastodon::CLI end ip_blocks = if options[:force] - IpBlock.where('ip >>= ?', address) + IpBlock.containing(address) else - IpBlock.where('ip <<= ?', address) + IpBlock.contained_by(address) end if ip_blocks.empty?