reputable 0.1.17 → 0.1.19

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: 8767ca87c7fdd5abc6584e738599020cbd6977bc6193371caeef1425eedb8dfd
4
- data.tar.gz: 5196f00349ec3b380bec72db3b98c5f09d08965d297e7f43a8c639b9d1eed3dd
3
+ metadata.gz: ffc332f72eed47a768d73dae0cac8a2efbbf73de0b41115fcf064ac046cfcc93
4
+ data.tar.gz: 42abaea0b5b896a54611ebc43946751fc2a303c62f94d4d199345afe846d88a1
5
5
  SHA512:
6
- metadata.gz: 36285df97965903af8e913d3f0937969ae4e48399f0468fd2e00b22d3b0e7c6d50d51682d9ec82a31483729ca7f0d69d4d0ec47115b12dce62ff01948d18b3ec
7
- data.tar.gz: 6aea15486988795b5ce444581be796e33d15906c871f5cc28208d876b0604053603f455f8d16536b4879773991905f85882f56b4fed47d85b71b1ea9abb34a42
6
+ metadata.gz: f2fd4c2f08d86b89a19d0676d372f4b63f71ad70fe6c426c313e25cf48786544c6ca58ae729981ed4525d9dd8881c757b8c07810ea7984e405c133e82608ed23
7
+ data.tar.gz: 8e16c4839f384c4dbd4709996efab5e542a8f792522e283b2f3fcdb2db1eab2f13e149556f2f369ef23dc73d2cef7da83515fb95e69eca8a8e86de041afc4544
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reputable (0.1.17)
4
+ reputable (0.1.19)
5
5
  connection_pool (~> 2.2)
6
6
  redis (>= 4.0, < 6.0)
7
7
 
data/README.md CHANGED
@@ -501,6 +501,33 @@ Reputable.lookup_reputation(:ip, request.ip)
501
501
  # expires_at: 0, metadata: { order_id: "123" } }
