antispam 0.3.2 → 0.3.5
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bdbea61620fe47180c54c8c12a52980516c45d6ba5a964af6ca10d8e55cafb9a
|
|
4
|
+
data.tar.gz: ab054479f0ff3b244d7bc4a339f464b733267978d4752a80206d47057048770c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 070de4332d9749600d1d0cbe1f8b4ac4e3cd8865fc07e9ed6bd0dd1e2c821b62b1034bbd5d6611c8416c65e7a3531d95037cd81072971eaf8bb31abdb92d09d0
|
|
7
|
+
data.tar.gz: 73c95962012c1f57d919992975bb1d55243fde066d2a9e416dc3ec60995bf593d2ad7bebad8998a776f8a3360a2ab054121f20ed6f38919dcb6ac512779c26f4
|
|
@@ -1,13 +1,47 @@
|
|
|
1
|
+
require 'net/http'
|
|
1
2
|
module Antispam
|
|
2
3
|
class Signup < ApplicationRecord
|
|
3
|
-
def self.analyze(user_id:, ip:)
|
|
4
|
+
def self.analyze(user_id:, ip: nil, request: nil)
|
|
5
|
+
record(user_id: user_id, ip: ip || request&.remote_ip).safe?
|
|
6
|
+
end
|
|
7
|
+
# Like analyze, but also asks Defendium whether the form's _defendium token passed.
|
|
8
|
+
# Returns a hash; :safe is true only if our score is safe and Defendium says "pass".
|
|
9
|
+
def self.check_spam(user_id:, request:)
|
|
10
|
+
signup = record(user_id: user_id, ip: request.remote_ip)
|
|
11
|
+
human_check = verify_human(request)
|
|
12
|
+
{
|
|
13
|
+
safe: signup.safe? && human_check == "pass",
|
|
14
|
+
signup_safe: signup.safe?,
|
|
15
|
+
spamscore: signup.spamscore,
|
|
16
|
+
human_check: human_check,
|
|
17
|
+
country_code: signup.country_code,
|
|
18
|
+
number_from_this_ip: signup.number_from_this_ip
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
def self.record(user_id:, ip:)
|
|
4
22
|
ip_integer = IPAddr.new(ip).to_i rescue 0
|
|
5
23
|
signup = Signup.where(user_id: user_id).first_or_initialize
|
|
6
24
|
signup.ip = ip
|
|
7
25
|
signup.country_code = Iplocator.get_country(ip_integer)
|
|
8
26
|
signup.number_from_this_ip = Signup.where(ip: ip).count
|
|
9
27
|
signup.save
|
|
10
|
-
signup
|
|
28
|
+
signup
|
|
29
|
+
end
|
|
30
|
+
# Returns "pass", "uncompleted", "spam", or "unknown" if Defendium couldn't be reached.
|
|
31
|
+
def self.verify_human(request)
|
|
32
|
+
token = request.params[:_defendium]
|
|
33
|
+
return "uncompleted" if token.blank?
|
|
34
|
+
uri = URI("https://defendium.com/human/verify")
|
|
35
|
+
body = { token: token.to_s, host: request.host, ip: request.remote_ip, user_agent: request.user_agent.to_s, required: true, secret_key: defendium_api_key }
|
|
36
|
+
response = Net::HTTP.post(uri, body.to_json, "Content-Type" => "application/json")
|
|
37
|
+
return "unknown" unless response.is_a?(Net::HTTPSuccess)
|
|
38
|
+
JSON.parse(response.body)["result"].to_s.presence || "unknown"
|
|
39
|
+
rescue StandardError
|
|
40
|
+
"unknown"
|
|
41
|
+
end
|
|
42
|
+
# Optional; set in credentials (defendium: api_key:) or ENV["DEFENDIUM_API_KEY"].
|
|
43
|
+
def self.defendium_api_key
|
|
44
|
+
Rails.application.credentials.dig(:defendium, :api_key) || ENV["DEFENDIUM_API_KEY"]
|
|
11
45
|
end
|
|
12
46
|
def spamscore
|
|
13
47
|
spamscore = 50 # Start at a neutral score
|
|
@@ -15,13 +49,13 @@ module Antispam
|
|
|
15
49
|
spamscore += 10 if self.number_from_this_ip > 5
|
|
16
50
|
spamscore += 10 if self.number_from_this_ip > 10
|
|
17
51
|
spamscore += 10 if Iplocator.countries_suspected_of_spam.include?(self.country_code)
|
|
18
|
-
spamscore -=
|
|
52
|
+
spamscore -= 5 if self.number_from_this_ip < 2
|
|
19
53
|
spamscore -= 10 if Iplocator.trusted_countries.include?(self.country_code)
|
|
20
54
|
spamscore = [[spamscore, 0].max, 100].min # Clamp to a value between 0 and 100
|
|
21
55
|
spamscore
|
|
22
56
|
end
|
|
23
57
|
def safe?
|
|
24
|
-
self.spamscore
|
|
58
|
+
self.spamscore < 40
|
|
25
59
|
end
|
|
26
60
|
end
|
|
27
61
|
end
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
<th>Created At</th>
|
|
13
13
|
<th>Updated At</th>
|
|
14
14
|
<th>Safe?</th>
|
|
15
|
+
<th>Spamscore</th>
|
|
15
16
|
</tr>
|
|
16
17
|
</thead>
|
|
17
18
|
|
|
@@ -22,9 +23,10 @@
|
|
|
22
23
|
<td><%= signup.ip %></td>
|
|
23
24
|
<td><%= signup.country_code %></td>
|
|
24
25
|
<td><%= signup.number_from_this_ip %></td>
|
|
25
|
-
<td><%= signup.created_at %></td>
|
|
26
|
-
<td><%= signup.updated_at %></td>
|
|
26
|
+
<td><%= signup.created_at.strftime("%Y-%m-%d %I:%M %p") %></td>
|
|
27
|
+
<td><%= signup.updated_at.strftime("%Y-%m-%d %I:%M %p") %></td>
|
|
27
28
|
<td><%= signup.safe? %></td>
|
|
29
|
+
<td><%= signup.spamscore %></td>
|
|
28
30
|
</tr>
|
|
29
31
|
<% end %>
|
|
30
32
|
</tbody>
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
module Antispam
|
|
3
3
|
module Spamcheckers
|
|
4
4
|
class Defendium
|
|
5
|
-
# Returns
|
|
5
|
+
# Returns 1 for spam, 0 for not spam.
|
|
6
6
|
def self.check(content, key, verbose)
|
|
7
7
|
# nethttp2.rb
|
|
8
8
|
require 'uri'
|
|
9
9
|
require 'net/http'
|
|
10
|
+
require 'json'
|
|
10
11
|
|
|
11
12
|
uri = URI('https://api.defendium.com/check')
|
|
12
13
|
params = { secret_key: key, content: content }
|
|
@@ -14,7 +15,7 @@ module Antispam
|
|
|
14
15
|
|
|
15
16
|
res = Net::HTTP.get_response(uri)
|
|
16
17
|
if res.is_a?(Net::HTTPSuccess)
|
|
17
|
-
result = res.body
|
|
18
|
+
result = JSON.parse(res.body)
|
|
18
19
|
if result["warnings"]
|
|
19
20
|
Rails.logger.info result["warnings"]
|
|
20
21
|
end
|
|
@@ -27,4 +28,4 @@ module Antispam
|
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
|
-
end
|
|
31
|
+
end
|
data/lib/antispam/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module Antispam
|
|
2
|
-
VERSION = '0.3.
|
|
3
|
-
end
|
|
1
|
+
module Antispam
|
|
2
|
+
VERSION = '0.3.5'
|
|
3
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: antispam
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Kopf
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -65,14 +65,13 @@ dependencies:
|
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
|
-
description:
|
|
69
|
-
DNS blacklists
|
|
70
|
-
spam detection using Project Honey Pot to block known spammers automatically
|
|
71
|
-
|
|
72
|
-
to
|
|
73
|
-
performance impact
|
|
74
|
-
block spam at the request level
|
|
75
|
-
the README for more details.\n"
|
|
68
|
+
description: 'Antispam helps prevent spam in your Rails applications by checking against
|
|
69
|
+
DNS blacklists and spam-prevention databases. It has two core features: (1) IP-based
|
|
70
|
+
spam detection using Project Honey Pot to block known spammers automatically, and
|
|
71
|
+
(2) content-based spam detection using Defendium’s machine learning API, which is
|
|
72
|
+
free for up to 1,000 checks per day. Blacklist lookups are cached for 24 hours to
|
|
73
|
+
minimize performance impact. The gem integrates seamlessly with Rails, allowing
|
|
74
|
+
you to block spam at the request level and redirect flagged users to a captcha page.'
|
|
76
75
|
email:
|
|
77
76
|
- antispam@ryankopf.com
|
|
78
77
|
executables: []
|