reputable 0.1.19 → 0.1.20

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: ffc332f72eed47a768d73dae0cac8a2efbbf73de0b41115fcf064ac046cfcc93
4
- data.tar.gz: 42abaea0b5b896a54611ebc43946751fc2a303c62f94d4d199345afe846d88a1
3
+ metadata.gz: 6060e2e9fd11f70f0722c0f9683c1fe334f75aced2791dfde4a6336b5f08b429
4
+ data.tar.gz: 0c92fbbcc06ec6473e4af1c64b87003c92555c2137643d021b149aa3416a0acc
5
5
  SHA512:
6
- metadata.gz: f2fd4c2f08d86b89a19d0676d372f4b63f71ad70fe6c426c313e25cf48786544c6ca58ae729981ed4525d9dd8881c757b8c07810ea7984e405c133e82608ed23
7
- data.tar.gz: 8e16c4839f384c4dbd4709996efab5e542a8f792522e283b2f3fcdb2db1eab2f13e149556f2f369ef23dc73d2cef7da83515fb95e69eca8a8e86de041afc4544
6
+ metadata.gz: 1fee3bf3e197dbad2377296119ef87d43657f37a008982af4c14b15f39fcff0c59c13054a8d132b5c568cd31f695183e58b54ab34affac94a342893de7ace262
7
+ data.tar.gz: 43a20b7d26fcc4a0464e0c29c15be6cf25874335ea841c4b77c704dca2f4b4fdf94d42cd60ec2638ea29c3cbfdefef1bdf5bd161b22c907275853866e83cf703
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reputable (0.1.19)
4
+ reputable (0.1.20)
5
5
  connection_pool (~> 2.2)
6
6
  redis (>= 4.0, < 6.0)
7
7
 
data/README.md CHANGED
@@ -528,6 +528,58 @@ Reputable.lookup_reputation(:asn, "15169")
528
528
 
529
529
  **Note:** ASNs are normalized automatically - both `"15169"` and `"AS15169"` work.
530
530
 
531
+ ### Enforcing ASN Reputation in Controllers
532
+
533
+ If you want to challenge or block requests based on ASN reputation (independent of the middleware's IP-based gate), add a controller filter:
534
+
535
+ ```ruby
536
+ # app/controllers/application_controller.rb
537
+ class ApplicationController < ActionController::Base
538
+ before_action :enforce_asn_reputation
539
+
540
+ private
541
+
542
+ def enforce_asn_reputation
543
+ return if reputable_verified?
544
+
545
+ asn = request_asn
546
+ return unless asn
547
+
548
+ if Reputable.challenged_asn?(asn)
549
+ redirect_to Reputable.verification_url(
550
+ return_url: request.original_url,
551
+ session_id: session.id.to_s
552
+ ), status: 302, allow_other_host: true
553
+ elsif Reputable.blocked_asn?(asn)
554
+ redirect_to Reputable.blocked_page_url, status: 302, allow_other_host: true
555
+ end
556
+ end
557
+
558
+ def reputable_verified?
559
+ session[:reputable_verified] || session[:reputable_verified_at].present?
560
+ end
561
+
562
+ def request_asn
563
+ # Option 1: From a header (if HAProxy/Cloudflare provides it)
564
+ # request.headers["X-ASN"]&.sub(/^AS/i, "")
565
+
566
+ # Option 2: From your own GeoIP lookup
567
+ # GeoIP.lookup(request.remote_ip)&.asn
568
+
569
+ # Option 3: Stored in request.env from earlier middleware
570
+ # request.env["app.asn"]
571
+ end
572
+ end
573
+ ```
574
+
575
+ To apply only to specific controllers or actions:
576
+
577
+ ```ruby
578
+ class CheckoutController < ApplicationController
579
+ before_action :enforce_asn_reputation, only: [:create]
580
+ end
581
+ ```
582
+
531
583
  ---
532
584
 
533
585
  ## User Verification & Trust Flow
@@ -98,6 +98,7 @@ module Reputable
98
98
  def safe_reputation_gate(env)
99
99
  return nil unless @reputation_gate
100
100
  return nil unless Reputable.enabled?
101
+ return nil unless Reputable.operational?
101
102
  return nil if skip_request?(env)
102
103
 
103
104
  enforce_reputation_gate(env)
@@ -159,6 +159,9 @@ module Reputable
159
159
  )