502
502
  ```
503
503
 
504
+ ### ASN Reputation
505
+
506
+ Apply and lookup reputations for entire ASNs (Autonomous System Numbers). Useful for blocking datacenter traffic or known-bad networks.
507
+
508
+ ```ruby
509
+ # Apply reputation to an ASN
510
+ Reputable.block_asn("15169", reason: "datacenter_abuse")
511
+ Reputable.challenge_asn("7922", reason: "suspicious_traffic")
512
+ Reputable.trust_asn("16509", reason: "known_partner")
513
+ Reputable.ignore_asn("32934", reason: "internal_monitoring")
514
+
515
+ # Quick boolean checks
516
+ Reputable.blocked_asn?("15169") # => true/false
517
+ Reputable.challenged_asn?("7922") # => true/false
518
+ Reputable.trusted_asn?("16509") # => true/false
519
+
520
+ # Get status string
521
+ Reputable.lookup_asn("15169")
522
+ # => "untrusted_block" or nil
523
+
524
+ # Full lookup with metadata
525
+ Reputable.lookup_reputation(:asn, "15169")
526
+ # => { status: "untrusted_block", reason: "datacenter_abuse", ... }
527
+ ```
528
+
529
+ **Note:** ASNs are normalized automatically - both `"15169"` and `"AS15169"` work.
530
+
504
531
  ---
505
532
 
506
533
  ## User Verification & Trust Flow
@@ -205,8 +205,113 @@ module Reputable
205
205
  lookup_ip(ip) == "untrusted_challenge"
206
206
  end
207
207
 
208
+ # ========================================================================
209
+ # ASN LOOKUP METHODS
210
+ # ========================================================================
211
+
212
+ # Quick lookup for ASN reputation status
213
+ # Returns just the status string (or nil)
214
+ # ASN is normalized (strips "AS" prefix if present)
215
+ #
216
+ # @param asn [String] ASN (e.g., "15169" or "AS15169")
217
+ # @return [String, nil] Status string or nil
218
+ #
219
+ # @example
220
+ # status = Reputable::Reputation.lookup_asn("15169")
221
+ # # => "untrusted_block" or nil
222
+ def lookup_asn(asn)
223
+ result = lookup(:asn, normalize_asn(asn))
224
+ result&.dig(:status)
225
+ end
226
+
227
+ # Check if an ASN is trusted (any trusted_* status)
228
+ #
229
+ # @param asn [String] ASN
230
+ # @return [Boolean] Returns false if disabled, nil lookup, or not trusted
231
+ def trusted_asn?(asn)
232
+ status = lookup_asn(asn)
233
+ return false if status.nil?
234
+
235
+ status.start_with?("trusted")
236
+ end
237
+
238
+ # Check if an ASN should be blocked
239
+ #
240
+ # @param asn [String] ASN
241
+ # @return [Boolean]
242
+ def blocked_asn?(asn)
243
+ lookup_asn(asn) == "untrusted_block"
244
+ end
245
+
246
+ # Check if an ASN should be challenged
247
+ #
248
+ # @param asn [String] ASN
249
+ # @return [Boolean]
250
+ def challenged_asn?(asn)
251
+ lookup_asn(asn) == "untrusted_challenge"
252
+ end
253
+
254
+ # ========================================================================
255
+ # ASN APPLY CONVENIENCE METHODS
256
+ # ========================================================================
257
+
258
+ # Convenience method: Trust an ASN (behavioral by default)
259
+ def trust_asn(asn, reason: "manual_trust", status: :trusted_behavior, ttl: nil, **metadata)
260
+ apply(
261
+ entity_type: :asn,
262
+ entity_id: normalize_asn(asn),
263
+ status: status,
264
+ reason: reason,
265
+ ttl: ttl,
266
+ metadata: metadata
267
+ )
268
+ end
269
+
270
+ # Convenience method: Block an ASN
271
+ def block_asn(asn, reason: "manual_block", ttl: nil, **metadata)
272
+ apply(
273
+ entity_type: :asn,
274
+ entity_id: normalize_asn(asn),
275
+ status: :untrusted_block,
276
+ reason: reason,
277
+ ttl: ttl,
278
+ metadata: metadata
279
+ )
280
+ end
281
+
282
+ # Convenience method: Challenge an ASN (CAPTCHA, etc.)
283
+ def challenge_asn(asn, reason: "suspicious_traffic", ttl: nil, **metadata)
284
+ apply(
285
+ entity_type: :asn,
286
+ entity_id: normalize_asn(asn),
287
+ status: :untrusted_challenge,
288
+ reason: reason,
289
+ ttl: ttl,
290
+ metadata: metadata
291
+ )
292
+ end
293
+
294
+ # Convenience method: Mark ASN to be ignored in analytics
295
+ def ignore_asn(asn, reason: "datacenter_traffic", ttl: nil, **metadata)
296
+ apply(
297
+ entity_type: :asn,
298
+ entity_id: normalize_asn(asn),
299
+ status: :untrusted_ignore,
300
+ reason: reason,
301
+ ttl: ttl,
302
+ metadata: metadata
303
+ )
304
+ end
305
+
208
306
  private
209
307
 
308
+ # Normalize ASN by stripping "AS" prefix if present
309
+ # @param asn [String] ASN with or without prefix
310
+ # @return [String] ASN without prefix
311
+ def normalize_asn(asn)
312
+ asn.to_s.sub(/^AS/i, "")
313
+ end
314
+
210
315
  def valid_entity_type?(entity_type)
211
316
  VALID_ENTITY_TYPES.include?(entity_type.to_sym)
212
317
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Reputable
4
- VERSION = "0.1.17"
4
+ VERSION = "0.1.19"
5
5
  end
data/lib/reputable.rb CHANGED
@@ -126,6 +126,39 @@ module Reputable
126
126
  Reputation.challenged_ip?(ip)
127
127
  end
128
128
 
129
+ # Delegate ASN reputation methods to Reputation module
130
+ def lookup_asn(asn)
131
+ Reputation.lookup_asn(asn)
132
+ end
133
+
134
+ def trusted_asn?(asn)
135
+ Reputation.trusted_asn?(asn)
136
+ end
137
+
138
+ def blocked_asn?(asn)
139
+ Reputation.blocked_asn?(asn)
140
+ end
141
+
142
+ def challenged_asn?(asn)
143
+ Reputation.challenged_asn?(asn)
144
+ end
145
+
146
+ def trust_asn(asn, reason: "manual_trust", status: :trusted_behavior, ttl: nil, **metadata)
147
+ Reputation.trust_asn(asn, reason: reason, status: status, ttl: ttl, **metadata)
148
+ end
149
+
150
+ def block_asn(asn, reason: "manual_block", ttl: nil, **metadata)
151
+ Reputation.block_asn(asn, reason: reason, ttl: ttl, **metadata)
152
+ end
153
+
154
+ def challenge_asn(asn, reason: "suspicious_traffic", ttl: nil, **metadata)
155
+ Reputation.challenge_asn(asn, reason: reason, ttl: ttl, **metadata)
156
+ end
157
+
158
+ def ignore_asn(asn, reason: "datacenter_traffic", ttl: nil, **metadata)
159
+ Reputation.ignore_asn(asn, reason: reason, ttl: ttl, **metadata)
160
+ end
161
+
129
162
  # Generate a signed verification URL
130
163
  # @param return_url [String] URL to redirect to after successful verification
131
164
  # @param failure_url [String, nil] URL to redirect to on failure (optional)
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.17
4
+ version: 0.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reputable
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-01-29 00:00:00.000000000 Z
11
+ date: 2026-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis