reputable 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10ace4d8c54f4fe4bcf4a1a2bbba66015dbff719b353ee9331e9f3ad56400c69
4
- data.tar.gz: d3044684df204b097e1a739f29425947306ed9c5533d4a20c66b1064dafc8892
3
+ metadata.gz: '09fa87a88ec9b2c8b0cf010e6291c7386f32ed2ceaf55b80c34cd831a75b07f4'
4
+ data.tar.gz: ab4eb854a090b4c971722932fffe097ae1f52a8feaf1525b8bf2ed6fc9462411
5
5
  SHA512:
6
- metadata.gz: d3e578a48821efe6610ee60d0560c366fa2136e4fcbc93274822abda5cfb776e0aa924fe7877ff3c2164b177328fe630734fbf5d972103d741d5fc5f8db3f65b
7
- data.tar.gz: 077b28a5af24557650e4e82759f63656532da2586f200b68a1dee2ebb6315c238efa44bf8dbb5a58634eb3cecb1819649772abeb65f78efcd064339453d842e3
6
+ metadata.gz: 45143f6b28ebc3e70810a0a58830b6136c1575a6c4888ad5a680dfc1d3cf09ec9e619ef104873883ecc083324cd083dbe769648494701eedc3f488c5215eb7e6
7
+ data.tar.gz: b1c8722bc5e7c4c9cc4080fb922a0a245c0a42996e5ab4abd6e984e33943f50da0d7d8f55873096630bafd93ec53bc7a703049ab36fc63c8fd68af9cf8f23f43
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reputable (0.1.10)
4
+ reputable (0.1.12)
5
5
  connection_pool (~> 2.2)
6
6
  redis (>= 4.0, < 6.0)
7
7
 
data/README.md CHANGED
@@ -269,7 +269,15 @@ config.middleware.use Reputable::Middleware,
269
269
  },
270
270
 
271
271
  # Async mode (default: true) - tracking runs in background thread
272
- async: true
272
+ async: true,
273
+
274
+ # Request tracking (default: false) - push request context to Redis
275
+ # Falls back to ENV REPUTABLE_TRACK_REQUEST if not set
276
+ track_request: true,
277
+
278
+ # Expose reputation flags in request env for views/controllers (default: true)
279
+ # Sets request.env['reputable.ignore_analytics'] when status is untrusted_ignore
280
+ expose_reputation: true
273
281
  ```
274
282
 
275
283
  ### Optional Reputation Gate
@@ -328,6 +336,11 @@ if current_ip_trusted?
328
336
  # Skip CAPTCHA, higher rate limits
329
337
  end
330
338
 
339
+ # View/helper flag for untrusted_ignore
340
+ if reputable_ignore_analytics?
341
+ # Skip analytics / tracking in views
342
+ end
343
+
331
344
  if current_ip_blocked?
332
345
  render status: 403
333
346
  return
@@ -556,6 +569,11 @@ The gem is designed with resilience as the top priority:
556
569
  REPUTABLE_ENABLED=false
557
570
  ```
558
571
 