160
160
  return if reputable_verified?(session_key: session_key)
161
161
 
162
+ # Skip redirect when circuit is open — the Reputable server is likely unreachable
163
+ return unless Reputable.operational?
164
+
162
165
  # Check for new format (reputable_s) or legacy format (reputable_signature)
163
166
  if params[:reputable_s] || params[:reputable_signature]
164
167
  if Reputable.verify_redirect_return(params)
@@ -207,6 +210,9 @@ module Reputable
207
210
  blocked_message: nil,
208
211
  blocked_show_ip: true
209
212
  )
213
+ # Skip all gating when circuit is open — the Reputable server is likely unreachable
214
+ return unless Reputable.operational?
215
+
210
216
  if current_ip_blocked?
211
217
  render_reputable_blocked_page(
212
218
  status: blocked_status,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Reputable
4
- VERSION = "0.1.19"
4
+ VERSION = "0.1.20"
5
5
  end
data/lib/reputable.rb CHANGED
@@ -75,6 +75,28 @@ module Reputable
75
75
  !enabled?
76
76
  end
77
77
 
78
+ # Check if Reputable is operational (enabled AND circuit breaker is closed)
79
+ # Use this to guard redirect/gating decisions — when the circuit is open,
80
+ # the Reputable server is likely unreachable and redirects would fail.
81
+ # @return [Boolean] true if Reputable can be used, false otherwise
82
+ def operational?
83
+ return false unless enabled?
84
+ return false if Connection.circuit_open?
85
+ true
86
+ end
87
+
88
+ # Get a detailed status report for monitoring/debugging
89
+ # @return [Hash] status information
90
+ def status
91
+ {
92
+ enabled: enabled?,
93
+ operational: operational?,
94
+ circuit_breaker: Connection.circuit_open? ? "open" : "closed",
95
+ failure_count: Connection.failure_count,
96
+ circuit_opened_at: Connection.circuit_opened_at
97
+ }
98
+ end
99
+
78
100
  # Delegate tracking methods to Tracker
79
101
  def track_request(ip:, path:, **options)
80
102
  Tracker.track_request(ip: ip, path: path, **options)
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.19
4
+ version: 0.1.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reputable
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-03 00:00:00.000000000 Z
11
+ date: 2026-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -137,7 +137,6 @@ files:
137
137
  - lib/reputable/reputation.rb
138
138
  - lib/reputable/tracker.rb
139
139
  - lib/reputable/version.rb
140
- - reputable.gemspec
141
140
  homepage: https://github.com/reputable-click/reputable-rb
142
141
  licenses:
143
142
  - MIT
data/reputable.gemspec DELETED
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/reputable/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "reputable"
7
- spec.version = Reputable::VERSION
8
- spec.authors = ["Reputable"]
9
- spec.email = ["support@reputable.click"]
10
-
11
- spec.summary = "Ruby client for Reputable - bot detection and reputation scoring"
12
- spec.description = "Track requests and manage IP reputation through Redis/Dragonfly integration with Reputable"
13
- spec.homepage = "https://github.com/reputable-click/reputable-rb"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.7.0"
16
-
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = spec.homepage
19
- spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
-
21
- spec.files = Dir.chdir(__dir__) do
22
- `git ls-files -z`.split("\x0").reject do |f|
23
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}) || f.end_with?(".gem")
24
- end
25
- end
26
- spec.bindir = "exe"
27
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
- spec.require_paths = ["lib"]
29
-
30
- spec.add_dependency "redis", ">= 4.0", "< 6.0"
31
- spec.add_dependency "connection_pool", "~> 2.2"
32
-
33
- spec.add_development_dependency "bundler", "~> 2.0"
34
- spec.add_development_dependency "rake", "~> 13.0"
35
- spec.add_development_dependency "rspec", "~> 3.12"
36
- spec.add_development_dependency "rack", "~> 2.0"
37
- spec.add_development_dependency "rubocop", "~> 1.0"
38
- end