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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: deb7098b89c7771c3a67061353ea1333960830b49a5181487ae0ffddb5aaab40
4
- data.tar.gz: 7ada271f3c917b2869cb4a92fa7d5b70606d9c5020c4d4eb5e44934d25abcad9
3
+ metadata.gz: c201e827a1cfece7b14b2179d32600480513672661307a3a889a81b7e53f2efe
4
+ data.tar.gz: f9b1f819e3f07aebc0c486d56c07fe4cbae5de504e48cdc33fbd57a3e27950b1
5
5
  SHA512:
6
- metadata.gz: d3ef0076d08ed077460f8b98f90b38b4bcada5a6c50916a8fada274afea6c3786f04ce311471aace68a39dd732193c09cb15b2afa43ce5502ee577a5c3fe70e5
7
- data.tar.gz: 41eda0779322117d6a2235b5ef8a5303e3ce6d7c9dcb66cecae9b2252d98b793364a9e6014f51858419a84a2f39896b44549462d1e8f91608248c35d2a88e29e
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
- You need to add this to your routes.rb
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
@@ -2,6 +2,7 @@ Antispam::Engine.routes.draw do
2
2
  resources :clears
3
3
  resources :blocks
4
4
  resources :challenges
5
+ resources :signups
5
6
  root to: 'ips#index'
6
7
  get 'validate', to: 'validate#index'
7
8
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Antispam
2
- VERSION = '0.2.11'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -2,3 +2,11 @@
2
2
  # task :antispam do
3
3
  # # Task goes here
4
4
  # end
5
+
6
+ namespace :antispam do
7
+ desc "Install Antispam by importing IP data"
8
+ task install: :environment do
9
+ Antispam::Iplocator.import
10
+ puts "Antispam IP data imported successfully."
11
+ end
12
+ end
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.2.11
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: 2024-10-29 00:00:00.000000000 Z
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 checks DNS blacklists and helps prevent spam on your site.
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/20210130213708_create_antispam_ips.rb
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.5.20
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: []
@@ -1,12 +0,0 @@
1
- class CreateAntispamIps < 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
- end
12
- end
@@ -1,11 +0,0 @@
1
- class CreateAntispamChallenges < ActiveRecord::Migration[6.1]
2
- def change
3
- create_table :antispam_challenges do |t|
4
- t.string :question
5
- t.string :answer
6
- t.string :code
7
-
8
- t.timestamps
9
- end
10
- end
11
- end
@@ -1,12 +0,0 @@
1
- class CreateAntispamBlocks < ActiveRecord::Migration[6.1]
2
- def change
3
- create_table :antispam_blocks do |t|
4
- t.string :ip
5
- t.string :provider
6
- t.string :controllername
7
- t.string :actionname
8
-
9
- t.timestamps
10
- end
11
- end
12
- end
@@ -1,13 +0,0 @@
1
- class CreateAntispamClears < ActiveRecord::Migration[6.1]
2
- def change
3
- create_table :antispam_clears do |t|
4
- t.string :ip
5
- t.string :result
6
- t.string :answer
7
- t.integer :threat_before
8
- t.integer :threat_after
9
-
10
- t.timestamps
11
- end
12
- end
13
- end
@@ -1,5 +0,0 @@
1
- class AddThreatToAntispamBlocks < ActiveRecord::Migration[6.1]
2
- def change
3
- add_column :antispam_blocks, :threat, :integer
4
- end
5
- end