Class: IpDetector

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
app/lib/ip_detector.rb

Overview

This utility class will assist with the detection of WarmlyYours IP addresses
Use the constants to define fixed network blocks
Employee ips will be pulled from last login info in the last 15 days.

Constant Summary collapse

WY_CA_IP_BLOCKS =

Wy ca ip blocks.

[
  '172.20.30.0/24',
  '172.20.41.0/24',
  '172.20.31.0/24',
  '69.165.131.68/32',
  '173.212.185.65/32', # Richmond Hill Wan 2 (terago)
  '72.139.108.22/32',
  '72.138.19.30/32' # Richmond Hill Wan1 (venture)
].map { |subnet| IPAddr.new(subnet) }.freeze
WY_US_IP_BLOCKS =

Wy us ip blocks.

[
  '172.20.0.0/16',
  '127.0.0.1/24',
  '192.168.0.0/16',
  '50.200.53.120/30',
  '98.193.60.229/32' # LZ office WAN 2 (Comcast, static) — warehouse side egresses here
].map { |subnet| IPAddr.new(subnet) }.freeze
WY_IN_IP_BLOCKS =

Wy india office (Hyderabad contractor team) ip blocks.

[
  '183.82.96.242/32'
].map { |subnet| IPAddr.new(subnet) }.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.office_location(ip) ⇒ Symbol?

Which fixed office network an IP belongs to. Deliberately checks only the
static office blocks, NOT employee_ip_blocks — those are recent sign-in
IPs (mostly homes), which answer "is this one of our people", not "are
they in the building".

Parameters:

  • ip (String, IPAddr)

Returns:

  • (Symbol, nil)

    :ca_office, :us_office, :in_office, :remote — nil for an unparsable IP



63
64
65
66
67
68
69
70
71
72
# File 'app/lib/ip_detector.rb', line 63

def self.office_location(ip)
  addr = IPAddr.new(ip.to_s)
  return :ca_office if WY_CA_IP_BLOCKS.any? { |block| block.include?(addr) }
  return :us_office if WY_US_IP_BLOCKS.any? { |block| block.include?(addr) }
  return :in_office if WY_IN_IP_BLOCKS.any? { |block| block.include?(addr) }

  :remote
rescue IPAddr::InvalidAddressError
  nil
end

.warmlyyours_canada_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
# File 'app/lib/ip_detector.rb', line 78

def self.warmlyyours_canada_ip?(ip)
  instance.warmlyyours_canada_ip?(ip)
end

.warmlyyours_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'app/lib/ip_detector.rb', line 74

def self.warmlyyours_ip?(ip)
  instance.warmlyyours_ip?(ip)
end

Instance Method Details

#cloudflare_ip_list_itemsObject

Build the Cloudflare IP list payload for $warmlyyours_users.
Returns an array of { ip:, comment: } hashes ready for the Lists API.
Filters out private/loopback ranges that Cloudflare would reject.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'app/lib/ip_detector.rb', line 93

def cloudflare_ip_list_items
  items = []

  WY_CA_IP_BLOCKS.each do |block|
    next if private_range?(block)

    items << { ip: block.to_range.first.to_s + cidr_suffix(block), comment: 'WY Canada Office' }
  end

  WY_US_IP_BLOCKS.each do |block|
    next if private_range?(block)

    items << { ip: block.to_range.first.to_s + cidr_suffix(block), comment: 'WY US Office' }
  end

  WY_IN_IP_BLOCKS.each do |block|
    next if private_range?(block)

    items << { ip: block.to_range.first.to_s + cidr_suffix(block), comment: 'WY India Office' }
  end

  employee_rows = base_scope.distinct.pluck(:current_sign_in_ip, :email)
  employee_rows.each do |ip_str, email|
    next if ip_str.blank?

    begin
      addr = IPAddr.new(ip_str)
      next if private_range?(addr)
    rescue IPAddr::InvalidAddressError
      next
    end

    items << { ip: ip_str, comment: "Employee: #{email.presence}".truncate(500) }
  end

  items.uniq { |item| item[:ip] }
end

#employee_ca_ip_blocksObject



34
35
36
37
38
39
# File 'app/lib/ip_detector.rb', line 34

def employee_ca_ip_blocks
  ips = safe_cache_fetch(%i[ip_detector employee_ca_ips]) do
    base_scope.joins(:employee).where(Employee[:company_id].eq(Company::CAN)).distinct.pluck(:current_sign_in_ip)
  end
  ips.map { |subnet| IPAddr.new subnet }
end

#employee_ip_blocksObject



41
42
43
44
45
46
# File 'app/lib/ip_detector.rb', line 41

def employee_ip_blocks
  ips = safe_cache_fetch(%i[ip_detector employee_ips]) do
    base_scope.distinct.pluck(:current_sign_in_ip)
  end
  ips.map { |subnet| IPAddr.new subnet }
end

#warmlyyours_ca_ip_blocksObject



52
53
54
# File 'app/lib/ip_detector.rb', line 52

def warmlyyours_ca_ip_blocks
  (WY_CA_IP_BLOCKS + employee_ca_ip_blocks).compact.uniq
end

#warmlyyours_canada_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'app/lib/ip_detector.rb', line 86

def warmlyyours_canada_ip?(ip)
  warmlyyours_ca_ip_blocks.any? { |block| block.include?(ip) }
end

#warmlyyours_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
# File 'app/lib/ip_detector.rb', line 82

def warmlyyours_ip?(ip)
  warmlyyours_ip_blocks.any? { |block| block.include?(ip) }
end

#warmlyyours_ip_blocksObject



48
49
50
# File 'app/lib/ip_detector.rb', line 48

def warmlyyours_ip_blocks
  (WY_CA_IP_BLOCKS + WY_US_IP_BLOCKS + WY_IN_IP_BLOCKS + employee_ip_blocks).compact.uniq
end