Class: Reputable::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/reputable/configuration.rb

Overview

Configuration class for Reputable client

Supports TLS connections with automatic SSL error handling. All SSL/connection errors are caught and logged, never breaking your app.

Constant Summary collapse

DEFAULT_TTLS =

Default TTLs in seconds (0 = forever)

{
  trusted_verified: 0,          # Forever
  trusted_behavior: 365 * 24 * 3600, # 1 year
  untrusted_challenge: 7 * 24 * 3600, # 7 days
  untrusted_block: 7 * 24 * 3600,     # 7 days
  untrusted_ignore: 7 * 24 * 3600     # 7 days
}.freeze
DEFAULT_IP_HEADERS =

Default IP header priority (first match wins) Covers: Heroku, Cloudflare, AWS ALB/ELB, nginx, HAProxy, generic proxies

%w[
  HTTP_CF_CONNECTING_IP
  HTTP_X_FORWARDED_FOR
  HTTP_X_REAL_IP
  HTTP_TRUE_CLIENT_IP
  HTTP_X_CLIENT_IP
  HTTP_X_CLUSTER_CLIENT_IP
  HTTP_FORWARDED
  REMOTE_ADDR
].freeze
PRIVATE_IP_RANGES =

Common private/internal IP ranges to skip when parsing X-Forwarded-For

