antispam 0.1.4 → 0.1.7

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: '06962cddbbfd16f9f59e18277630d9c597865483df7f72a5b33bdeccfab15c98'
4
- data.tar.gz: ce7b03a25d08d79271e61f7081d73922602c84201f7867d32a818fc9ff3b67e2
3
+ metadata.gz: 636c6cfd1e3a5c84182eaa1e19966e553a2098c4f3a01a049cdbe4613165a52e
4
+ data.tar.gz: 8a53d23ef78da214962bd81411a97a720d5eba3a15817d3f7ccd5bfac81719ec
5
5
  SHA512:
6
- metadata.gz: 63cb93116a4a5d5409ce5a6643071f5edc267f245251a97e06be683ec036126b245ca621c57656848812436a4761f3adc7c8e1980b451264a6942c3e8442d14b
7
- data.tar.gz: 04ca386da73cd5b9d273476ecbe624c1045f1d2933c58eab9bd4948b49806745d399b5aa4351d575ce9ad2bc75a945d8d4732336663bf13be7dd74972320dcf2
6
+ metadata.gz: b4d6e23e0432af6b62b7cd9e469c2393a9e4f4513b13d93d282e6841062bd706d70fa44dd6bed0d79658da80ff52827ee8ba9d63baa0a84df2112a7fd313b3dd
7
+ data.tar.gz: 9ca4921062395565e50fa29daf9d56bd3e691b5a675fb34bc4d6ec5e1378da1f3be5b19bdc73294be7fcb55b8e3d766819c140ef45b602d8904818eccf10f187
data/README.md CHANGED
@@ -1,72 +1,113 @@
1
- # Antispam
2
- The antispam gem helps prevent spam in your Rails applications by
3
- checking against various antispam blacklists on the web.
4
- You can configure which spam blacklists are checked in your application configuration.
5
-
6
- ## Usage
7
-
8
- The gem is used by adding this to your ApplicationController.rb
9
-
10
- ```
11
- before_action do
12
- check_ip_against_database(ip_blacklists: {default: 'yourcodehere'}, verbose: true)
13
- end
14
- ```
15
-
16
- Once the filter is setup, everything else is handled for your application.
17
- The gem will run during any request that is not a GET request.
18
-
19
- Blacklist database lookups are cached for 24 hours, and cached results won't need
20
- to slowdown your app by additional http requests on the backend.
21
-
22
- The gem needs to create some database tables to function; these store the cached
23
- blacklist database lookups, and any actions caused by the gem.
24
-
25
- You need to add this to your routes.rb
26
- ```
27
- mount Antispam::Engine => "/antispam"
28
- ```
29
- You can see what IP addresses have been blocked by going to /antispam/blocks
30
- but your applicationcontroller must respond to ```is_admin?``` function.
31
-
32
-
33
- ## Installation
34
- Add this line to your application's Gemfile:
35
-
36
- ```ruby
37
- gem 'antispam'
38
- ```
39
-
40
- And then execute:
41
- ```bash
42
- $ bundle
43
- ```
44
-
45
- Or install it yourself as:
46
- ```bash
47
- $ gem install antispam
48
- $ rails antispam:install:migrations
49
- $ rails db:migrate SCOPE=antispam
50
- ```
51
- The gem depends on image_processing, which depends on vips. We are using vips to
52
- generate captcha images.
53
- ```
54
- sudo apt install libvips-tools
55
- ```
56
-
57
- ## Development
58
-
59
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
60
-
61
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
62
-
63
- ## Contributing
64
-
65
- Bug reports and pull requests are welcome on GitHub at https://github.com/ryankopf/antispam. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/antispam/blob/master/CODE_OF_CONDUCT.md).
66
-
67
- ## License
68
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
69
-
70
- ## Code of Conduct
71
-
72
- Everyone interacting in the Antispam project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ryankopf/antispam/blob/master/CODE_OF_CONDUCT.md).
1
+ # Antispam
2
+ The antispam gem helps prevent spam in your Rails applications by
3
+ providing tools that check spam against powerful spam-prevention
4
+ databases, accessible for free.
5
+
6
+ The first feature checks against an IP database of spam, allowing you
7
+ to stop spammers who are prolific and have been detected on other websites.
8
+ It uses the blazing fast Defendium API to quickly determine if submitted
9
+ content is spam or not.
10
+
11
+ The second feature allows you to submit user-provided content to a spam
12
+ checking service that uses machine learning and a database of content to
13
+ determine whether the user's submitted content is spam.
14
+
15
+ ## Spam Content Checking - Usage
16
+
17
+ ```
18
+ result = Antispam::Checker.check(content: @comment.body)
19
+ if result.is_spam?
20
+ @comment.save
21
+ else
22
+ redirect_to "/access_denied"
23
+ end
24
+ ```
25
+
26
+ ## Bad IP Checking - Usage
27
+
28
+ The gem is used by adding this to your ApplicationController.rb
29
+
30
+ ```
31
+ before_action do
32
+ check_ip_against_database(ip_blacklists: {default: 'yourcodehere'}, verbose: true)
33
+ end
34
+ ```
35
+
36
+ Codes are from the [httpbl](https://www.projecthoneypot.org/httpbl.php) at projecthoneypot.org
37
+
38
+ Once the filter is setup, everything else is handled for your application.
39
+ By default the gem will run during any request that is not a GET request.
40
+
41
+ You can change the filter to run during other requests.
42
+
43
+ ```
44
+ before_action do
45
+ check_ip_against_database(ip_blacklists: {default: 'yourcodehere'}, methods: [:get,:post,:put,:patch,:delete])
46
+ end
47
+ ```
48
+
49
+ Blacklist database lookups are cached for 24 hours, and cached results won't need
50
+ to slowdown your app by additional http requests on the backend.
51
+
52
+ The gem needs to create some database tables to function; these store the cached
53
+ blacklist database lookups, and any actions caused by the gem.
54
+
55
+ You need to add this to your routes.rb
56
+ ```
57
+ mount Antispam::Engine => "/antispam"
58
+ ```
59
+ You can see what IP addresses have been blocked by going to /antispam/blocks
60
+ but your ApplicationController.rb must respond to ```is_admin?``` function.
61
+
62
+
63
+ ## Installation
64
+ Add this line to your application's Gemfile:
65
+
66
+ ```ruby
67
+ gem 'antispam'
68
+ ```
69
+
70
+ And then execute:
71
+ ```bash
72
+ $ bundle
73
+ ```
74
+
75
+ Or install it yourself as:
76
+ ```bash
77
+ $ gem install antispam
78
+ $ rails antispam:install:migrations
79
+ $ rails db:migrate SCOPE=antispam
80
+ ```
81
+ The gem depends on image_processing, which depends on vips. We are using vips to
82
+ generate captcha images.
83
+ ```
84
+ sudo apt install libvips-tools
85
+ ```
86
+
87
+ ## Development
88
+
89
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
90
+
91
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
92
+
93
+ ## Contributing
94
+
95
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ryankopf/antispam. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/antispam/blob/master/CODE_OF_CONDUCT.md).
96
+
97
+ ## License
98
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
99
+
100
+ ## Code of Conduct
101
+
102
+ Everyone interacting in the Antispam project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ryankopf/antispam/blob/master/CODE_OF_CONDUCT.md).
103
+
104
+ ## NO WARRANTY
105
+
106
+ THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND,
107
+ EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO,
108
+ ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS,
109
+ ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
110
+ OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE
111
+ ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO
112
+ THE SUBJECT SOFTWARE. THIS SOFTWARE IS PROVIDED "AS IS." IF YOUR JURISDICTION
113
+ DOES NOT ALLOW THESE LIMITATIONS THEN YOU MAY NOT USE THE SOFTWARE.
@@ -1,11 +1,11 @@
1
- module Antispam
2
- class ApplicationController < ::ApplicationController
3
- def must_be_admin
4
- begin
5
- render plain: 'Not available.' unless is_admin?
6
- rescue
7
- render plain: 'Not available.'
8
- end
9
- end
10
- end
11
- end
1
+ module Antispam
2
+ class ApplicationController < ::ApplicationController
3
+ def must_be_admin
4
+ begin
5
+ render plain: 'Not available.' unless is_admin?
6
+ rescue
7
+ render plain: 'Not available.'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,28 +1,28 @@
1
- require_dependency "antispam/application_controller"
2
-
3
- module Antispam
4
- class BlocksController < ApplicationController
5
- before_action :must_be_admin
6
- before_action :set_block, only: [:show]
7
-
8
- # GET /blocks
9
- def index
10
- @blocks = Block.all
11
- end
12
-
13
- # GET /blocks/1
14
- def show
15
- end
16
-
17
- private
18
- # Use callbacks to share common setup or constraints between actions.
19
- def set_block
20
- @block = Block.find(params[:id])
21
- end
22
-
23
- # Only allow a list of trusted parameters through.
24
- def block_params
25
- params.require(:block).permit(:ip, :provider, :controllername, :actionname)
26
- end
27
- end
28
- end
1
+ require_dependency "antispam/application_controller"
2
+
3
+ module Antispam
4
+ class BlocksController < ApplicationController
5
+ before_action :must_be_admin
6
+ before_action :set_block, only: [:show]
7
+
8
+ # GET /blocks
9
+ def index
10
+ @blocks = Block.all
11
+ end
12
+
13
+ # GET /blocks/1
14
+ def show
15
+ end
16
+
17
+ private
18
+ # Use callbacks to share common setup or constraints between actions.
19
+ def set_block
20
+ @block = Block.find(params[:id])
21
+ end
22
+
23
+ # Only allow a list of trusted parameters through.
24
+ def block_params
25
+ params.require(:block).permit(:ip, :provider, :controllername, :actionname)
26
+ end
27
+ end
28
+ end
@@ -1,49 +1,50 @@
1
- require_dependency "antispam/application_controller"
2
-
3
- module Antispam
4
- class ChallengesController < ApplicationController
5
- before_action :set_challenge, only: [:show, :edit, :update, :destroy]
6
-
7
- # GET /challenges/1
8
- def show
9
- respond_to do |format|
10
- format.jpeg do
11
- image = @challenge.get_image
12
- render content_type: 'image/jpeg', plain: image.jpegsave_buffer
13
- end
14
- end
15
- end
16
-
17
- # GET /challenges/new
18
- def new
19
- # use in the future for changing code
20
- end
21
-
22
- # PATCH/PUT /challenges/1
23
- def update
24
- if @challenge.validate?(params[:challenge][:answer])
25
- a = Antispam::Ip.find_or_create_by(address: request.remote_ip, provider: 'httpbl')
26
- before = a.threat
27
- a.threat = [(a.threat || 0) - 25, 0].max
28
- c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Passed', threat_before: before, threat_after: a.threat)
29
- a.expires_at = 1.hour.from_now
30
- a.save
31
- redirect_to '/'
32
- else
33
- c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Failed')
34
- redirect_to '/antispam/validate', notice: 'Invalid answer.'
35
- end
36
- end
37
-
38
- private
39
- # Use callbacks to share common setup or constraints between actions.
40
- def set_challenge
41
- @challenge = Challenge.find(params[:id])
42
- end
43
-
44
- # Only allow a list of trusted parameters through.
45
- def challenge_params
46
- params.require(:challenge).permit(:answer, :code)
47
- end
48
- end
49
- end
1
+ require_dependency "antispam/application_controller"
2
+
3
+ module Antispam
4
+ class ChallengesController < ApplicationController
5
+ before_action :set_challenge, only: [:show, :edit, :update, :destroy]
6
+
7
+ # GET /challenges/1
8
+ def show
9
+ respond_to do |format|
10
+ format.jpeg do
11
+ image = @challenge.get_image
12
+ render content_type: 'image/jpeg', plain: image.jpegsave_buffer
13
+ end
14
+ end
15
+ end
16
+
17
+ # GET /challenges/new
18
+ def new
19
+ # use in the future for changing code
20
+ head :ok
21
+ end
22
+
23
+ # PATCH/PUT /challenges/1
24
+ def update
25
+ if @challenge.validate?(params[:challenge][:answer])
26
+ a = Antispam::Ip.find_or_create_by(address: request.remote_ip, provider: 'httpbl')
27
+ before = a.threat
28
+ a.threat = [(a.threat || 0) - 25, 0].max
29
+ c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Passed', threat_before: before, threat_after: a.threat)
30
+ a.expires_at = 1.hour.from_now
31
+ a.save
32
+ redirect_to '/'
33
+ else
34
+ c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Failed')
35
+ redirect_to '/antispam/validate', notice: 'Invalid answer.'
36
+ end
37
+ end
38
+
39
+ private
40
+ # Use callbacks to share common setup or constraints between actions.
41
+ def set_challenge
42
+ @challenge = Challenge.find(params[:id])
43
+ end
44
+
45
+ # Only allow a list of trusted parameters through.
46
+ def challenge_params
47
+ params.require(:challenge).permit(:answer, :code)
48
+ end
49
+ end
50
+ end
@@ -1,28 +1,28 @@
1
- require_dependency "antispam/application_controller"
2
-
3
- module Antispam
4
- class ClearsController < ApplicationController
5
- before_action :must_be_admin
6
- before_action :set_clear, only: [:show, :edit, :update, :destroy]
7
-
8
- # GET /clears
9
- def index
10
- @clears = Clear.all
11
- end
12
-
13
- # GET /clears/1
14
- def show
15
- end
16
-
17
- private
18
- # Use callbacks to share common setup or constraints between actions.
19
- def set_clear
20
- @clear = Clear.find(params[:id])
21
- end
22
-
23
- # Only allow a list of trusted parameters through.
24
- def clear_params
25
- params.require(:clear).permit(:ip, :result, :answer, :threat_before, :threat_after)
26
- end
27
- end
28
- end
1
+ require_dependency "antispam/application_controller"
2
+
3
+ module Antispam
4
+ class ClearsController < ApplicationController
5
+ before_action :must_be_admin
6
+ before_action :set_clear, only: [:show, :edit, :update, :destroy]
7
+
8
+ # GET /clears
9
+ def index
10
+ @clears = Clear.all
11
+ end
12
+
13
+ # GET /clears/1
14
+ def show
15
+ end
16
+
17
+ private
18
+ # Use callbacks to share common setup or constraints between actions.
19
+ def set_clear
20
+ @clear = Clear.find(params[:id])
21
+ end
22
+
23
+ # Only allow a list of trusted parameters through.
24
+ def clear_params
25
+ params.require(:clear).permit(:ip, :result, :answer, :threat_before, :threat_after)
26
+ end
27
+ end
28
+ end
@@ -1,39 +1,39 @@
1
- <p id="notice"><%= notice %></p>
2
-
3
- <div class="row">
4
- <div class="cx">
5
- <h1>Blocks</h1>
6
-
7
- <table>
8
- <thead>
9
- <tr>
10
- <th>Ip</th>
11
- <th>Provider</th>
12
- <th>Controllername</th>
13
- <th>Actionname</th>
14
- <th>Threat</th>
15
- <th colspan="3"></th>
16
- </tr>
17
- </thead>
18
-
19
- <tbody>
20
- <% Antispam::Block.all.order(created_at: :desc).limit(50).each do |block| %>
21
- <tr>
22
- <td><%= block.ip %></td>
23
- <td><%= block.provider %></td>
24
- <td><%= block.controllername %></td>
25
- <td><%= block.actionname %></td>
26
- <td><%= block.threat %></td>
27
- <td><%= time_ago_in_words block.created_at %> ago</td>
28
- <!-- <td><%#= link_to 'Show', block %></td>-->
29
- <!-- <td><%#= link_to 'Edit', edit_block_path(block) %></td>-->
30
- <!-- <td><%#= link_to 'Destroy', block, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
31
- </tr>
32
- <% end %>
33
- </tbody>
34
- </table>
35
- </div>
36
- <div class="cx">
37
- <%= render template: '/antispam/clears/index.html' %>
38
- </div>
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <div class="row">
4
+ <div class="cx">
5
+ <h1>Blocks</h1>
6
+
7
+ <table>
8
+ <thead>
9
+ <tr>
10
+ <th>Ip</th>
11
+ <th>Provider</th>
12
+ <th>Controllername</th>
13
+ <th>Actionname</th>
14
+ <th>Threat</th>
15
+ <th colspan="3"></th>
16
+ </tr>
17
+ </thead>
18
+
19
+ <tbody>
20
+ <% Antispam::Block.all.order(created_at: :desc).limit(50).each do |block| %>
21
+ <tr>
22
+ <td><%= block.ip %></td>
23
+ <td><%= block.provider %></td>
24
+ <td><%= block.controllername %></td>
25
+ <td><%= block.actionname %></td>
26
+ <td><%= block.threat %></td>
27
+ <td><%= time_ago_in_words block.created_at %> ago</td>
28
+ <!-- <td><%#= link_to 'Show', block %></td>-->
29
+ <!-- <td><%#= link_to 'Edit', edit_block_path(block) %></td>-->
30
+ <!-- <td><%#= link_to 'Destroy', block, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
31
+ </tr>
32
+ <% end %>
33
+ </tbody>
34
+ </table>
35
+ </div>
36
+ <div class="cx">
37
+ <%= render template: '/antispam/clears/index', formats: :html %>
38
+ </div>
39
39
  </div>