572
+ ```bash
573
+ # Enable request tracking (push request context to Redis)
574
+ REPUTABLE_TRACK_REQUEST=true
575
+ ```
576
+
559
577
  ```ruby
560
578
  # Check in code
561
579
  if Reputable.enabled?
@@ -644,7 +662,7 @@ expect(Reputable.lookup_ip('1.2.3.4')).to be_nil
644
662
 
645
663
  ## How It Works
646
664
 
647
- 1. **Request Tracking**: Your Rails app pushes request data to Redis buffers
665
+ 1. **Request Tracking**: Your Rails app pushes request data to Redis buffers (enable with `track_request: true` or `REPUTABLE_TRACK_REQUEST=true`)
648
666
  2. **Async Processing**: Reputable API processes buffers asynchronously
649
667
  3. **Behavioral Analysis**: Requests go through classification and pattern analysis
650
668
  4. **Reputation Storage**: Scores stored in Redis for O(1) lookups
@@ -44,7 +44,9 @@ module Reputable
44
44
  @skip_if = options[:skip_if]
45
45
  @tag_builder = options[:tag_builder]
46
46
  @async = options.fetch(:async, true)
47
+ @track_request = options.key?(:track_request) ? options[:track_request] : nil
47
48
  @reputation_gate = options.fetch(:reputation_gate, false)
49
+ @expose_reputation = options.fetch(:expose_reputation, true)
48
50
  @challenge_action = options.fetch(:challenge_action, :verify)
49
51
  @block_action = options.fetch(:block_action, :blocked_page_remote)
50
52
  @challenge_redirect_status = options.fetch(:challenge_redirect_status, 302)
@@ -72,6 +74,9 @@ module Reputable
72
74
  return gate_response
73
75
  end
74
76
 
77
+ # Optional: expose reputation context for views/controllers
78
+ safe_apply_reputation_context(env) if @expose_reputation
79
+
75
80
  # ALWAYS process the request first - tracking must never block
76
81
  status, headers, response = @app.call(env)
77
82
 
@@ -96,9 +101,9 @@ module Reputable
96
101
  end
97
102
 
98
103
  def enforce_reputation_gate(env)
99
- ip = extract_ip(env)
100
- status = Reputable::Reputation.lookup_ip(ip)
104
+ status = reputation_status(env)
101
105
  return nil if status.nil?
106
+ ip = env["reputable.ip"] || extract_ip(env)
102
107
 
103
108
  case status
104
109
  when "untrusted_block"
@@ -114,6 +119,9 @@ module Reputable
114
119
  def safe_track_request(env)
115
120
  # Skip if disabled globally
116
121
  return unless Reputable.enabled?
122
+
123
+ # Skip unless explicitly enabled
124
+ return unless track_request_enabled?
117
125
 
118
126
  # Skip if this request should be skipped
119
127
  return if skip_request?(env)
@@ -124,6 +132,17 @@ module Reputable
124
132
  Reputable.logger&.debug("Reputable middleware: #{e.class} - #{e.message}")
125
133
  end
126
134
 
135
+ def track_request_enabled?
136
+ return @track_request unless @track_request.nil?
137
+
138
+ env_value = ENV["REPUTABLE_TRACK_REQUEST"]
139
+ return false if env_value.nil?
140
+
141
+ !%w[0 false no off disabled].include?(env_value.to_s.downcase)
142
+ rescue StandardError
143
+ false
144
+ end
145
+
127
146
  def handle_verification_return(env)
128
147
  request = Rack::Request.new(env)
129
148
  # Quick check to avoid overhead
@@ -133,6 +152,10 @@ module Reputable
133
152
 
134
153
  if Reputable.verify_redirect_return(request.params)
135
154
  env["reputable.verified"] = true
155
+ ignore_analytics = request.params["reputable_ignore_analytics"]
156
+ unless ignore_analytics.nil?
157
+ env["reputable.ignore_analytics"] = ignore_analytics.to_s == "true"
158
+ end
136
159
 
137
160
  # Store in session if available
138
161
  if env["rack.session"]
@@ -255,6 +278,30 @@ module Reputable
255
278
  Reputable::BlockedPage.response(**options)
256
279
  end
257
280
 
281
+ def safe_apply_reputation_context(env)
282
+ return unless Reputable.enabled?
283
+ return if skip_request?(env)
284
+
285
+ reputation_status(env)
286
+ rescue StandardError => e
287
+ Reputable.logger&.debug("Reputable reputation context: #{e.class} - #{e.message}")
288
+ end
289
+
290
+ def reputation_status(env)
291
+ return env["reputable.reputation_status"] if env.key?("reputable.reputation_status")
292
+
293
+ ip = extract_ip(env)
294
+ env["reputable.ip"] = ip
295
+ status = Reputable::Reputation.lookup_ip(ip)
296
+ env["reputable.reputation_status"] = status
297
+ env["reputable.ignore_analytics"] = (status == "untrusted_ignore")
298
+ status
299
+ rescue StandardError
300
+ env["reputable.reputation_status"] = nil
301
+ env["reputable.ignore_analytics"] = false
302
+ nil
303
+ end
304
+
258
305
  def blocked_page_options
259
306
  config = Reputable.configuration
260
307
  defaults = {
@@ -8,7 +8,7 @@ module Reputable
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
- helper_method :reputable_verified? if respond_to?(:helper_method)
11
+ helper_method :reputable_verified?, :reputable_ignore_analytics? if respond_to?(:helper_method)
12
12
  end
13
13
 
14
14
  # Track the current request with optional extra tags
@@ -88,6 +88,17 @@ module Reputable
88
88
  Reputable::Reputation.lookup_ip(request.remote_ip)
89
89
  end
90
90
 
91
+ # Check if analytics should be ignored for this request
92
+ # Uses middleware-populated flag when available, falls back to lookup.
93
+ def reputable_ignore_analytics?
94
+ value = request.env["reputable.ignore_analytics"]
95
+ return value unless value.nil?
96
+
97
+ current_ip_status == "untrusted_ignore"
98
+ rescue StandardError
99
+ false
100
+ end
101
+
91
102
  # ========================================
92
103
  # Verification redirect helpers
93
104
  # ========================================
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Reputable
4
- VERSION = "0.1.10"
4
+ VERSION = "0.1.12"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reputable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reputable
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-12-30 00:00:00.000000000 Z
11
+ date: 2025-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis