antispam 0.2.11 → 0.3.1
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/MIT-LICENSE +5 -0
- data/README.md +7 -6
- data/app/controllers/antispam/signups_controller.rb +10 -0
- data/app/models/antispam/iplocator.rb +40 -0
- data/app/models/antispam/signup.rb +27 -0
- data/app/views/antispam/signups/index.html.erb +31 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20210130213708_create_antispam_tables.rb +58 -0
- data/lib/antispam/version.rb +1 -1
- data/lib/tasks/antispam_tasks.rake +8 -0
- metadata +30 -12
- data/db/migrate/20210130213708_create_antispam_ips.rb +0 -12
- data/db/migrate/20210130214835_create_antispam_challenges.rb +0 -11
- data/db/migrate/20210130234107_create_antispam_blocks.rb +0 -12
- data/db/migrate/20210130235537_create_antispam_clears.rb +0 -13
- data/db/migrate/20210131165122_add_threat_to_antispam_blocks.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c201e827a1cfece7b14b2179d32600480513672661307a3a889a81b7e53f2efe
|
4
|
+
data.tar.gz: f9b1f819e3f07aebc0c486d56c07fe4cbae5de504e48cdc33fbd57a3e27950b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f37d63454377603cb8216140f96f6c84a5575e1be3d47906ee413f1b58bcda4593be281db41877ad3c5ebdde6f4ec2e4484b49615dc5763b0f3a5ef3815f081
|
7
|
+
data.tar.gz: cfdd369ceb4398c20f214fa230139134b3dd218d81a1e2e3f51d3d764fed6408149c425dc4007a5007a910150fbf8cbe24f451547c1dea4fb7114f72955c10c7
|
data/MIT-LICENSE
CHANGED
@@ -18,3 +18,8 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
IP DATABASE LICENSE
|
23
|
+
|
24
|
+
The ip database is from db-ip .com, and is not subject to this license, but
|
25
|
+
is CC 4.0 Attribution. https://creativecommons.org/licenses/by/4.0/
|
data/README.md
CHANGED
@@ -84,28 +84,29 @@ gem 'antispam'
|
|
84
84
|
```
|
85
85
|
|
86
86
|
And then execute:
|
87
|
-
```bash
|
88
|
-
$ bundle
|
89
|
-
```
|
90
87
|
|
91
|
-
Or install it yourself as:
|
92
88
|
```bash
|
93
89
|
$ gem install antispam
|
94
90
|
$ rails antispam:install:migrations
|
91
|
+
$ rails antispam:install
|
95
92
|
$ rails db:migrate SCOPE=antispam
|
96
93
|
```
|
94
|
+
|
97
95
|
The gem depends on image_processing, which depends on vips. We are using vips to
|
98
96
|
generate captcha images.
|
97
|
+
|
99
98
|
```
|
100
99
|
sudo apt install libvips-tools
|
101
100
|
```
|
102
101
|
|
103
|
-
|
102
|
+
To be able to view recent spam-blocking activity, you need to add antispam to your routes.rb
|
103
|
+
|
104
104
|
```
|
105
105
|
mount Antispam::Engine => "/antispam"
|
106
106
|
```
|
107
107
|
|
108
|
-
Then add to your application controller:
|
108
|
+
Then add the following to your application controller:
|
109
|
+
|
109
110
|
```
|
110
111
|
before_action do
|
111
112
|
check_ip_against_database(ip_blacklists: {default: 'your_api_key_here'}, verbose: true)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_dependency "antispam/application_controller"
|
2
|
+
|
3
|
+
module Antispam
|
4
|
+
class SignupsController < ApplicationController
|
5
|
+
before_action :must_be_admin
|
6
|
+
def index
|
7
|
+
@signups = Signup.order(created_at: :desc).limit(100).offset(params[:page].to_i * 100)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Antispam
|
2
|
+
class Iplocator < ApplicationRecord
|
3
|
+
|
4
|
+
def self.get_country(ip_integer)
|
5
|
+
ip = Iplocator.find_by("? > ip_from AND ? < ip_to",ip_integer,ip_integer)
|
6
|
+
return nil if ip.nil?
|
7
|
+
ip.country_code
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.import
|
11
|
+
require 'csv'
|
12
|
+
file_path = File.expand_path('../../../../ip-to-country.csv', __FILE__)
|
13
|
+
csv_data = CSV.read(file_path, headers: false)
|
14
|
+
csv_data.each do |row|
|
15
|
+
begin
|
16
|
+
Iplocator.create(
|
17
|
+
ip_from: IPAddr.new(row[0]).to_i,
|
18
|
+
ip_to: IPAddr.new(row[1]).to_i,
|
19
|
+
country_code: row[2]
|
20
|
+
)
|
21
|
+
rescue
|
22
|
+
puts "Error importing row: #{row.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
puts "Imported #{csv_data.length} rows."
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.ip_to_string(ip)
|
29
|
+
ip.split(".").map{|x|x.to_i.to_s(16)}.join("_")
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.countries_suspected_of_spam
|
33
|
+
%w[CN IN RU BR ID PH TH VN SG NG UA PK BD EG TR ZA MX MA KE]
|
34
|
+
end
|
35
|
+
def self.trusted_countries
|
36
|
+
%w[US DE GB CA AU JP FR NL]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Antispam
|
2
|
+
class Signup < ApplicationRecord
|
3
|
+
def self.analyze(user_id:, ip:)
|
4
|
+
ip_integer = IPAddr.new(ip).to_i rescue 0
|
5
|
+
signup = Signup.where(user_id: user_id).first_or_initialize
|
6
|
+
signup.ip = ip
|
7
|
+
signup.country_code = Iplocator.get_country(ip_integer)
|
8
|
+
signup.number_from_this_ip = Signup.where(ip: ip).count
|
9
|
+
signup.save
|
10
|
+
signup.safe?
|
11
|
+
end
|
12
|
+
def spamscore
|
13
|
+
spamscore = 50 # Start at a neutral score
|
14
|
+
spamscore += 10 if self.country_code.nil? || (self.country_code == 'ZZ')
|
15
|
+
spamscore += 10 if self.number_from_this_ip > 5
|
16
|
+
spamscore += 10 if self.number_from_this_ip > 10
|
17
|
+
spamscore += 10 if Iplocator.countries_suspected_of_spam.include?(self.country_code)
|
18
|
+
spamscore -= 10 if self.number_from_this_ip < 2
|
19
|
+
spamscore -= 10 if Iplocator.trusted_countries.include?(self.country_code)
|
20
|
+
spamscore = [[spamscore, 0].max, 100].min # Clamp to a value between 0 and 100
|
21
|
+
spamscore
|
22
|
+
end
|
23
|
+
def safe?
|
24
|
+
self.spamscore <= 50
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
|
3
|
+
<h1>Signups</h1>
|
4
|
+
|
5
|
+
<table>
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th>User ID</th>
|
9
|
+
<th>IP</th>
|
10
|
+
<th>Country Code</th>
|
11
|
+
<th>Number from this IP</th>
|
12
|
+
<th>Created At</th>
|
13
|
+
<th>Updated At</th>
|
14
|
+
<th>Safe?</th>
|
15
|
+
</tr>
|
16
|
+
</thead>
|
17
|
+
|
18
|
+
<tbody>
|
19
|
+
<% @signups.each do |signup| %>
|
20
|
+
<tr>
|
21
|
+
<td><%= signup.user_id %></td>
|
22
|
+
<td><%= signup.ip %></td>
|
23
|
+
<td><%= signup.country_code %></td>
|
24
|
+
<td><%= signup.number_from_this_ip %></td>
|
25
|
+
<td><%= signup.created_at %></td>
|
26
|
+
<td><%= signup.updated_at %></td>
|
27
|
+
<td><%= signup.safe? %></td>
|
28
|
+
</tr>
|
29
|
+
<% end %>
|
30
|
+
</tbody>
|
31
|
+
</table>
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
class CreateAntispamTables < ActiveRecord::Migration[6.1]
|
2
|
+
def change
|
3
|
+
create_table :antispam_ips do |t|
|
4
|
+
t.string :address
|
5
|
+
t.string :provider
|
6
|
+
t.integer :threat
|
7
|
+
t.datetime :expires_at
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :antispam_challenges do |t|
|
13
|
+
t.string :question
|
14
|
+
t.string :answer
|
15
|
+
t.string :code
|
16
|
+
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
create_table :antispam_blocks do |t|
|
21
|
+
t.string :ip
|
22
|
+
t.string :provider
|
23
|
+
t.string :controllername
|
24
|
+
t.string :actionname
|
25
|
+
t.integer :threat
|
26
|
+
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table :antispam_clears do |t|
|
31
|
+
t.string :ip
|
32
|
+
t.string :result
|
33
|
+
t.string :answer
|
34
|
+
t.integer :threat_before
|
35
|
+
t.integer :threat_after
|
36
|
+
|
37
|
+
t.timestamps
|
38
|
+
end
|
39
|
+
|
40
|
+
create_table :antispam_iplocators do |t|
|
41
|
+
t.integer :ip_from, null: false, unsigned: true
|
42
|
+
t.integer :ip_to, null: false, unsigned: true
|
43
|
+
t.string :country_code, limit: 2, null: false
|
44
|
+
t.index ["ip_from", "ip_to"], name: "ips"
|
45
|
+
t.index ["ip_from"], name: "ip_from"
|
46
|
+
t.index ["ip_to"], name: "ip_to"
|
47
|
+
end
|
48
|
+
|
49
|
+
create table :antispam_signups do |t|
|
50
|
+
t.integer :user_id
|
51
|
+
t.string :ip
|
52
|
+
t.string :country_code
|
53
|
+
t.integer :number_from_this_ip
|
54
|
+
t.timestamps
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/antispam/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: antispam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Kopf
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-23 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rails
|
@@ -38,6 +37,20 @@ dependencies:
|
|
38
37
|
- - "~>"
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: '1.0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: csv
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
41
54
|
- !ruby/object:Gem::Dependency
|
42
55
|
name: net-http
|
43
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,7 +65,14 @@ dependencies:
|
|
52
65
|
- - ">="
|
53
66
|
- !ruby/object:Gem::Version
|
54
67
|
version: '0'
|
55
|
-
description: Antispam
|
68
|
+
description: "Antispam helps prevent spam in your Rails applications by checking against
|
69
|
+
DNS blacklists \nand spam-prevention databases.\n\nKey features:\n- IP-based spam
|
70
|
+
detection using Project Honey Pot to block known spammers automatically.\n- Content-based
|
71
|
+
spam detection using Defendium's machine learning API (free for up to \n 1,000
|
72
|
+
checks per day).\n- Blacklist lookups are cached for 24 hours to minimize performance
|
73
|
+
impact.\n\nThe gem integrates seamlessly with Rails, allowing you to block spam
|
74
|
+
at the request level \nand redirect flagged users to a captcha page.\n\nSee the
|
75
|
+
README for more details.\n"
|
56
76
|
email:
|
57
77
|
- antispam@ryankopf.com
|
58
78
|
executables: []
|
@@ -85,6 +105,7 @@ files:
|
|
85
105
|
- app/controllers/antispam/blocks_controller.rb
|
86
106
|
- app/controllers/antispam/challenges_controller.rb
|
87
107
|
- app/controllers/antispam/clears_controller.rb
|
108
|
+
- app/controllers/antispam/signups_controller.rb
|
88
109
|
- app/controllers/antispam/validate_controller.rb
|
89
110
|
- app/helpers/antispam/application_helper.rb
|
90
111
|
- app/helpers/antispam/blocks_helper.rb
|
@@ -97,6 +118,8 @@ files:
|
|
97
118
|
- app/models/antispam/challenge.rb
|
98
119
|
- app/models/antispam/clear.rb
|
99
120
|
- app/models/antispam/ip.rb
|
121
|
+
- app/models/antispam/iplocator.rb
|
122
|
+
- app/models/antispam/signup.rb
|
100
123
|
- app/views/antispam/blocks/index.html.erb
|
101
124
|
- app/views/antispam/blocks/show.html.erb
|
102
125
|
- app/views/antispam/challenges/_form.html.erb
|
@@ -106,14 +129,11 @@ files:
|
|
106
129
|
- app/views/antispam/challenges/show.html.erb
|
107
130
|
- app/views/antispam/clears/index.html.erb
|
108
131
|
- app/views/antispam/clears/show.html.erb
|
132
|
+
- app/views/antispam/signups/index.html.erb
|
109
133
|
- app/views/antispam/validate/index.html.erb
|
110
134
|
- app/views/layouts/antispam/application.html.erb
|
111
135
|
- config/routes.rb
|
112
|
-
- db/migrate/
|
113
|
-
- db/migrate/20210130214835_create_antispam_challenges.rb
|
114
|
-
- db/migrate/20210130234107_create_antispam_blocks.rb
|
115
|
-
- db/migrate/20210130235537_create_antispam_clears.rb
|
116
|
-
- db/migrate/20210131165122_add_threat_to_antispam_blocks.rb
|
136
|
+
- db/migrate/20210130213708_create_antispam_tables.rb
|
117
137
|
- lib/antispam.rb
|
118
138
|
- lib/antispam/blacklists/httpbl.rb
|
119
139
|
- lib/antispam/checker.rb
|
@@ -131,7 +151,6 @@ metadata:
|
|
131
151
|
homepage_uri: https://ryankopf.com
|
132
152
|
source_code_uri: https://github.com/ryankopf/antispam
|
133
153
|
changelog_uri: https://github.com/ryankopf/antispam/CHANGELOG.md
|
134
|
-
post_install_message:
|
135
154
|
rdoc_options: []
|
136
155
|
require_paths:
|
137
156
|
- lib
|
@@ -146,8 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
165
|
- !ruby/object:Gem::Version
|
147
166
|
version: '0'
|
148
167
|
requirements: []
|
149
|
-
rubygems_version: 3.
|
150
|
-
signing_key:
|
168
|
+
rubygems_version: 3.6.4
|
151
169
|
specification_version: 4
|
152
170
|
summary: A spam prevention gem.
|
153
171
|
test_files: []
|