antispam 0.2.0 → 0.2.3
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 +20 -20
- data/README.md +129 -128
- data/Rakefile +18 -18
- data/app/assets/config/antispam_manifest.js +1 -1
- data/app/assets/stylesheets/antispam/application.css +15 -15
- data/app/assets/stylesheets/antispam/blocks.css +4 -4
- data/app/assets/stylesheets/antispam/challenges.css +4 -4
- data/app/assets/stylesheets/antispam/clears.css +4 -4
- data/app/assets/stylesheets/scaffold.css +80 -80
- data/app/controllers/antispam/application_controller.rb +11 -11
- data/app/controllers/antispam/blocks_controller.rb +28 -28
- data/app/controllers/antispam/challenges_controller.rb +50 -50
- data/app/controllers/antispam/clears_controller.rb +28 -28
- data/app/controllers/antispam/validate_controller.rb +12 -12
- data/app/helpers/antispam/application_helper.rb +4 -4
- data/app/helpers/antispam/blocks_helper.rb +4 -4
- data/app/helpers/antispam/challenges_helper.rb +4 -4
- data/app/helpers/antispam/clears_helper.rb +4 -4
- data/app/jobs/antispam/application_job.rb +4 -4
- data/app/mailers/antispam/application_mailer.rb +6 -6
- data/app/models/antispam/application_record.rb +5 -5
- data/app/models/antispam/block.rb +4 -4
- data/app/models/antispam/challenge.rb +26 -26
- data/app/models/antispam/clear.rb +4 -4
- data/app/models/antispam/ip.rb +11 -6
- data/app/views/antispam/blocks/index.html.erb +38 -38
- data/app/views/antispam/blocks/show.html.erb +24 -24
- data/app/views/antispam/challenges/_form.html.erb +32 -32
- data/app/views/antispam/challenges/edit.html.erb +6 -6
- data/app/views/antispam/challenges/index.html.erb +31 -31
- data/app/views/antispam/challenges/new.html.erb +5 -5
- data/app/views/antispam/challenges/show.html.erb +19 -19
- data/app/views/antispam/clears/index.html.erb +32 -32
- data/app/views/antispam/clears/show.html.erb +29 -29
- data/app/views/antispam/validate/index.html.erb +16 -14
- data/app/views/layouts/antispam/application.html.erb +25 -15
- data/config/routes.rb +7 -7
- data/db/migrate/20210130213708_create_antispam_ips.rb +12 -12
- data/db/migrate/20210130214835_create_antispam_challenges.rb +11 -11
- data/db/migrate/20210130234107_create_antispam_blocks.rb +12 -12
- data/db/migrate/20210130235537_create_antispam_clears.rb +13 -13
- data/db/migrate/20210131165122_add_threat_to_antispam_blocks.rb +5 -5
- data/lib/antispam/blacklists/httpbl.rb +49 -49
- data/lib/antispam/checker.rb +30 -30
- data/lib/antispam/engine.rb +5 -5
- data/lib/antispam/results.rb +18 -18
- data/lib/antispam/spamcheckers/defendium.rb +29 -29
- data/lib/antispam/tools.rb +59 -59
- data/lib/antispam/version.rb +3 -3
- data/lib/antispam.rb +21 -17
- data/lib/tasks/antispam_tasks.rake +4 -4
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 926be70eedd3e1ed1cd3d2de620fb76f600b9c0fc1dd9655616fec74dd266a1b
|
4
|
+
data.tar.gz: eb9f451155c5b396b65b4cb83ce8d712acf1505f3d324efa97f0066a13dcb995
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51acf3def424da9283b592a5384a771c3270e1ad87a22620e81f1a7b42201b92f687c4ded7640e44e08e1acd7b42af8808a08c3ea935e79bbe2091446286be05
|
7
|
+
data.tar.gz: 257836862a2566429f0baf6d606fe8c492fefedf3702651c44bf7987de51b285c99fd4a5efdc7fa37b1d100236800a682feb6c934ae30573d2a1ab5eda7363a9
|
data/MIT-LICENSE
CHANGED
@@ -1,20 +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.
|
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
CHANGED
@@ -1,128 +1,129 @@
|
|
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 relies on the lightning-quick httpbl from Project Honey Pot.
|
9
|
-
|
10
|
-
The second feature allows you to submit user-provided content to a spam
|
11
|
-
checking service that uses machine learning and a database of content to
|
12
|
-
determine whether the user's submitted content is spam. It uses the blazing
|
13
|
-
fast Defendium API I created to quickly determine if submitted content is
|
14
|
-
spam or not. Defendium's [pricing](https://defendium.com/pricing) is free
|
15
|
-
for up to 1,000 API calls per day, which should be sufficient for 99% of users.
|
16
|
-
|
17
|
-
The two features are optional, and you can use either one without the other.
|
18
|
-
|
19
|
-
## Spam Content Checking - Usage
|
20
|
-
|
21
|
-
```
|
22
|
-
result = Antispam::Checker.check(content: @comment.body)
|
23
|
-
if result.is_spam?
|
24
|
-
redirect_to "/access_denied"
|
25
|
-
else
|
26
|
-
@comment.save
|
27
|
-
end
|
28
|
-
```
|
29
|
-
|
30
|
-
## Bad IP Checking - Usage
|
31
|
-
|
32
|
-
The gem is used by adding this to your ApplicationController.rb
|
33
|
-
|
34
|
-
```
|
35
|
-
before_action do
|
36
|
-
check_ip_against_database(ip_blacklists: {default: '
|
37
|
-
end
|
38
|
-
```
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
$
|
94
|
-
$ rails
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
ANY
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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 relies on the lightning-quick httpbl from Project Honey Pot.
|
9
|
+
|
10
|
+
The second feature allows you to submit user-provided content to a spam
|
11
|
+
checking service that uses machine learning and a database of content to
|
12
|
+
determine whether the user's submitted content is spam. It uses the blazing
|
13
|
+
fast Defendium API I created to quickly determine if submitted content is
|
14
|
+
spam or not. Defendium's [pricing](https://defendium.com/pricing) is free
|
15
|
+
for up to 1,000 API calls per day, which should be sufficient for 99% of users.
|
16
|
+
|
17
|
+
The two features are optional, and you can use either one without the other.
|
18
|
+
|
19
|
+
## Spam Content Checking - Usage
|
20
|
+
|
21
|
+
```
|
22
|
+
result = Antispam::Checker.check(content: @comment.body)
|
23
|
+
if result.is_spam?
|
24
|
+
redirect_to "/access_denied"
|
25
|
+
else
|
26
|
+
@comment.save
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
## Bad IP Checking - Usage
|
31
|
+
|
32
|
+
The gem is used by adding this to your ApplicationController.rb
|
33
|
+
|
34
|
+
```
|
35
|
+
before_action do
|
36
|
+
check_ip_against_database(ip_blacklists: {default: 'your_api_key_here'}, verbose: true)
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
API Keys can be obtained by visiting the [httpbl](https://www.projecthoneypot.org/httpbl.php)
|
41
|
+
at projecthoneypot.org
|
42
|
+
|
43
|
+
Once the filter is setup, everything else is handled for your application.
|
44
|
+
By default the gem will run during any request that is not a GET request.
|
45
|
+
|
46
|
+
When a POST/PATCH/ETC (non-GET) request comes in, the IP blacklist is checked
|
47
|
+
to see if the poster is on a spam blacklist. If the poster is on the blacklist
|
48
|
+
then the request is automatically blocked and redirected to a captcha page. A
|
49
|
+
real user can then enter the captcha to bypass the block. In the future other
|
50
|
+
captcha options may be supported, such as mechanical (hashing) captcha and
|
51
|
+
other types of invisible captcha.
|
52
|
+
|
53
|
+
Eventually configurable settings may be in place to give other options when
|
54
|
+
a spammy IP is detected, but the current defaults are set to only block spam
|
55
|
+
in cases where the blacklist is quite certain the IP is only doing spam.
|
56
|
+
|
57
|
+
You can change the filter to run during other requests.
|
58
|
+
|
59
|
+
```
|
60
|
+
before_action do
|
61
|
+
check_ip_against_database(ip_blacklists: {default: 'yourcodehere'}, methods: [:get,:post,:put,:patch,:delete])
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
Blacklist database lookups are cached for 24 hours, and cached results won't need
|
66
|
+
to slowdown your app by additional http requests on the backend.
|
67
|
+
|
68
|
+
The gem needs to create some database tables to function; these store the cached
|
69
|
+
blacklist database lookups, and any actions caused by the gem.
|
70
|
+
|
71
|
+
You need to add this to your routes.rb
|
72
|
+
```
|
73
|
+
mount Antispam::Engine => "/antispam"
|
74
|
+
```
|
75
|
+
You can see what IP addresses have been blocked by going to /antispam/blocks
|
76
|
+
but your ApplicationController.rb must respond to ```is_admin?``` function.
|
77
|
+
|
78
|
+
|
79
|
+
## Installation
|
80
|
+
Add this line to your application's Gemfile:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
gem 'antispam'
|
84
|
+
```
|
85
|
+
|
86
|
+
And then execute:
|
87
|
+
```bash
|
88
|
+
$ bundle
|
89
|
+
```
|
90
|
+
|
91
|
+
Or install it yourself as:
|
92
|
+
```bash
|
93
|
+
$ gem install antispam
|
94
|
+
$ rails antispam:install:migrations
|
95
|
+
$ rails db:migrate SCOPE=antispam
|
96
|
+
```
|
97
|
+
The gem depends on image_processing, which depends on vips. We are using vips to
|
98
|
+
generate captcha images.
|
99
|
+
```
|
100
|
+
sudo apt install libvips-tools
|
101
|
+
```
|
102
|
+
|
103
|
+
## Development
|
104
|
+
|
105
|
+
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.
|
106
|
+
|
107
|
+
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).
|
108
|
+
|
109
|
+
## Contributing
|
110
|
+
|
111
|
+
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).
|
112
|
+
|
113
|
+
## License
|
114
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
115
|
+
|
116
|
+
## Code of Conduct
|
117
|
+
|
118
|
+
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).
|
119
|
+
|
120
|
+
## NO WARRANTY
|
121
|
+
|
122
|
+
THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND,
|
123
|
+
EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO,
|
124
|
+
ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS,
|
125
|
+
ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
126
|
+
OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE
|
127
|
+
ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO
|
128
|
+
THE SUBJECT SOFTWARE. THIS SOFTWARE IS PROVIDED "AS IS." IF YOUR JURISDICTION
|
129
|
+
DOES NOT ALLOW THESE LIMITATIONS THEN YOU MAY NOT USE THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,18 +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
|
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
|
@@ -1 +1 @@
|
|
1
|
-
//= link_directory ../stylesheets/antispam .css
|
1
|
+
//= link_directory ../stylesheets/antispam .css
|
@@ -1,15 +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
|
-
*/
|
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
|
+
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
2
|
-
Place all the styles related to the matching controller here.
|
3
|
-
They will automatically be included in application.css.
|
4
|
-
*/
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
2
|
-
Place all the styles related to the matching controller here.
|
3
|
-
They will automatically be included in application.css.
|
4
|
-
*/
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
2
|
-
Place all the styles related to the matching controller here.
|
3
|
-
They will automatically be included in application.css.
|
4
|
-
*/
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
@@ -1,80 +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
|
-
}
|
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
|
+
}
|
@@ -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
|