@@ -1,32 +1,32 @@
1
- <p id="notice"><%= notice %></p>
2
-
3
- <h1>Clears</h1>
4
-
5
- <table>
6
- <thead>
7
- <tr>
8
- <th>Ip</th>
9
- <th>Result</th>
10
- <th>Answer</th>
11
- <th>Threat before</th>
12
- <th>Threat after</th>
13
- <th colspan="3"></th>
14
- </tr>
15
- </thead>
16
-
17
- <tbody>
18
- <% Antispam::Clear.all.order(created_at: :desc).limit(50).each do |clear| %>
19
- <tr>
20
- <td><%= clear.ip %></td>
21
- <td><%= clear.result %></td>
22
- <td><%= clear.answer %></td>
23
- <td><%= clear.threat_before %></td>
24
- <td><%= clear.threat_after %></td>
25
- <td><%= time_ago_in_words clear.created_at %> ago</td>
26
- <!-- <td><%#= link_to 'Show', clear %></td>-->
27
- <!-- <td><%#= link_to 'Edit', edit_clear_path(clear) %></td>-->
28
- <!-- <td><%#= link_to 'Destroy', clear, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
29
- </tr>
30
- <% end %>
31
- </tbody>
32
- </table>
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <h1>Clears</h1>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Ip</th>
9
+ <th>Result</th>
10
+ <th>Answer</th>
11
+ <th>Threat before</th>
12
+ <th>Threat after</th>
13
+ <th colspan="3"></th>
14
+ </tr>
15
+ </thead>
16
+
17
+ <tbody>
18
+ <% Antispam::Clear.all.order(created_at: :desc).limit(50).each do |clear| %>
19
+ <tr>
20
+ <td><%= clear.ip %></td>
21
+ <td><%= clear.result %></td>
22
+ <td><%= clear.answer %></td>
23
+ <td><%= clear.threat_before %></td>
24
+ <td><%= clear.threat_after %></td>
25
+ <td><%= time_ago_in_words clear.created_at %> ago</td>
26
+ <!-- <td><%#= link_to 'Show', clear %></td>-->
27
+ <!-- <td><%#= link_to 'Edit', edit_clear_path(clear) %></td>-->
28
+ <!-- <td><%#= link_to 'Destroy', clear, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
29
+ </tr>
30
+ <% end %>
31
+ </tbody>
32
+ </table>
@@ -1,15 +1,15 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Antispam</title>
5
- <%= csrf_meta_tags %>
6
- <%= csp_meta_tag %>
7
- <style>.row { width:100%;display: flex;} .cx { width: 50%; }</style>
8
- <%#= stylesheet_link_tag "antispam/application", media: "all" %>
9
- </head>
10
- <body>
11
-
12
- <%= yield %>
13
-
14
- </body>
15
- </html>
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Antispam</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+ <style>.row { width:100%;display: flex;} .cx { width: 50%; }</style>
8
+ <%#= stylesheet_link_tag "antispam/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
@@ -1,5 +1,5 @@
1
- class AddThreatToAntispamBlocks < ActiveRecord::Migration[6.1]
2
- def change
3
- add_column :antispam_blocks, :threat, :integer
4
- end
5
- end
1
+ class AddThreatToAntispamBlocks < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :antispam_blocks, :threat, :integer
4
+ end
5
+ end
@@ -2,28 +2,33 @@ require 'resolv'
2
2
  module Antispam
