antispam 0.1.0
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +72 -0
- data/Rakefile +18 -0
- data/app/assets/config/antispam_manifest.js +1 -0
- data/app/assets/images/antispam/captcha/a.gif +0 -0
- data/app/assets/images/antispam/captcha/b.gif +0 -0
- data/app/assets/images/antispam/captcha/blank.gif +0 -0
- data/app/assets/images/antispam/captcha/c.gif +0 -0
- data/app/assets/images/antispam/captcha/d.gif +0 -0
- data/app/assets/images/antispam/captcha/e.gif +0 -0
- data/app/assets/images/antispam/captcha/f.gif +0 -0
- data/app/assets/images/antispam/captcha/g.gif +0 -0
- data/app/assets/images/antispam/captcha/h.gif +0 -0
- data/app/assets/images/antispam/captcha/i.gif +0 -0
- data/app/assets/images/antispam/captcha/j.gif +0 -0
- data/app/assets/images/antispam/captcha/k.gif +0 -0
- data/app/assets/images/antispam/captcha/l.gif +0 -0
- data/app/assets/stylesheets/antispam/application.css +15 -0
- data/app/assets/stylesheets/antispam/blocks.css +4 -0
- data/app/assets/stylesheets/antispam/challenges.css +4 -0
- data/app/assets/stylesheets/antispam/clears.css +4 -0
- data/app/assets/stylesheets/scaffold.css +80 -0
- data/app/controllers/antispam/application_controller.rb +4 -0
- data/app/controllers/antispam/blocks_controller.rb +70 -0
- data/app/controllers/antispam/challenges_controller.rb +49 -0
- data/app/controllers/antispam/clears_controller.rb +63 -0
- data/app/controllers/antispam/validate_controller.rb +12 -0
- data/app/helpers/antispam/application_helper.rb +4 -0
- data/app/helpers/antispam/blocks_helper.rb +4 -0
- data/app/helpers/antispam/challenges_helper.rb +4 -0
- data/app/helpers/antispam/clears_helper.rb +4 -0
- data/app/jobs/antispam/application_job.rb +4 -0
- data/app/mailers/antispam/application_mailer.rb +6 -0
- data/app/models/antispam/application_record.rb +5 -0
- data/app/models/antispam/block.rb +4 -0
- data/app/models/antispam/challenge.rb +26 -0
- data/app/models/antispam/clear.rb +4 -0
- data/app/models/antispam/ip.rb +7 -0
- data/app/views/antispam/blocks/_form.html.erb +37 -0
- data/app/views/antispam/blocks/edit.html.erb +6 -0
- data/app/views/antispam/blocks/index.html.erb +37 -0
- data/app/views/antispam/blocks/new.html.erb +5 -0
- data/app/views/antispam/blocks/show.html.erb +24 -0
- data/app/views/antispam/challenges/_form.html.erb +32 -0
- data/app/views/antispam/challenges/edit.html.erb +6 -0
- data/app/views/antispam/challenges/index.html.erb +31 -0
- data/app/views/antispam/challenges/new.html.erb +5 -0
- data/app/views/antispam/challenges/show.html.erb +19 -0
- data/app/views/antispam/clears/_form.html.erb +42 -0
- data/app/views/antispam/clears/edit.html.erb +6 -0
- data/app/views/antispam/clears/index.html.erb +32 -0
- data/app/views/antispam/clears/new.html.erb +5 -0
- data/app/views/antispam/clears/show.html.erb +29 -0
- data/app/views/antispam/validate/index.html.erb +14 -0
- data/app/views/layouts/antispam/application.html.erb +15 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20210130213708_create_antispam_ips.rb +12 -0
- data/db/migrate/20210130214835_create_antispam_challenges.rb +11 -0
- data/db/migrate/20210130234107_create_antispam_blocks.rb +12 -0
- data/db/migrate/20210130235537_create_antispam_clears.rb +13 -0
- data/lib/antispam.rb +11 -0
- data/lib/antispam/blacklists/httpbl.rb +43 -0
- data/lib/antispam/engine.rb +5 -0
- data/lib/antispam/tools.rb +49 -0
- data/lib/antispam/version.rb +3 -0
- data/lib/tasks/antispam_tasks.rake +4 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d0436bc2335d973b63d2ffb1e34a7a497ff9f86e2cf98d87c38fb2c5797f2fff
|
4
|
+
data.tar.gz: a8cfe2b31913ba9c7a4ad9f0153b5f59c9b140c36cdcca20086ea7db94a8a8ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9755957fce4a89628c1e2b587ee046da5fccaf4692a5f0a596fa2dc5afea282a68d05d04a8ad82689f5e9d30c3660bad5fcbf75184141648b8e17ab0d693dfef
|
7
|
+
data.tar.gz: 769deceafe70aafc9b5f98e1b1d995876ad98542a8c75a1633c75f6ea226331d5ce55270fce438f322927947fca539f59d60e6ea5e48603095c1e5656f906e96
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2021
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
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 have a user_has_role?("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).
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
4
|
+
load "rails/tasks/engine.rake"
|
5
|
+
|
6
|
+
load "rails/tasks/statistics.rake"
|
7
|
+
|
8
|
+
require "bundler/gem_tasks"
|
9
|
+
|
10
|
+
require "rake/testtask"
|
11
|
+
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = false
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :test
|
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/antispam .css
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,80 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #fff;
|
3
|
+
color: #333;
|
4
|
+
margin: 33px;
|
5
|
+
}
|
6
|
+
|
7
|
+
body, p, ol, ul, td {
|
8
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
9
|
+
font-size: 13px;
|
10
|
+
line-height: 18px;
|
11
|
+
}
|
12
|
+
|
13
|
+
pre {
|
14
|
+
background-color: #eee;
|
15
|
+
padding: 10px;
|
16
|
+
font-size: 11px;
|
17
|
+
}
|
18
|
+
|
19
|
+
a {
|
20
|
+
color: #000;
|
21
|
+
}
|
22
|
+
|
23
|
+
a:visited {
|
24
|
+
color: #666;
|
25
|
+
}
|
26
|
+
|
27
|
+
a:hover {
|
28
|
+
color: #fff;
|
29
|
+
background-color: #000;
|
30
|
+
}
|
31
|
+
|
32
|
+
th {
|
33
|
+
padding-bottom: 5px;
|
34
|
+
}
|
35
|
+
|
36
|
+
td {
|
37
|
+
padding: 0 5px 7px;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.field,
|
41
|
+
div.actions {
|
42
|
+
margin-bottom: 10px;
|
43
|
+
}
|
44
|
+
|
45
|
+
#notice {
|
46
|
+
color: green;
|
47
|
+
}
|
48
|
+
|
49
|
+
.field_with_errors {
|
50
|
+
padding: 2px;
|
51
|
+
background-color: red;
|
52
|
+
display: table;
|
53
|
+
}
|
54
|
+
|
55
|
+
#error_explanation {
|
56
|
+
width: 450px;
|
57
|
+
border: 2px solid red;
|
58
|
+
padding: 7px 7px 0;
|
59
|
+
margin-bottom: 20px;
|
60
|
+
background-color: #f0f0f0;
|
61
|
+
}
|
62
|
+
|
63
|
+
#error_explanation h2 {
|
64
|
+
text-align: left;
|
65
|
+
font-weight: bold;
|
66
|
+
padding: 5px 5px 5px 15px;
|
67
|
+
font-size: 12px;
|
68
|
+
margin: -7px -7px 0;
|
69
|
+
background-color: #c00;
|
70
|
+
color: #fff;
|
71
|
+
}
|
72
|
+
|
73
|
+
#error_explanation ul li {
|
74
|
+
font-size: 12px;
|
75
|
+
list-style: square;
|
76
|
+
}
|
77
|
+
|
78
|
+
label {
|
79
|
+
display: block;
|
80
|
+
}
|
@@ -0,0 +1,70 @@
|
|
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, :edit, :update, :destroy]
|
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
|
+
# # GET /blocks/new
|
18
|
+
# def new
|
19
|
+
# @block = Block.new
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # GET /blocks/1/edit
|
23
|
+
# def edit
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # POST /blocks
|
27
|
+
# def create
|
28
|
+
# @block = Block.new(block_params)
|
29
|
+
#
|
30
|
+
# if @block.save
|
31
|
+
# redirect_to @block, notice: 'Block was successfully created.'
|
32
|
+
# else
|
33
|
+
# render :new
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # PATCH/PUT /blocks/1
|
38
|
+
# def update
|
39
|
+
# if @block.update(block_params)
|
40
|
+
# redirect_to @block, notice: 'Block was successfully updated.'
|
41
|
+
# else
|
42
|
+
# render :edit
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # DELETE /blocks/1
|
47
|
+
# def destroy
|
48
|
+
# @block.destroy
|
49
|
+
# redirect_to blocks_url, notice: 'Block was successfully destroyed.'
|
50
|
+
# end
|
51
|
+
|
52
|
+
private
|
53
|
+
# Use callbacks to share common setup or constraints between actions.
|
54
|
+
def set_block
|
55
|
+
@block = Block.find(params[:id])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Only allow a list of trusted parameters through.
|
59
|
+
def block_params
|
60
|
+
params.require(:block).permit(:ip, :provider, :controllername, :actionname)
|
61
|
+
end
|
62
|
+
def must_be_admin
|
63
|
+
begin
|
64
|
+
return false unless user_has_role?("admin")
|
65
|
+
rescue
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,49 @@
|
|
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
|
@@ -0,0 +1,63 @@
|
|
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
|
+
# # GET /clears/new
|
18
|
+
# def new
|
19
|
+
# @clear = Clear.new
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # GET /clears/1/edit
|
23
|
+
# def edit
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # POST /clears
|
27
|
+
# def create
|
28
|
+
# @clear = Clear.new(clear_params)
|
29
|
+
#
|
30
|
+
# if @clear.save
|
31
|
+
# redirect_to @clear, notice: 'Clear was successfully created.'
|
32
|
+
# else
|
33
|
+
# render :new
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # PATCH/PUT /clears/1
|
38
|
+
# def update
|
39
|
+
# if @clear.update(clear_params)
|
40
|
+
# redirect_to @clear, notice: 'Clear was successfully updated.'
|
41
|
+
# else
|
42
|
+
# render :edit
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # DELETE /clears/1
|
47
|
+
# def destroy
|
48
|
+
# @clear.destroy
|
49
|
+
# redirect_to clears_url, notice: 'Clear was successfully destroyed.'
|
50
|
+
# end
|
51
|
+
|
52
|
+
private
|
53
|
+
# Use callbacks to share common setup or constraints between actions.
|
54
|
+
def set_clear
|
55
|
+
@clear = Clear.find(params[:id])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Only allow a list of trusted parameters through.
|
59
|
+
def clear_params
|
60
|
+
params.require(:clear).permit(:ip, :result, :answer, :threat_before, :threat_after)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|