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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +20 -2
- data/lib/reputable/middleware.rb +49 -2
- data/lib/reputable/rails.rb +12 -1
- data/lib/reputable/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '09fa87a88ec9b2c8b0cf010e6291c7386f32ed2ceaf55b80c34cd831a75b07f4'
|
|
4
|
+
data.tar.gz: ab4eb854a090b4c971722932fffe097ae1f52a8feaf1525b8bf2ed6fc9462411
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 45143f6b28ebc3e70810a0a58830b6136c1575a6c4888ad5a680dfc1d3cf09ec9e619ef104873883ecc083324cd083dbe769648494701eedc3f488c5215eb7e6
|
|
7
|
+
data.tar.gz: b1c8722bc5e7c4c9cc4080fb922a0a245c0a42996e5ab4abd6e984e33943f50da0d7d8f55873096630bafd93ec53bc7a703049ab36fc63c8fd68af9cf8f23f43
|
data/Gemfile.lock
CHANGED
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
|
data/lib/reputable/middleware.rb
CHANGED
|
@@ -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
|
-
|
|
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 = {
|
data/lib/reputable/rails.rb
CHANGED
|
@@ -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
|
# ========================================
|
data/lib/reputable/version.rb
CHANGED
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.
|
|
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-
|
|
11
|
+
date: 2025-12-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|