3
3
  module Blacklists
4
4
  class Httpbl
5
- def self.check(ip, key)
5
+ def self.check(ip, key, verbose)
6
6
  threat = 0
7
7
  begin
8
- return get_old_result(ip) if get_old_result(ip)
8
+ old_result = get_old_result(ip)
9
+ if old_result
10
+ Rails.logger.info "Returning old result for #{ip}." if verbose
11
+ return get_old_result(ip)
12
+ end
9
13
  check = ip.split('.').reverse.join('.')
10
14
  host = key + '.' + check + ".dnsbl.httpbl.org"
11
15
  address = Resolv::getaddress(host)
12
16
  z,days,threat,iptype = address.split('.')
13
- Rails.logger.info "Spam located: #{iptype} type at #{threat} threat. (#{ip} - #{address})"
17
+ Rails.logger.info "Spam located: #{iptype} type at #{threat} threat. (#{ip} - #{address})" if verbose
18
+ threat = threat.to_i
14
19
  # Create or update
15
- if (threat.to_i > 30)
16
- Rails.logger.info "Spamcheck: Very high, over 30!"
20
+ if (threat > 30)
21
+ Rails.logger.info "Spamcheck: Very high, over 30!" if verbose
17
22
  end
18
23
  rescue Exception => e
19
24
  case e
