legitbot 0.4.2 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 585e32c80a367b94dee89599e33e659ed9461404f5b66dc5f2d84a7ba03849a0
4
- data.tar.gz: dd60d23e4b7332817b6a6f3a2161ce15c57f5863efea1741902e1efb69fb2798
3
+ metadata.gz: 0ad027c85951667c22f02a0fde2347e5d1503493b07f4f041ab1f0965eae096b
4
+ data.tar.gz: a967d17674592fb06cefbebf8abe7fce9b72e49281f116ab337d0f888d46d326
5
5
  SHA512:
6
- metadata.gz: 3a89023768d7dd4b9cce76bd9e50cb1fd76d2cc88dd03518ea6c6ef70c880de91b6a7eb342e50fa89dbcb428cae19ab4c619ab8715b7c84041b7a60b967cebfd
7
- data.tar.gz: 745d57d3976bf59af9ffdc0f642cc6ccc85e2a3a261bcbfd40ad8644f34881c8765a884a420c85fdf19731de5ce8f18d4ad8ee3a2153a1a36fca402cf6d49a12
6
+ metadata.gz: be5c129e2d5e4f381a056744daa29907da3bb42849ff2ff33b7b45525d1175ad465e01f6f3e1b523b5163608ad747edbebea1c4bd3e355d927b3102ad3dca016
7
+ data.tar.gz: 9562a862188263637923035e0cc8b533f1f4153bc863c07a1b01538f2487c1052b0c68a4ca00dcf4085eb6a031c2cc92d264985fd429ecf47f8aadd46801eca0
@@ -0,0 +1,17 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ insert_final_newline = true
6
+ trim_trailing_whitespace = true
7
+ charset = utf-8
8
+
9
+ indent_style = space
10
+ indent_size = 2
11
+
12
+ [*.md]
13
+ trim_trailing_whitespace = false
14
+
15
+ [*.yml]
16
+ indent_style = space
17
+ indent_size = 2
@@ -0,0 +1,60 @@
1
+ name: build
2
+
3
+ on: [pull_request, push]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby: [ jruby, 2.6 ]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby }}
20
+ - name: Cache dependencies
21
+ uses: actions/cache@v1
22
+ with:
23
+ path: vendor/bundle
24
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
25
+ restore-keys: |
26
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-
27
+ - name: Install dependencies
28
+ run: |
29
+ bundle config path vendor/bundle
30
+ bundle install --jobs 4 --retry 3
31
+ - name: Run tests
32
+ run: bundle exec rake test
33
+
34
+ lint:
35
+ needs: test
36
+ runs-on: ubuntu-latest
37
+
38
+ strategy:
39
+ matrix:
40
+ ruby: [ 2.6 ]
41
+
42
+ steps:
43
+ - uses: actions/checkout@v2
44
+ - name: Set up Ruby
45
+ uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: ${{ matrix.ruby }}
48
+ - name: Cache dependencies
49
+ uses: actions/cache@v1
50
+ with:
51
+ path: vendor/bundle
52
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
53
+ restore-keys: |
54
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-
55
+ - name: Install dependencies
56
+ run: |
57
+ bundle config path vendor/bundle
58
+ bundle install --jobs 4 --retry 3
59
+ - name: Run linter
60
+ run: bundle exec rubocop
data/.gitignore CHANGED
@@ -4,3 +4,4 @@ Gemfile.lock
4
4
  *.gemfile.lock
5
5
  /pkg
6
6
  /tags
7
+ /vendor
@@ -1,9 +1,3 @@
1
1
  AllCops:
2
- Include:
3
- - '**/*.gemspec'
4
- - '**/Gemfile'
5
- - '**/Rakefile'
6
- - 'lib/**/*.rb'
7
- - 'test/**/*.rb'
8
- Exclude:
9
- - 'pkg/**'
2
+ CacheRootDirectory: 'vendor'
3
+ NewCops: enable
@@ -0,0 +1 @@
1
+ 2.4
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Legitbot [![Build Status](https://secure.travis-ci.org/alaz/legitbot.png?branch=master)](http://travis-ci.org/alaz/legitbot) [![Gem Version](https://badge.fury.io/rb/legitbot.svg)](https://badge.fury.io/rb/legitbot)
1
+ # Legitbot ![](https://github.com/alaz/legitbot/workflows/build/badge.svg) [![Gem Version](https://badge.fury.io/rb/legitbot.svg)](https://badge.fury.io/rb/legitbot)
2
2
 
3
3
  Ruby gem to check that an IP belongs to a bot, typically a search
4
4
  engine. This can be of help in protecting a web site from fake search
@@ -44,6 +44,7 @@ end
44
44
  ## Supported
45
45
 
46
46
  * [Ahrefs](https://ahrefs.com/robot)
47
+ * [Alexa](https://support.alexa.com/hc/en-us/articles/360046707834-What-are-the-IP-addresses-for-Alexa-s-Certify-and-Site-Audit-crawlers-)
47
48
  * [Applebot](https://support.apple.com/en-us/HT204683)
48
49
  * [Baidu spider](http://help.baidu.com/question?prod_en=master&class=498&id=1000973)
49
50
  * [Bingbot](https://blogs.bing.com/webmaster/2012/08/31/how-to-verify-that-bingbot-is-bingbot/)
@@ -67,3 +68,8 @@ Apache 2.0
67
68
  detects bots by `User-Agent`
68
69
  * [crawler_detect](https://github.com/loadkpi/crawler_detect) is a Ruby gem and Rack
69
70
  middleware to detect crawlers by few different request headers, including `User-Agent`
71
+ * Project Honeypot's
72
+ [http:BL](https://www.projecthoneypot.org/httpbl_api.php) can not only
73
+ classify IP as a search engine, but also label them as suspicious and
74
+ reports the number of days since the last activity. My implementation of
75
+ the protocol in Scala is [here](https://github.com/osinka/httpbl).
@@ -14,13 +14,13 @@ Gem::Specification.new do |spec|
14
14
  spec.summary = 'Validate requests from Web crawlers: impersonating or not?'
15
15
  spec.description = 'Does Web request come from a real search engine or from an impersonating agent?'
16
16
 
17
- spec.required_ruby_version = '>= 2.3.0'
17
+ spec.required_ruby_version = '>= 2.4.0'
18
18
  spec.add_dependency 'augmented_interval_tree', '~> 0.1', '>= 0.1.1'
19
19
  spec.add_dependency 'irrc', '~> 0.2', '>= 0.2.1'
20
20
  spec.add_development_dependency 'bump', '~> 0.8', '>= 0.8.0'
21
21
  spec.add_development_dependency 'minitest', '~> 5.1', '>= 5.1.0'
22
22
  spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.0'
23
- spec.add_development_dependency 'rubocop', '~> 0.74', '>= 0.74.0'
23
+ spec.add_development_dependency 'rubocop', '~> 0.90', '< 0.91'
24
24
 
25
25
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
26
26
  spec.rdoc_options = ['--charset=UTF-8']
@@ -4,6 +4,7 @@ require_relative 'legitbot/legitbot'
4
4
  require_relative 'legitbot/botmatch'
5
5
 
6
6
  require_relative 'legitbot/ahrefs'
7
+ require_relative 'legitbot/alexa'
7
8
  require_relative 'legitbot/apple'
8
9
  require_relative 'legitbot/baidu'
9
10
  require_relative 'legitbot/bing'
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legitbot # :nodoc:
4
+ # https://support.alexa.com/hc/en-us/articles/360046707834-What-are-the-IP-addresses-for-Alexa-s-Certify-and-Site-Audit-crawlers-
5
+ # https://support.alexa.com/hc/en-us/articles/200462340
6
+ # https://support.alexa.com/hc/en-us/articles/200450194
7
+ class Alexa < BotMatch
8
+ ip_ranges %w[
9
+ 52.86.176.3
10
+ 52.4.48.181
11
+ 52.2.182.169
12
+ 52.86.185.29
13
+ ]
14
+ end
15
+
16
+ rule Legitbot::Alexa, %w[Alexabot ia_archiver]
17
+ end
@@ -4,6 +4,8 @@ module Legitbot # :nodoc:
4
4
  # https://duckduckgo.com/duckduckbot
5
5
  class DuckDuckGo < BotMatch
6
6
  ip_ranges %w[
7
+ 23.21.227.69
8
+ 40.88.21.235
7
9
  50.16.241.113
8
10
  50.16.241.114
9
11
  50.16.241.117
@@ -12,7 +14,8 @@ module Legitbot # :nodoc:
12
14
  52.5.190.19
13
15
  54.197.234.188
14
16
  54.208.100.253
15
- 23.21.227.69
17
+ 54.208.102.37
18
+ 107.21.1.8
16
19
  ]
17
20
  end
18
21
 
@@ -18,6 +18,7 @@ module Legitbot
18
18
  # otherwise.
19
19
  # :yields: a found bot
20
20
  #
21
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
21
22
  def self.bot(user_agent, ip)
22
23
  bots = @rules
23
24
  .select { |rule| rule[:fragments].any? { |f| user_agent.index f } }
@@ -32,6 +33,7 @@ module Legitbot
32
33
  selected
33
34
  end
34
35
  end
36
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
35
37
 
36
38
  def self.rule(clazz, fragments)
37
39
  @rules << { class: clazz, fragments: fragments }
@@ -59,22 +59,26 @@ module Legitbot
59
59
  partition_ips(@ip_ranges_loader.call)
60
60
  end
61
61
 
62
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
63
62
  def partition_ips(ips)
64
- return [] if ips.empty?
63
+ return [] unless ips&.any?
65
64
 
66
65
  ips
67
66
  .map { |cidr| IPAddr.new(cidr) }
68
67
  .partition(&:ipv4?)
69
68
  .each_with_index
70
69
  .map do |list, index|
71
- ranges = list.map(&:to_range).map do |r|
72
- (r.begin.to_i..r.end.to_i)
73
- end
74
- [FAMILIES[index], IntervalTree::Tree.new(ranges)]
70
+ [FAMILIES[index], build_interval_tree(list)]
75
71
  end.to_h
76
72
  end
77
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
73
+
74
+ private
75
+
76
+ def build_interval_tree(list)
77
+ ranges = list.map(&:to_range).map do |r|
78
+ (r.begin.to_i..r.end.to_i)
79
+ end
80
+ IntervalTree::Tree.new(ranges)
81
+ end
78
82
  end
79
83
  end
80
84
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Legitbot
4
- VERSION = '0.4.2'
4
+ VERSION = '1.1.0'
5
5
  end
@@ -7,27 +7,40 @@ module Legitbot # :nodoc:
7
7
  end
8
8
 
9
9
  rule Legitbot::Yandex, %w[
10
- YandexBot
11
10
  YandexAccessibilityBot
12
- YandexMobileBot
13
- YandexDirectDyn
14
- YandexScreenshotBot
15
- YandexImages
16
- YandexVideo
17
- YandexVideoParser
18
- YandexMedia
11
+ YandexAdNet
19
12
  YandexBlogs
13
+ YandexBot/
14
+ YandexCalendar
15
+ YandexDirect/
16
+ YandexDirectDyn
20
17
  YandexFavicons
21
- YandexWebmaster
22
- YandexPagechecker
23
- YandexImageResizer
24
18
  YaDirectFetcher
25
- YandexCalendar
26
- YandexSitelinks
19
+ YandexForDomain
20
+ YandexImages
21
+ YandexImageResizer
22
+ YandexMobileBot
23
+ YandexMarket
24
+ YandexMedia
27
25
  YandexMetrika
26
+ YandexMobileScreenShotBot
28
27
  YandexNews
29
- YandexVertis
28
+ YandexOntoDB
29
+ YandexOntoDBAPI
30
+ YandexPagechecker
31
+ YandexPartner
32
+ YandexRCA
30
33
  YandexSearchShop
34
+ YandexSitelinks
35
+ YandexSpravBot
36
+ YandexTracker
37
+ YandexTurbo
38
+ YandexVertis
31
39
  YandexVerticals
40
+ YandexVideo
41
+ YandexVideoParser
42
+ YandexWebmaster
43
+ YandexScreenshotBot
44
+ YandexMedianaBot
32
45
  ]
33
46
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require 'legitbot'
5
+
6
+ class AlexaTest < Minitest::Test
7
+ def test_malicious_ip
8
+ ip = '149.210.164.47'
9
+ match = Legitbot::Alexa.new ip
10
+ assert !match.valid?, msg: "#{ip} is not a real Alexa IP"
11
+ end
12
+
13
+ def test_valid_ip
14
+ ip = '52.86.176.3'
15
+ match = Legitbot::Alexa.new ip
16
+ assert match.valid?, msg: "#{ip} is a valid Alexa IP"
17
+ end
18
+
19
+ def test_malicious_ua
20
+ bot = Legitbot.bot(
21
+ 'Mozilla/5.0 (compatible; Alexabot/1.0; +http://www.alexa.com/help/certifyscan; certifyscan@alexa.com)',
22
+ '149.210.164.47'
23
+ )
24
+ assert bot, msg: 'Alexa detected from User-Agent'
25
+ assert !bot.valid?, msg: 'Not a valid Alexa'
26
+ end
27
+
28
+ def test_valid_ua
29
+ bot = Legitbot.bot(
30
+ 'Mozilla/5.0 (compatible; Alexabot/1.0; +http://www.alexa.com/help/certifyscan; certifyscan@alexa.com)',
31
+ '52.86.176.3'
32
+ )
33
+ assert bot, msg: 'Alexa detected from User-Agent'
34
+ assert bot.valid?, msg: 'Valid Alexa'
35
+ end
36
+ end
@@ -16,7 +16,7 @@ class AppleTest < Minitest::Test
16
16
  assert match.fake?, msg: "#{ip} is a fake Applebot IP"
17
17
  end
18
18
 
19
- # rubocop:disable Metrics/LineLength
19
+ # rubocop:disable Layout/LineLength
20
20
  def test_user_agent
21
21
  bot = Legitbot.bot(
22
22
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Applebot/0.1; +http://www.apple.com/go/applebot)',
@@ -25,5 +25,5 @@ class AppleTest < Minitest::Test
25
25
  assert_equal :apple, bot.detected_as
26
26
  assert bot.valid?, msg: 'A valid Applebot User-agent and IP'
27
27
  end
28
- # rubocop:enable Metrics/LineLength
28
+ # rubocop:enable Layout/LineLength
29
29
  end
@@ -5,14 +5,14 @@ require 'legitbot'
5
5
 
6
6
  module Legitbot
7
7
  class Facebook
8
- # rubocop:disable Metrics/LineLength
8
+ # rubocop:disable Layout/LineLength
9
9
  def self.whois
10
10
  {
11
11
  ipv4: ['69.63.176.0/20', '66.220.144.0/20', '66.220.144.0/21', '69.63.184.0/21', '69.63.176.0/21', '74.119.76.0/22', '69.171.255.0/24', '173.252.64.0/18', '69.171.224.0/19', '69.171.224.0/20', '103.4.96.0/22', '69.63.176.0/24', '173.252.64.0/19', '173.252.70.0/24', '31.13.64.0/18', '31.13.24.0/21', '66.220.152.0/21', '66.220.159.0/24', '69.171.239.0/24', '69.171.240.0/20', '31.13.64.0/19', '31.13.64.0/24', '31.13.65.0/24', '31.13.67.0/24', '31.13.68.0/24', '31.13.69.0/24', '31.13.70.0/24', '31.13.71.0/24', '31.13.72.0/24', '31.13.73.0/24', '31.13.74.0/24', '31.13.75.0/24', '31.13.76.0/24', '31.13.77.0/24', '31.13.96.0/19', '31.13.66.0/24', '173.252.96.0/19', '69.63.178.0/24', '31.13.78.0/24', '31.13.79.0/24', '31.13.80.0/24', '31.13.82.0/24', '31.13.83.0/24', '31.13.84.0/24', '31.13.85.0/24', '31.13.86.0/24', '31.13.87.0/24', '31.13.88.0/24', '31.13.89.0/24', '31.13.90.0/24', '31.13.91.0/24', '31.13.92.0/24', '31.13.93.0/24', '31.13.94.0/24', '31.13.95.0/24', '69.171.253.0/24', '69.63.186.0/24', '31.13.81.0/24', '179.60.192.0/22', '179.60.192.0/24', '179.60.193.0/24', '179.60.194.0/24', '179.60.195.0/24', '185.60.216.0/22', '45.64.40.0/22', '185.60.216.0/24', '185.60.217.0/24', '185.60.218.0/24', '185.60.219.0/24', '129.134.0.0/16', '157.240.0.0/16', '157.240.8.0/24', '157.240.0.0/24', '157.240.1.0/24', '157.240.2.0/24', '157.240.3.0/24', '157.240.4.0/24', '157.240.5.0/24', '157.240.6.0/24', '157.240.7.0/24', '157.240.9.0/24', '157.240.10.0/24', '157.240.16.0/24', '157.240.19.0/24', '157.240.11.0/24', '157.240.12.0/24', '157.240.13.0/24', '157.240.14.0/24', '157.240.15.0/24', '157.240.17.0/24', '157.240.18.0/24', '157.240.20.0/24', '157.240.21.0/24', '157.240.22.0/24', '157.240.23.0/24', '157.240.0.0/17', '69.171.250.0/24', '157.240.24.0/24', '157.240.25.0/24', '199.201.64.0/24', '199.201.65.0/24', '199.201.64.0/22', '204.15.20.0/22', '157.240.192.0/24', '129.134.0.0/17', '157.240.198.0/24'],
12
12
  ipv6: []
13
13
  }
14
14
  end
15
- # rubocop:enable Metrics/LineLength
15
+ # rubocop:enable Layout/LineLength
16
16
  end
17
17
  end
18
18
 
@@ -33,7 +33,7 @@ class FacebookTest < Minitest::Test
33
33
  assert match.fake?, msg: "#{ip} is a fake Facebook IP"
34
34
  end
35
35
 
36
- # rubocop:disable Metrics/LineLength, Metrics/MethodLength
36
+ # rubocop:disable Layout/LineLength, Metrics/MethodLength
37
37
  def test_user_agent
38
38
  Legitbot.bot(
39
39
  'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
@@ -59,5 +59,5 @@ class FacebookTest < Minitest::Test
59
59
  assert bot.fake?, msg: 'fake Facebook'
60
60
  end
61
61
  end
62
- # rubocop:enable Metrics/LineLength, Metrics/MethodLength
62
+ # rubocop:enable Layout/LineLength, Metrics/MethodLength
63
63
  end
@@ -46,6 +46,11 @@ module Legitbot
46
46
  end
47
47
  end
48
48
 
49
+ class NilRanges
50
+ include IpRanges
51
+ ip_ranges { nil }
52
+ end
53
+
49
54
  class IpRangesTest < Minitest::Test
50
55
  def test_partition_method
51
56
  empty = NoRanges.partition_ips([])
@@ -108,6 +113,10 @@ module Legitbot
108
113
  assert_equal 2, LoadRanges.counter
109
114
  end
110
115
  # rubocop:enable Metrics/AbcSize
116
+
117
+ def test_nil_ranges
118
+ assert NilRanges.valid_ip?('127.0.0.1')
119
+ end
111
120
  end
112
121
  end
113
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legitbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Azarov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2020-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: augmented_interval_tree
@@ -54,82 +54,82 @@ dependencies:
54
54
  name: bump
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- version: 0.8.0
60
57
  - - "~>"
61
58
  - !ruby/object:Gem::Version
62
59
  version: '0.8'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.8.0
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: 0.8.0
70
67
  - - "~>"
71
68
  - !ruby/object:Gem::Version
72
69
  version: '0.8'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.8.0
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: minitest
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
79
- version: 5.1.0
80
77
  - - "~>"
81
78
  - !ruby/object:Gem::Version
82
79
  version: '5.1'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 5.1.0
83
83
  type: :development
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: 5.1.0
90
87
  - - "~>"
91
88
  - !ruby/object:Gem::Version
92
89
  version: '5.1'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 5.1.0
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: rake
95
95
  requirement: !ruby/object:Gem::Requirement
96
96
  requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- version: 12.3.0
100
97
  - - "~>"
101
98
  - !ruby/object:Gem::Version
102
99
  version: '12.3'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 12.3.0
103
103
  type: :development
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: 12.3.0
110
107
  - - "~>"
111
108
  - !ruby/object:Gem::Version
112
109
  version: '12.3'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 12.3.0
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rubocop
115
115
  requirement: !ruby/object:Gem::Requirement
116
116
  requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- version: 0.74.0
120
117
  - - "~>"
121
118
  - !ruby/object:Gem::Version
122
- version: '0.74'
119
+ version: '0.90'
120
+ - - "<"
121
+ - !ruby/object:Gem::Version
122
+ version: '0.91'
123
123
  type: :development
124
124
  prerelease: false
125
125
  version_requirements: !ruby/object:Gem::Requirement
126
126
  requirements:
127
- - - ">="
128
- - !ruby/object:Gem::Version
129
- version: 0.74.0
130
127
  - - "~>"
131
128
  - !ruby/object:Gem::Version
132
- version: '0.74'
129
+ version: '0.90'
130
+ - - "<"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.91'
133
133
  description: Does Web request come from a real search engine or from an impersonating
134
134
  agent?
135
135
  email: self@alaz.me
@@ -137,9 +137,11 @@ executables: []
137
137
  extensions: []
138
138
  extra_rdoc_files: []
139
139
  files:
140
+ - ".editorconfig"
141
+ - ".github/workflows/build.yml"
140
142
  - ".gitignore"
141
143
  - ".rubocop.yml"
142
- - ".travis.yml"
144
+ - ".ruby-version"
143
145
  - Gemfile
144
146
  - LICENSE.txt
145
147
  - README.md
@@ -147,6 +149,7 @@ files:
147
149
  - legitbot.gemspec
148
150
  - lib/legitbot.rb
149
151
  - lib/legitbot/ahrefs.rb
152
+ - lib/legitbot/alexa.rb
150
153
  - lib/legitbot/apple.rb
151
154
  - lib/legitbot/baidu.rb
152
155
  - lib/legitbot/bing.rb
@@ -164,6 +167,7 @@ files:
164
167
  - lib/legitbot/version.rb
165
168
  - lib/legitbot/yandex.rb
166
169
  - test/ahrefs_test.rb
170
+ - test/alexa_test.rb
167
171
  - test/apple_as_google_test.rb
168
172
  - test/apple_test.rb
169
173
  - test/botmatch_test.rb
@@ -179,7 +183,7 @@ homepage: https://github.com/alaz/legitbot
179
183
  licenses:
180
184
  - Apache-2.0
181
185
  metadata: {}
182
- post_install_message:
186
+ post_install_message:
183
187
  rdoc_options:
184
188
  - "--charset=UTF-8"
185
189
  require_paths:
@@ -188,15 +192,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
188
192
  requirements:
189
193
  - - ">="
190
194
  - !ruby/object:Gem::Version
191
- version: 2.3.0
195
+ version: 2.4.0
192
196
  required_rubygems_version: !ruby/object:Gem::Requirement
193
197
  requirements:
194
198
  - - ">="
195
199
  - !ruby/object:Gem::Version
196
200
  version: '0'
197
201
  requirements: []
198
- rubygems_version: 3.0.6
199
- signing_key:
202
+ rubygems_version: 3.1.2
203
+ signing_key:
200
204
  specification_version: 4
201
205
  summary: 'Validate requests from Web crawlers: impersonating or not?'
202
206
  test_files:
@@ -204,6 +208,7 @@ test_files:
204
208
  - test/legitbot/validators/domains_test.rb
205
209
  - test/legitbot/validators/ip_ranges_test.rb
206
210
  - test/pinterest_test.rb
211
+ - test/alexa_test.rb
207
212
  - test/ahrefs_test.rb
208
213
  - test/apple_test.rb
209
214
  - test/apple_as_google_test.rb
@@ -1,12 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.5
6
- - 2.3
7
- - jruby-head
8
- jdk:
9
- - openjdk8
10
- before_install:
11
- - gem update --system
12
- - gem install bundler