%w[
  127.0.0.0/8
  10.0.0.0/8
  172.16.0.0/12
  192.168.0.0/16
  ::1/128
  fc00::/7
  fe80::/10
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/reputable/configuration.rb', line 64

def initialize
  @redis_url = ENV.fetch("REPUTABLE_REDIS_URL", "redis://127.0.0.1:6379")
  @redis_options = {}
  @buffer_prefix = "reputable:buffer"
  @pool_size = Integer(ENV.fetch("REPUTABLE_POOL_SIZE", "5"))
  @pool_timeout = Float(ENV.fetch("REPUTABLE_POOL_TIMEOUT", "1.0"))
  @connect_timeout = Float(ENV.fetch("REPUTABLE_CONNECT_TIMEOUT", "0.5"))
  @read_timeout = Float(ENV.fetch("REPUTABLE_READ_TIMEOUT", "0.5"))
  @write_timeout = Float(ENV.fetch("REPUTABLE_WRITE_TIMEOUT", "0.5"))
  @default_ttls = DEFAULT_TTLS.dup
  @ssl_params = nil  # Use system defaults, or override for custom CA/certs
  @trusted_proxies = nil  # Additional trusted proxy IPs/ranges
  @ip_header_priority = DEFAULT_IP_HEADERS.dup
  @on_error = nil  # Optional error callback: ->(error, context) { ... }
  
  # Support multiple trusted keys (comma-separated), fallback to old secret key env var
  @trusted_keys = []
  if ENV["REPUTABLE_TRUSTED_KEYS"]
    @trusted_keys = ENV["REPUTABLE_TRUSTED_KEYS"].split(",").map(&:strip)
  elsif ENV["REPUTABLE_TRUSTED_KEY"]
    @trusted_keys = [ENV["REPUTABLE_TRUSTED_KEY"]]
  elsif ENV["REPUTABLE_SECRET_KEY"]
    @trusted_keys = [ENV["REPUTABLE_SECRET_KEY"]]
  end
  @base_url = ENV.fetch("REPUTABLE_BASE_URL", "https://api.reputable.click")
  @measurement_base_url = ENV["REPUTABLE_SIGNALS_BASE_URL"] || ENV["REPUTABLE_MEASURE_BASE_URL"]
  @measurement_customer_id = ENV["REPUTABLE_SIGNALS_CUSTOMER_ID"] || ENV["REPUTABLE_MEASURE_CUSTOMER_ID"]
  @measurement_result_jwks = parse_json_env("REPUTABLE_SIGNALS_JWKS") || parse_json_env("REPUTABLE_MEASURE_RESULT_JWKS")
  @measurement_audience = ENV.fetch("REPUTABLE_MEASURE_AUDIENCE", "reputable-measure")
  @signals_secret_key = ENV["REPUTABLE_SIGNALS_SECRET_KEY"]
  @signals_publishable_key = ENV["REPUTABLE_SIGNALS_PUBLISHABLE_KEY"]
  # Legacy capability-era settings; kept as readable attributes so old
  # initializers do not crash, but no longer used.
  @measurement_capability = ENV["REPUTABLE_MEASURE_CAPABILITY"]
  @measurement_private_jwk = parse_json_env("REPUTABLE_MEASURE_PRIVATE_JWK")
  @measurement_token_ttl = Integer(ENV.fetch("REPUTABLE_MEASURE_TOKEN_TTL", "120"))
  @site_name = ENV["REPUTABLE_SITE_NAME"]
  @support_email = ENV["REPUTABLE_SUPPORT_EMAIL"]
  @support_url = ENV["REPUTABLE_SUPPORT_URL"]
  @verbose = %w[1 true yes on].include?(ENV.fetch("REPUTABLE_VERBOSE", "").downcase)
end

Instance Attribute Details

#base_urlObject Also known as: verification_base_url

Returns the value of attribute base_url.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def base_url
  @base_url
end

#buffer_prefixObject

Returns the value of attribute buffer_prefix.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def buffer_prefix
  @buffer_prefix
end

#connect_timeoutObject

Returns the value of attribute connect_timeout.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def connect_timeout
  @connect_timeout
end

#default_ttlsObject

Returns the value of attribute default_ttls.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def default_ttls
  @default_ttls
end

#ip_header_priorityObject

Returns the value of attribute ip_header_priority.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def ip_header_priority
  @ip_header_priority
end

#measurement_audienceObject

Returns the value of attribute measurement_audience.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_audience
  @measurement_audience
end

#measurement_base_urlObject

Returns the value of attribute measurement_base_url.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_base_url
  @measurement_base_url
end

#measurement_capabilityObject

Returns the value of attribute measurement_capability.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_capability
  @measurement_capability
end

#measurement_customer_idObject

Returns the value of attribute measurement_customer_id.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_customer_id
  @measurement_customer_id
end

#measurement_private_jwkObject

Returns the value of attribute measurement_private_jwk.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_private_jwk
  @measurement_private_jwk
end

#measurement_result_jwksObject

Returns the value of attribute measurement_result_jwks.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_result_jwks
  @measurement_result_jwks
end

#measurement_token_ttlObject

Returns the value of attribute measurement_token_ttl.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def measurement_token_ttl
  @measurement_token_ttl
end

#on_errorObject

Returns the value of attribute on_error.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def on_error
  @on_error
end

#pool_sizeObject

Returns the value of attribute pool_size.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def pool_size
  @pool_size
end

#pool_timeoutObject

Returns the value of attribute pool_timeout.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def pool_timeout
  @pool_timeout
end

#read_timeoutObject

Returns the value of attribute read_timeout.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def read_timeout
  @read_timeout
end

#redis_optionsObject

Returns the value of attribute redis_options.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def redis_options
  @redis_options
end

#redis_urlObject

Returns the value of attribute redis_url.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def redis_url
  @redis_url
end

#reputation_buffer_keyObject

Returns the value of attribute reputation_buffer_key.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def reputation_buffer_key
  @reputation_buffer_key
end

#request_buffer_keyObject

Returns the value of attribute request_buffer_key.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def request_buffer_key
  @request_buffer_key
end

#signals_publishable_keyObject

Returns the value of attribute signals_publishable_key.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def signals_publishable_key
  @signals_publishable_key
end

#signals_secret_keyObject

Returns the value of attribute signals_secret_key.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def signals_secret_key
  @signals_secret_key
end

#site_nameObject

Returns the value of attribute site_name.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def site_name
  @site_name
end

#ssl_paramsObject

Returns the value of attribute ssl_params.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def ssl_params
  @ssl_params
end

#support_emailObject

Returns the value of attribute support_email.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def support_email
  @support_email
end

#support_urlObject

Returns the value of attribute support_url.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def support_url
  @support_url
end

#trusted_keysObject

Returns the value of attribute trusted_keys.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def trusted_keys
  @trusted_keys
end

#trusted_proxiesObject

Returns the value of attribute trusted_proxies.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def trusted_proxies
  @trusted_proxies
end

#verboseObject

Returns the value of attribute verbose.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def verbose
  @verbose
end

#write_timeoutObject

Returns the value of attribute write_timeout.



13
14
15
# File 'lib/reputable/configuration.rb', line 13

def write_timeout
  @write_timeout
end

Instance Method Details

#default_ttl_for(status) ⇒ Object



139
140
141
142
# File 'lib/reputable/configuration.rb', line 139

def default_ttl_for(status)
  status_sym = status.to_sym
  @default_ttls[status_sym] || DEFAULT_TTLS[:untrusted_challenge]
end

#effective_ssl_paramsObject

Build SSL params for Redis connection Merges custom ssl_params with sensible defaults



160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/reputable/configuration.rb', line 160

def effective_ssl_params
  return nil unless tls?
  
  defaults = {
    verify_mode: OpenSSL::SSL::VERIFY_PEER
  }
  
  # Allow disabling SSL verification via ENV (not recommended for production)
  if ENV["REPUTABLE_SSL_VERIFY"] == "false"
    defaults[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
  end
  
  ssl_params ? defaults.merge(ssl_params) : defaults
end

#enabled?Boolean

Check if Reputable is enabled (can be disabled via ENV)

Returns:

  • (Boolean)


124
125
126
127
128
129
# File 'lib/reputable/configuration.rb', line 124

def enabled?
  env_value = ENV["REPUTABLE_ENABLED"]
  return true if env_value.nil?  # Enabled by default
  
  !%w[0 false no off disabled].include?(env_value.to_s.downcase)
end

#parse_json_env(name) ⇒ Object



144
145
146
147
148
149
150
151
# File 'lib/reputable/configuration.rb', line 144

def parse_json_env(name)
  raw = ENV[name]
  return nil if raw.nil? || raw.empty?

  JSON.parse(raw)
rescue JSON::ParserError
  nil
end

#private_ip?(ip) ⇒ Boolean

Check if an IP is private/internal

Returns:

  • (Boolean)


181
182
183
184
185
186
187
188
# File 'lib/reputable/configuration.rb', line 181

def private_ip?(ip)
  return true if ip.nil? || ip.empty?
  
  addr = IPAddr.new(ip)
  private_ip_ranges.any? { |range| range.include?(addr) }
rescue IPAddr::InvalidAddressError
  false
end

#private_ip_rangesObject

Parse private IP ranges for filtering X-Forwarded-For



176
177
178
# File 'lib/reputable/configuration.rb', line 176

def private_ip_ranges
  @private_ip_ranges ||= PRIVATE_IP_RANGES.map { |cidr| IPAddr.new(cidr) }
end

#secret_keyObject

Alias for backward compatibility



107
108
109
# File 'lib/reputable/configuration.rb', line 107

def secret_key
  @trusted_keys.first
end

#secret_key=(key) ⇒ Object



111
112
113
# File 'lib/reputable/configuration.rb', line 111

def secret_key=(key)
  @trusted_keys = [key]
end

#tls?Boolean

Check if Redis URL uses TLS (rediss:// scheme)

Returns:

  • (Boolean)


154
155
156
# File 'lib/reputable/configuration.rb', line 154

def tls?
  redis_url&.start_with?("rediss://")
end