20
25
  when Resolv::ResolvError #Not spam! This blacklist gives an error when there's no spam threat.
21
- Rails.logger.info "Spamcheck: OK! Resolve error means the httpbl does not consider this spam."
26
+ Rails.logger.info "Spamcheck: OK! Resolve error means the httpbl does not consider this spam." if verbose
22
27
  when Interrupt #Something broke while trying to check blacklist.
23
- Rails.logger.info "Spamcheck: Interrupt when trying to resolve http blacklist. Possible timeout?"
28
+ Rails.logger.info "Spamcheck: Interrupt when trying to resolve http blacklist. Possible timeout?" if verbose
24
29
  else # Time Out
25
- Rails.logger.info "Spamcheck: There was an error, possibly a time out, when checking this IP."
26
- Rails.logger.info e.to_s
30
+ Rails.logger.info "Spamcheck: There was an error, possibly a time out, when checking this IP." if verbose
31
+ Rails.logger.info e.to_s if verbose
27
32
  end
28
33
  end
29
34
  update_old_result(ip, threat)
@@ -0,0 +1,20 @@
1
+ module Antispam
2
+ module Checker
3
+ # Checks content for spam
4
+ # check(options, spamcheck_providers)
5
+ # Usage: check({content: "No spam here"}, {defendium: 'MY_API_KEY'}})
6
+ def self.check(options = {}, spamcheck_providers = {defendium: 'YOUR_KEY'})
7
+ Rails.logger.info "Content was nil for spamcheck." if options[:content].nil? && options[:verbose]
8
+ return if options[:content].nil?
9
+ Rails.logger.info "Spamcheckers should be a hash" if (!(options[:spamcheck_providers].is_a? Hash)) && options[:verbose]
10
+ results = []
11
+ spamcheck_providers.each do |spamchecker_name, spamchecker_api_key|
12
+ if spamchecker_name == :defendium
13
+ results.append Antispam::Spamcheckers::Defendium.check(options[:content], spamchecker_api_key, options[:verbose])
14
+ end
15
+ end
16
+ result = Antispam::SpamcheckResult.new(results)
17
+ return result
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module Antispam
2
+ class SpamcheckResult
3
+ def initialize(results)
4
+ @results = results
5
+ end
6
+ def is_spam?
7
+ @results.select{|x| x > 0}.present?
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ #require 'resolv'
2
+ module Antispam
3
+ module Spamcheckers
4
+ class Defendium
5
+ def self.check(content, key, verbose)
6
+ # nethttp2.rb
7
+ require 'uri'
8
+ require 'net/http'
9
+
10
+ uri = URI('https://api.defendium.com/check')
11
+ params = { secret_key: key, content: content }
12
+ uri.query = URI.encode_www_form(params)
13
+
14
+ res = Net::HTTP.get_response(uri)
15
+ if res.is_a?(Net::HTTPSuccess)
16
+ result = res.body.to_json
17
+ if result["warnings"]
18
+ Rails.logger.info result["warnings"]
19
+ end
20
+ if result["result"]
21
+ return 1
22
+ else
23
+ return 0
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,48 +1,57 @@
1
- module Antispam
2
- module Tools
3
- # before_action :check_ip_against_database
4
- def check_ip_against_database(options = {ip_blacklists: {default: ''}})
5
- return if request.get?
6
- return if skip_if_user_whitelisted
7
- return if controller_name == "validate"
8
- ip = request.remote_ip
9
- # First, check IP blacklists.
10
- if (options[:ip_blacklists])
11
- if options[:ip_blacklists][:default]
12
- options[:ip_blacklists][:httpbl] = options[:ip_blacklists][:default]
13
- options[:ip_blacklists].delete(:default)
14
- end
15
- check_ip_against_blacklists(ip, options[:ip_blacklists], options[:verbose])
16
- end
17
- # Second, check for weird countries.
18
- if (options[:scrutinize_countries_except])
19
-
20
- end
21
- Rails.logger.info "Got to this function. #{ip}"
22
- puts "Got to this function. #{ip}"
23
- end
24
- def check_ip_against_blacklists(ip, lists, verbose)
25
- lists.each do |provider_name, provider_api_key|
26
- puts "Checking provider: #{provider_name}" if verbose
27
- if provider_name == :httpbl
28
- result = Antispam::Blacklists::Httpbl.check(ip, provider_api_key)
29
- puts result if verbose
30
- if (result > 30)
31
- Block.create(ip: ip, provider: provider_name, threat: result)
32
- redirect_to '/antispam/validate'
33
- end
34
- end
35
- end
36
- end
37
-
38
- def skip_if_user_whitelisted
39
- if respond_to? :current_user
40
- if current_user && current_user.respond_to?(:antispam_whitelisted?)
41
- return true if current_user.antispam_whitelisted?
42
- end
43
- end
44
- end
45
-
46
-
47
- end
48
- end
1
+ module Antispam
2
+ module Tools
3
+ # Checks spam against an IP database of spammers.
4
+ # Usage: before_action :check_ip_against_database
5
+ def check_ip_against_database(options = {ip_blacklists: {default: ''}})
6
+ if (options[:methods])
7
+ return if request.get? unless options[:methods].include?(:get)
8
+ return if request.post? unless options[:methods].include?(:post)
9
+ return if request.put? unless options[:methods].include?(:put)
10
+ return if request.patch? unless options[:methods].include?(:patch)
11
+ return if request.delete? unless options[:methods].include?(:delete)
12
+ else
13
+ return if request.get?
14
+ end
15
+ return if skip_if_user_whitelisted
16
+ return if controller_name == "validate"
17
+ ip = request.remote_ip
18
+ # First, check IP blacklists.
19
+ if (options[:ip_blacklists])
20
+ if options[:ip_blacklists][:default]
21
+ options[:ip_blacklists][:httpbl] = options[:ip_blacklists][:default]
22
+ options[:ip_blacklists].delete(:default)
23
+ end
24
+ check_ip_against_blacklists(ip, options[:ip_blacklists], options[:verbose])
25
+ end
26
+ # Second, check for weird countries.
27
+ if (options[:scrutinize_countries_except])
28
+
29
+ end
30
+ Rails.logger.info "Completed IP database check. #{ip}" if options[:verbose]
31
+ end
32
+ # Checks the specific blacklists
33
+ def check_ip_against_blacklists(ip, lists, verbose)
34
+ lists.each do |provider_name, provider_api_key|
35
+ Rails.logger.info "Checking provider: #{provider_name}" if verbose
36
+ if provider_name == :httpbl
37
+ result = Antispam::Blacklists::Httpbl.check(ip, provider_api_key, verbose)
38
+ Rails.logger.info(result) if verbose
39
+ if (result > 30)
40
+ Block.create(ip: ip, provider: provider_name, threat: result)
41
+ redirect_to '/antispam/validate'
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def skip_if_user_whitelisted
48
+ if respond_to? :current_user
49
+ if current_user && current_user.respond_to?(:antispam_whitelisted?)
50
+ return true if current_user.antispam_whitelisted?
51
+ end
52
+ end
53
+ end
54
+
55
+
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
- module Antispam
2
- VERSION = '0.1.4'
3
- end
1
+ module Antispam
2
+ VERSION = '0.1.7'
3
+ end
data/lib/antispam.rb CHANGED
@@ -1,11 +1,17 @@
1
- require "antispam/version"
2
- require "antispam/engine"
3
- require "antispam/tools"
4
- require "antispam/blacklists/httpbl"
5
-
6
- module Antispam
7
- ActiveSupport.on_load(:action_controller) do
8
- # self refers to ActionController::Base here
9
- self.include Antispam::Tools
10
- end
11
- end
1
+ require "antispam/version"
2
+ require "antispam/engine"
3
+ require "antispam/tools"
4
+ require "antispam/checker"
5
+ require "antispam/blacklists/httpbl"
6
+ require "antispam/spamcheckers/defendium"
7
+ require "antispam/results"
8
+
9
+ module Antispam
10
+ ActiveSupport.on_load(:action_controller) do
11
+ # self refers to ActionController::Base here
12
+ # This way is removed because below may be more compatible.
13
+ # self.include Antispam::Tools
14
+ # Would the below be a better (clearer? more compatible?) way to do this?
15
+ ActionController::Base.send(:include, Antispam::Tools)
16
+ end
17
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: antispam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Kopf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-31 00:00:00.000000000 Z
11
+ date: 2023-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.0
19
+ version: 6.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.0
26
+ version: 6.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: image_processing
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-http
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: Antispam checks DNS blacklists and helps prevent spam on your site.
42
56
  email:
43
57
  - antispam@ryankopf.com
@@ -83,20 +97,14 @@ files:
83
97
  - app/models/antispam/challenge.rb
84
98
  - app/models/antispam/clear.rb
85
99
  - app/models/antispam/ip.rb
86
- - app/views/antispam/blocks/_form.html.erb
87
- - app/views/antispam/blocks/edit.html.erb
88
100
  - app/views/antispam/blocks/index.html.erb
89
- - app/views/antispam/blocks/new.html.erb
90
101
  - app/views/antispam/blocks/show.html.erb
91
102
  - app/views/antispam/challenges/_form.html.erb
92
103
  - app/views/antispam/challenges/edit.html.erb
93
104
  - app/views/antispam/challenges/index.html.erb
94
105
  - app/views/antispam/challenges/new.html.erb
95
106
  - app/views/antispam/challenges/show.html.erb
96
- - app/views/antispam/clears/_form.html.erb
97
- - app/views/antispam/clears/edit.html.erb
98
107
  - app/views/antispam/clears/index.html.erb
99
- - app/views/antispam/clears/new.html.erb
100
108
  - app/views/antispam/clears/show.html.erb
101
109
  - app/views/antispam/validate/index.html.erb
102
110
  - app/views/layouts/antispam/application.html.erb
@@ -108,7 +116,10 @@ files:
108
116
  - db/migrate/20210131165122_add_threat_to_antispam_blocks.rb
