Class: Trackdown::Providers::BaseProvider

Inherits:
Object
  • Object
show all
Defined in:
lib/trackdown/providers/base_provider.rb

Class Method Summary collapse

Class Method Details

.available?(request: nil) ⇒ Boolean

Returns true if this provider can handle the given request/context

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


24
25
26
# File 'lib/trackdown/providers/base_provider.rb', line 24

def self.available?(request: nil)
  raise NotImplementedError, "#{self} must implement .available?"
end

.get_country_name(country_code) ⇒ Object

Helper to extract country name from country code using countries gem



77
78
79
80
81
82
83
84
# File 'lib/trackdown/providers/base_provider.rb', line 77

def self.get_country_name(country_code)
  return LocationResult::UNKNOWN unless country_code

  country = ISO3166::Country.new(country_code)
  country&.iso_short_name || country&.name || LocationResult::UNKNOWN
rescue StandardError
  LocationResult::UNKNOWN
end

.get_emoji_flag(country_code) ⇒ Object

Helper to get emoji flag from country code



68
69
70
71
72
73
74
# File 'lib/trackdown/providers/base_provider.rb', line 68

def self.get_emoji_flag(country_code)
  return LocationResult::UNKNOWN_FLAG unless country_code.is_a?(String)
  return LocationResult::UNKNOWN_FLAG unless /\A[A-Za-z]{2}\z/.match?(country_code)

  normalized_code = country_code.upcase
  normalized_code.tr('A-Z', "\u{1F1E6}-\u{1F1FF}")
end

.locate(ip, request: nil) ⇒ LocationResult

Locates the IP and returns a LocationResult

Parameters:

  • ip (String)

    The IP address to locate

  • request (ActionDispatch::Request, nil) (defaults to: nil)

    Optional Rails request object for header access

Returns:

Raises:

  • (NotImplementedError)


32
33
34
# File 'lib/trackdown/providers/base_provider.rb', line 32

def self.locate(ip, request: nil)
  raise NotImplementedError, "#{self} must implement .locate"
end

.parse_coordinate(value, range:) ⇒ Object

Parse an untrusted coordinate: a plain decimal within the given WGS-84 bounds, or nothing. The range check also settles NaN and Infinity, since a Range covers neither. https://www.rfc-editor.org/rfc/rfc5870#section-3.4.2



90
91
92
93
94
95
96
97
98
# File 'lib/trackdown/providers/base_provider.rb', line 90

def self.parse_coordinate(value, range:)
  return nil unless value.is_a?(String)

  decimal = value.strip
  return nil unless DECIMAL_COORDINATE_PATTERN.match?(decimal)

  coordinate = decimal.to_f
  range.cover?(coordinate) ? coordinate : nil
end

.provider_nameObject

How a result names this provider: the same symbol you'd set as config.provider, so result.provider_name == :cloudflare lines up with config.provider = :cloudflare.

Raises:

  • (NotImplementedError)


39
40
41
# File 'lib/trackdown/providers/base_provider.rb', line 39

def self.provider_name
  raise NotImplementedError, "#{self} must implement .provider_name"
end

.provider_sourceObject

Where this provider's answers physically come from, e.g. :cloudflare_request_headers or :maxmind_local_database.

Raises:

  • (NotImplementedError)


45
46
47
# File 'lib/trackdown/providers/base_provider.rb', line 45

def self.provider_source
  raise NotImplementedError, "#{self} must implement .provider_source"
end

.request_provenance(request) ⇒ Object

The provenance a request-backed provider stamps on every result.

The trust state is :unverified unless the host's own verifier vouches for the request. Trackdown never reads trust out of the headers themselves — anyone who can reach an unprotected origin can send those.



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/trackdown/providers/base_provider.rb', line 54

def self.request_provenance(request)
  source_was_verified = Trackdown.configuration.request_came_through_trusted_cdn_path?(
    request,
    provider_name: provider_name
  )

  {
    provider_name: provider_name,
    provider_source: provider_source,
    source_trust: source_was_verified ? :host_verified : :unverified
  }
end