antispam 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 636c6cfd1e3a5c84182eaa1e19966e553a2098c4f3a01a049cdbe4613165a52e
4
- data.tar.gz: 8a53d23ef78da214962bd81411a97a720d5eba3a15817d3f7ccd5bfac81719ec
3
+ metadata.gz: f04775ef37b7cf6a564c81bb3f664dbecf7b638fdf95db9beafd5484e5ceb3e5
4
+ data.tar.gz: bd219f97bc7ff11bf36fe4e98377c0e4b920a93e10f27fa4cae9a170db1d2ab8
5
5
  SHA512:
6
- metadata.gz: b4d6e23e0432af6b62b7cd9e469c2393a9e4f4513b13d93d282e6841062bd706d70fa44dd6bed0d79658da80ff52827ee8ba9d63baa0a84df2112a7fd313b3dd
7
- data.tar.gz: 9ca4921062395565e50fa29daf9d56bd3e691b5a675fb34bc4d6ec5e1378da1f3be5b19bdc73294be7fcb55b8e3d766819c140ef45b602d8904818eccf10f187
6
+ metadata.gz: 18e2653f47965506ef9673c01eb4bc15f1367c253822e8de402f5d1862020b6b60729ae444d03dccb89cf40583263cdef6845bac656512dbc1fb6499596d58cb
7
+ data.tar.gz: 5e19607550a09cc727785ae31fd0bc4221944f2a1a14e2573a43ea4c12969124507e3514dff346d1e8658caf380f2190d0118ced16ef049a3da4c11312126707
data/README.md CHANGED
@@ -5,21 +5,25 @@ databases, accessible for free.
5
5
 
6
6
  The first feature checks against an IP database of spam, allowing you
7
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.
8
+ It relies on the lightning-quick httpbl from Project Honey Pot.
10
9
 
11
10
  The second feature allows you to submit user-provided content to a spam
12
11
  checking service that uses machine learning and a database of content to
13
- determine whether the user's submitted content is spam.
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.
14
18
 
15
19
  ## Spam Content Checking - Usage
16
20
 
17
21
  ```
18
22
  result = Antispam::Checker.check(content: @comment.body)
19
23
  if result.is_spam?
20
- @comment.save
21
- else
22
24
  redirect_to "/access_denied"
25
+ else
26
+ @comment.save
23
27
  end
24
28
  ```
25
29
 
@@ -38,6 +42,17 @@ Codes are from the [httpbl](https://www.projecthoneypot.org/httpbl.php) at proje
38
42
  Once the filter is setup, everything else is handled for your application.
39
43
  By default the gem will run during any request that is not a GET request.
40
44
 
45
+ When a POST/PATCH/ETC (non-GET) request comes in, the IP blacklist is checked
46
+ to see if the poster is on a spam blacklist. If the poster is on the blacklist
47
+ then the request is automatically blocked and redirected to a captcha page. A
48
+ real user can then enter the captcha to bypass the block. In the future other
49
+ captcha options may be supported, such as mechanical (hashing) captcha and
50
+ other types of invisible captcha.
51
+
52
+ Eventually configurable settings may be in place to give other options when
53
+ a spammy IP is detected, but the current defaults are set to only block spam
54
+ in cases where the blacklist is quite certain the IP is only doing spam.
55
+
41
56
  You can change the filter to run during other requests.
42
57
 
43
58
  ```
@@ -2,6 +2,7 @@ require 'resolv'
2
2
  module Antispam
3
3
  module Blacklists
4
4
  class Httpbl
5
+ # Returns a threat-level number, or 0 if no threat / no result.
5
6
  def self.check(ip, key, verbose)
6
7
  threat = 0
7
8
  begin
@@ -1,20 +1,31 @@
1
1
  module Antispam
2
2
  module Checker
3
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'})
4
+ # check(options)
5
+ # Usage: check({content: "No spam here", providers: { defendium: 'MY_API_KEY'}})
6
+ def self.check(options = {})
7
+ # Default provider. 'YOUR_KEY' works temporarily, giving a warning but also giving results
8
+ # eventually add something to tell users to add their own keys
9
+ # or choose their preferred provider, when more provider options are added.
10
+ options[:providers] ||= {defendium: 'YOUR_KEY'}
7
11
  Rails.logger.info "Content was nil for spamcheck." if options[:content].nil? && options[:verbose]
8
12
  return if options[:content].nil?
9
- Rails.logger.info "Spamcheckers should be a hash" if (!(options[:spamcheck_providers].is_a? Hash)) && options[:verbose]
13
+ Rails.logger.info "Spamcheckers should be a hash" if (!(options[:providers].is_a? Hash)) && options[:verbose]
10
14
  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
+ options[:providers].each do |spamchecker_name, spamchecker_api_key|
16
+ results.append spamchecker(spamchecker_name).check(options[:content], spamchecker_api_key, options[:verbose])
17
+ # if spamchecker_name == :defendium
18
+ # results.append Antispam::Spamcheckers::Defendium.check(options[:content], spamchecker_api_key, options[:verbose])
19
+ # end
15
20
  end
16
21
  result = Antispam::SpamcheckResult.new(results)
17
22
  return result
18
23
  end
24
+ def self.spamchecker(provider)
25
+ class_name = provider.to_s.camelize
26
+ raise Antispam::NoSuchSpamcheckerError unless Antispam::Spamcheckers.const_defined? class_name
27
+ Antispam::Spamcheckers.const_get class_name
28
+ end
19
29
  end
30
+ class NoSuchSpamcheckerError < StandardError; end
20
31
  end
@@ -7,4 +7,12 @@ module Antispam
7
7
  @results.select{|x| x > 0}.present?
8
8
  end
9
9
  end
10
+ class BlacklistResult
11
+ def initialize(results)
12
+ @results = results
13
+ end
14
+ def is_bad?
15
+ @results.select{|x| x > 30}.present?
16
+ end
17
+ end
10
18
  end
@@ -2,6 +2,7 @@
2
2
  module Antispam
3
3
  module Spamcheckers
4
4
  class Defendium
5
+ # Returns a boolean, 1 for spam, 0 for not spam.
5
6
  def self.check(content, key, verbose)
6
7
  # nethttp2.rb
7
8
  require 'uri'
@@ -31,19 +31,17 @@ module Antispam
31
31
  end
32
32
  # Checks the specific blacklists
33
33
  def check_ip_against_blacklists(ip, lists, verbose)
34
+ results = []
34
35
  lists.each do |provider_name, provider_api_key|
35
36
  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
37
+ results.append blacklist(provider_name).check(ip, provider_api_key, verbose)
38
+ end
39
+ result = Antispam::BlacklistResult.new(results)
40
+ if result.is_bad?
41
+ Block.create(ip: ip, provider: lists.keys.first, threat: result)
42
+ redirect_to '/antispam/validate'
44
43
  end
45
44
  end
46
-
47
45
  def skip_if_user_whitelisted
48
46
  if respond_to? :current_user
49
47
  if current_user && current_user.respond_to?(:antispam_whitelisted?)
@@ -51,7 +49,11 @@ module Antispam
51
49
  end
52
50
  end
53
51
  end
54
-
55
-
52
+ def blacklist(provider)
53
+ class_name = provider.to_s.camelize
54
+ raise Antispam::NoSuchBlacklistError unless Antispam::Blacklists.const_defined? class_name
55
+ Antispam::Blacklists.const_get class_name
56
+ end
56
57
  end
58
+ class NoSuchBlacklistError < StandardError; end
57
59
  end
@@ -1,3 +1,3 @@
1
1
  module Antispam
2
- VERSION = '0.1.7'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: antispam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Kopf