109
117
  - lib/antispam.rb
110
118
  - lib/antispam/blacklists/httpbl.rb
119
+ - lib/antispam/checker.rb
111
120
  - lib/antispam/engine.rb
121
+ - lib/antispam/results.rb
122
+ - lib/antispam/spamcheckers/defendium.rb
112
123
  - lib/antispam/tools.rb
113
124
  - lib/antispam/version.rb
114
125
  - lib/tasks/antispam_tasks.rake
@@ -135,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
146
  - !ruby/object:Gem::Version
136
147
  version: '0'
137
148
  requirements: []
138
- rubygems_version: 3.1.4
149
+ rubygems_version: 3.4.4
139
150
  signing_key:
140
151
  specification_version: 4
141
152
  summary: A spam prevention gem.
@@ -1,37 +0,0 @@
1
- <%= form_with(model: block) do |form| %>
2
- <% if block.errors.any? %>
3
- <div id="error_explanation">
4
- <h2><%= pluralize(block.errors.count, "error") %> prohibited this block from being saved:</h2>
5
-
6
- <ul>
7
- <% block.errors.each do |error| %>
8
- <li><%= error.full_message %></li>
9
- <% end %>
10
- </ul>
11
- </div>
12
- <% end %>
13
-
14
- <div class="field">
15
- <%= form.label :ip %>
16
- <%= form.text_field :ip %>
17
- </div>
18
-
19
- <div class="field">
20
- <%= form.label :provider %>
21
- <%= form.text_field :provider %>
22
- </div>
23
-
24
- <div class="field">
25
- <%= form.label :controllername %>
26
- <%= form.text_field :controllername %>
27
- </div>
28
-
29
- <div class="field">
30
- <%= form.label :actionname %>
31
- <%= form.text_field :actionname %>
32
- </div>
33
-
34
- <div class="actions">
35
- <%= form.submit %>
36
- </div>
37
- <% end %>
@@ -1,6 +0,0 @@
1
- <h1>Editing Block</h1>
2
-
3
- <%= render 'form', block: @block %>
4
-
5
- <%= link_to 'Show', @block %> |
6
- <%= link_to 'Back', blocks_path %>
@@ -1,5 +0,0 @@
1
- <h1>New Block</h1>
2
-
3
- <%= render 'form', block: @block %>
4
-
5
- <%= link_to 'Back', blocks_path %>
@@ -1,42 +0,0 @@
1
- <%= form_with(model: clear) do |form| %>
2
- <% if clear.errors.any? %>
3
- <div id="error_explanation">
4
- <h2><%= pluralize(clear.errors.count, "error") %> prohibited this clear from being saved:</h2>
5
-
6
- <ul>
7
- <% clear.errors.each do |error| %>
8
- <li><%= error.full_message %></li>
9
- <% end %>
10
- </ul>
11
- </div>
12
- <% end %>
13
-
14
- <div class="field">
15
- <%= form.label :ip %>
16
- <%= form.text_field :ip %>
17
- </div>
18
-
19
- <div class="field">
20
- <%= form.label :result %>
21
- <%= form.text_field :result %>
22
- </div>
23
-
24
- <div class="field">
25
- <%= form.label :answer %>
26
- <%= form.text_field :answer %>
27
- </div>
28
-
29
- <div class="field">
30
- <%= form.label :threat_before %>
31
- <%= form.number_field :threat_before %>
32
- </div>
33
-
34
- <div class="field">
35
- <%= form.label :threat_after %>
36
- <%= form.number_field :threat_after %>
37
- </div>
38
-
39
- <div class="actions">
40
- <%= form.submit %>
41
- </div>
42
- <% end %>
@@ -1,6 +0,0 @@
1
- <h1>Editing Clear</h1>
2
-
3
- <%= render 'form', clear: @clear %>
4
-
5
- <%= link_to 'Show', @clear %> |
6
- <%= link_to 'Back', clears_path %>
@@ -1,5 +0,0 @@
1
- <h1>New Clear</h1>
2
-
3
- <%= render 'form', clear: @clear %>
4
-
5
- <%= link_to 'Back', clears_path %>