site-inspector 1.0.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +8 -0
  3. data/.rubocop.yml +42 -0
  4. data/.rubocop_todo.yml +139 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +9 -0
  7. data/Gemfile +7 -0
  8. data/Guardfile +10 -0
  9. data/README.md +189 -0
  10. data/Rakefile +10 -0
  11. data/bin/site-inspector +50 -22
  12. data/lib/cliver/dependency_ext.rb +24 -0
  13. data/lib/site-inspector.rb +62 -615
  14. data/lib/site-inspector/cache.rb +10 -51
  15. data/lib/site-inspector/checks/accessibility.rb +135 -0
  16. data/lib/site-inspector/checks/check.rb +54 -0
  17. data/lib/site-inspector/checks/content.rb +85 -0
  18. data/lib/site-inspector/checks/cookies.rb +45 -0
  19. data/lib/site-inspector/checks/dns.rb +138 -0
  20. data/lib/site-inspector/checks/headers.rb +68 -0
  21. data/lib/site-inspector/checks/hsts.rb +81 -0
  22. data/lib/site-inspector/checks/https.rb +40 -0
  23. data/lib/site-inspector/checks/sniffer.rb +67 -0
  24. data/lib/site-inspector/checks/wappalyzer.rb +62 -0
  25. data/lib/site-inspector/checks/whois.rb +36 -0
  26. data/lib/site-inspector/disk_cache.rb +42 -0
  27. data/lib/site-inspector/domain.rb +271 -0
  28. data/lib/site-inspector/endpoint.rb +217 -0
  29. data/lib/site-inspector/rails_cache.rb +13 -0
  30. data/lib/site-inspector/version.rb +5 -0
  31. data/package-lock.json +505 -0
  32. data/package.json +23 -0
  33. data/script/bootstrap +2 -0
  34. data/script/cibuild +11 -0
  35. data/script/console +3 -0
  36. data/script/pa11y-version +10 -0
  37. data/script/release +38 -0
  38. data/site-inspector.gemspec +42 -0
  39. data/spec/checks/site_inspector_endpoint_accessibility_spec.rb +84 -0
  40. data/spec/checks/site_inspector_endpoint_check_spec.rb +42 -0
  41. data/spec/checks/site_inspector_endpoint_content_spec.rb +117 -0
  42. data/spec/checks/site_inspector_endpoint_cookies_spec.rb +73 -0
  43. data/spec/checks/site_inspector_endpoint_dns_spec.rb +184 -0
  44. data/spec/checks/site_inspector_endpoint_headers_spec.rb +65 -0
  45. data/spec/checks/site_inspector_endpoint_hsts_spec.rb +92 -0
  46. data/spec/checks/site_inspector_endpoint_https_spec.rb +49 -0
  47. data/spec/checks/site_inspector_endpoint_sniffer_spec.rb +150 -0
  48. data/spec/checks/site_inspector_endpoint_wappalyzer_spec.rb +34 -0
  49. data/spec/checks/site_inspector_endpoint_whois_spec.rb +26 -0
  50. data/spec/fixtures/wappalyzer.json +125 -0
  51. data/spec/site_inspector_cache_spec.rb +15 -0
  52. data/spec/site_inspector_disk_cache_spec.rb +39 -0
  53. data/spec/site_inspector_domain_spec.rb +271 -0
  54. data/spec/site_inspector_endpoint_spec.rb +252 -0
  55. data/spec/site_inspector_spec.rb +48 -0
  56. data/spec/spec_helper.rb +19 -0
  57. metadata +204 -63
  58. data/lib/site-inspector/compliance.rb +0 -19
  59. data/lib/site-inspector/dns.rb +0 -92
  60. data/lib/site-inspector/headers.rb +0 -59
  61. data/lib/site-inspector/sniffer.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e4e41e2a1639e9f5f6e7f018ef58c664c834b2c2
4
- data.tar.gz: 3205114fcaaaa11cf03ec1eb8fa2f5736b6a99f7
2
+ SHA256:
3
+ metadata.gz: 9da6e03626519a29904ac4f663565104f6793e9fedae46f786f268ea7beaf870
4
+ data.tar.gz: 100c9e6f24fd2f5ded3cc7239d37f30852eb7c7cd4a0c69651fc1d260c0043c6
5
5
  SHA512:
6
- metadata.gz: ffa69fcc3949abe434a476bf8bff0c65dbd4085b5c40f379c0f7b3bbb9eaf43ffc41527ea571fe211ac71d3911b58deaebf8446ee96a69d8a279c2877e87e3bb
7
- data.tar.gz: b369d00e140c4b258b02f02e5b841f4ce26d84c0b7b32f10e6015a99673355b3a505194495fbf2bf5e9ecfabfed6e486db18572a56418bcfaf329b6acb746778
6
+ metadata.gz: 974095f3bc91b3a83c90ef9fa9879942e66e3a4927b0e1d83a0cba2727c9f7e301ab151a3f0bac1ff507d3a16549c64af4be23fdd245ede0ac0dc25401096ba2
7
+ data.tar.gz: 16378f1054392ef3aa472469860367bab3c4d276bd57eaec9131382109aa85218ad535d82477d215d7c0294f310e82eac987275fd1b7d5148c5d3a1e722c8ab5
@@ -0,0 +1,8 @@
1
+ .bundle
2
+ /*.gem
3
+ vendor
4
+ Gemfile.lock
5
+ /.env
6
+ /tmp
7
+ /cache
8
+ node_modules
@@ -0,0 +1,42 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-performance
5
+ - rubocop-rspec
6
+
7
+ AllCops:
8
+ NewCops: enable
9
+
10
+ Layout/LineLength:
11
+ Enabled: false
12
+
13
+ Metrics/MethodLength:
14
+ Enabled: false
15
+
16
+ Metrics/AbcSize:
17
+ Enabled: false
18
+
19
+ Style/Documentation:
20
+ Enabled: false
21
+
22
+ Naming/FileName:
23
+ Enabled: false
24
+
25
+ Metrics/CyclomaticComplexity:
26
+ Enabled: false
27
+
28
+ Style/DoubleNegation:
29
+ Enabled: false
30
+
31
+ Metrics/ClassLength:
32
+ Enabled: false
33
+
34
+ Style/ClassVars:
35
+ Enabled: false
36
+
37
+ Metrics/BlockLength:
38
+ Enabled: false
39
+
40
+ Security/MarshalLoad:
41
+ Exclude:
42
+ - lib/site-inspector/disk_cache.rb
@@ -0,0 +1,139 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-11-13 02:59:59 UTC using RuboCop version 1.3.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'site-inspector.gemspec'
15
+
16
+ # Offense count: 3
17
+ # Configuration parameters: AllowComments, AllowEmptyLambdas.
18
+ Lint/EmptyBlock:
19
+ Exclude:
20
+ - 'spec/site_inspector_domain_spec.rb'
21
+
22
+ # Offense count: 1
23
+ Lint/NoReturnInBeginEndBlocks:
24
+ Exclude:
25
+ - 'lib/site-inspector/endpoint.rb'
26
+
27
+ # Offense count: 2
28
+ # Configuration parameters: IgnoredMethods.
29
+ Metrics/PerceivedComplexity:
30
+ Max: 9
31
+
32
+ # Offense count: 3
33
+ # Configuration parameters: EnforcedStyleForLeadingUnderscores.
34
+ # SupportedStylesForLeadingUnderscores: disallowed, required, optional
35
+ Naming/MemoizedInstanceVariableName:
36
+ Exclude:
37
+ - 'lib/site-inspector/checks/accessibility.rb'
38
+
39
+ # Offense count: 23
40
+ # Configuration parameters: Prefixes.
41
+ # Prefixes: when, with, without
42
+ RSpec/ContextWording:
43
+ Exclude:
44
+ - 'spec/checks/site_inspector_endpoint_content_spec.rb'
45
+ - 'spec/checks/site_inspector_endpoint_dns_spec.rb'
46
+ - 'spec/checks/site_inspector_endpoint_sniffer_spec.rb'
47
+ - 'spec/site_inspector_domain_spec.rb'
48
+ - 'spec/site_inspector_endpoint_spec.rb'
49
+
50
+ # Offense count: 1
51
+ RSpec/EmptyExampleGroup:
52
+ Exclude:
53
+ - 'spec/checks/site_inspector_endpoint_accessibility_spec.rb'
54
+
55
+ # Offense count: 24
56
+ # Configuration parameters: Max.
57
+ RSpec/ExampleLength:
58
+ Exclude:
59
+ - 'spec/checks/site_inspector_endpoint_dns_spec.rb'
60
+ - 'spec/checks/site_inspector_endpoint_hsts_spec.rb'
61
+ - 'spec/checks/site_inspector_endpoint_https_spec.rb'
62
+ - 'spec/checks/site_inspector_endpoint_sniffer_spec.rb'
63
+ - 'spec/checks/site_inspector_endpoint_wappalyzer_spec.rb'
64
+ - 'spec/site_inspector_disk_cache_spec.rb'
65
+ - 'spec/site_inspector_domain_spec.rb'
66
+ - 'spec/site_inspector_endpoint_spec.rb'
67
+ - 'spec/site_inspector_spec.rb'
68
+
69
+ # Offense count: 15
70
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
71
+ # Include: **/*_spec*rb*, **/spec/**/*
72
+ RSpec/FilePath:
73
+ Exclude:
74
+ - 'spec/checks/site_inspector_endpoint_accessibility_spec.rb'
75
+ - 'spec/checks/site_inspector_endpoint_check_spec.rb'
76
+ - 'spec/checks/site_inspector_endpoint_content_spec.rb'
77
+ - 'spec/checks/site_inspector_endpoint_cookies_spec.rb'
78
+ - 'spec/checks/site_inspector_endpoint_dns_spec.rb'
79
+ - 'spec/checks/site_inspector_endpoint_headers_spec.rb'
80
+ - 'spec/checks/site_inspector_endpoint_hsts_spec.rb'
81
+ - 'spec/checks/site_inspector_endpoint_https_spec.rb'
82
+ - 'spec/checks/site_inspector_endpoint_sniffer_spec.rb'
83
+ - 'spec/checks/site_inspector_endpoint_wappalyzer_spec.rb'
84
+ - 'spec/checks/site_inspector_endpoint_whois_spec.rb'
85
+ - 'spec/site_inspector_cache_spec.rb'
86
+ - 'spec/site_inspector_disk_cache_spec.rb'
87
+ - 'spec/site_inspector_domain_spec.rb'
88
+ - 'spec/site_inspector_endpoint_spec.rb'
89
+
90
+ # Offense count: 55
91
+ RSpec/MultipleExpectations:
92
+ Max: 5
93
+
94
+ # Offense count: 240
95
+ # Configuration parameters: IgnoreSharedExamples.
96
+ RSpec/NamedSubject:
97
+ Exclude:
98
+ - 'spec/checks/site_inspector_endpoint_accessibility_spec.rb'
99
+ - 'spec/checks/site_inspector_endpoint_check_spec.rb'
100
+ - 'spec/checks/site_inspector_endpoint_content_spec.rb'
101
+ - 'spec/checks/site_inspector_endpoint_cookies_spec.rb'
102
+ - 'spec/checks/site_inspector_endpoint_dns_spec.rb'
103
+ - 'spec/checks/site_inspector_endpoint_headers_spec.rb'
104
+ - 'spec/checks/site_inspector_endpoint_hsts_spec.rb'
105
+ - 'spec/checks/site_inspector_endpoint_https_spec.rb'
106
+ - 'spec/checks/site_inspector_endpoint_sniffer_spec.rb'
107
+ - 'spec/checks/site_inspector_endpoint_wappalyzer_spec.rb'
108
+ - 'spec/checks/site_inspector_endpoint_whois_spec.rb'
109
+ - 'spec/site_inspector_cache_spec.rb'
110
+ - 'spec/site_inspector_disk_cache_spec.rb'
111
+ - 'spec/site_inspector_domain_spec.rb'
112
+ - 'spec/site_inspector_endpoint_spec.rb'
113
+
114
+ # Offense count: 2
115
+ RSpec/RepeatedDescription:
116
+ Exclude:
117
+ - 'spec/checks/site_inspector_endpoint_content_spec.rb'
118
+
119
+ # Offense count: 9
120
+ RSpec/RepeatedExample:
121
+ Exclude:
122
+ - 'spec/checks/site_inspector_endpoint_accessibility_spec.rb'
123
+ - 'spec/checks/site_inspector_endpoint_content_spec.rb'
124
+ - 'spec/site_inspector_domain_spec.rb'
125
+
126
+ # Offense count: 2
127
+ RSpec/RepeatedExampleGroupDescription:
128
+ Exclude:
129
+ - 'spec/site_inspector_domain_spec.rb'
130
+
131
+ # Offense count: 30
132
+ RSpec/SubjectStub:
133
+ Exclude:
134
+ - 'spec/checks/site_inspector_endpoint_accessibility_spec.rb'
135
+ - 'spec/checks/site_inspector_endpoint_dns_spec.rb'
136
+ - 'spec/checks/site_inspector_endpoint_headers_spec.rb'
137
+ - 'spec/checks/site_inspector_endpoint_hsts_spec.rb'
138
+ - 'spec/checks/site_inspector_endpoint_https_spec.rb'
139
+ - 'spec/site_inspector_endpoint_spec.rb'
@@ -0,0 +1 @@
1
+ 2.6.6
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ script: "script/cibuild"
5
+ sudo: false
6
+ cache:
7
+ - bundler
8
+ - node_modules
9
+ before_script: npm install
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'sniffles', github: 'wa0x6e/sniffles'
6
+
7
+ gemspec
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A sample Guardfile
4
+ # More info at https://github.com/guard/guard#readme
5
+
6
+ guard 'rake', task: 'test' do
7
+ watch(%r{^test/.+$})
8
+ watch(%r{^lib/.+$})
9
+ watch(%r{^views/.+$})
10
+ end
@@ -0,0 +1,189 @@
1
+ # Site Inspector
2
+
3
+ A Ruby Gem to sniff information about a domain's technology and capabilities.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/site-inspector.svg)](http://badge.fury.io/rb/site-inspector) [![Build Status](https://travis-ci.org/benbalter/site-inspector.svg)](https://travis-ci.org/benbalter/site-inspector)
6
+
7
+ ## Demo
8
+
9
+ [site-inspector.herokuapp.com](https://site-inspector.herokuapp.com) ([source](https://github.com/benbalter/site-inspector-demo))
10
+
11
+ ## Concepts
12
+
13
+ Site Inspector involves three primary concepts:
14
+
15
+ * **Domain** - A domain has a host defined by it's TLD + SLD. A domain might be `example.com`. Domain's have certain domain-wide properties like whether it supports non-www requests, or if it enforces HTTPS.
16
+
17
+ * **Endpoint** - Each domain has four endpoints based on whether you make your request with HTTPS or not, and whether you prefix the host with `www.` or not. So the domain `example.com` may have endpoints at `https://example.com`, `https://www.example.com`, `http://example.com`, and `https://www.example.com`. There may theoretically be a different server responding to each endpoint, so endpoints have certain endpoint-specific properties, like whether it responds or not, or whether it redirects. Each domain has one canonical (primary) endpoint.
18
+
19
+ * **Checks** - A check is a set of tests performed on an endpoint. A check might look at what headers are returned, what CMS is used, or whether there is a valid HTTPS certificate. There are some built in checks, listed below, or you can define your own. While they're endpoint specific, checks often filter up and inform some of the domain-wide logic (such as if the domain supports HTTPS).
20
+
21
+ ## Usage
22
+
23
+ ### Ruby
24
+
25
+ ```ruby
26
+ domain = SiteInspector.inspect "whitehouse.gov"
27
+ domain.https?
28
+ # => true
29
+ domain.www?
30
+ # => true
31
+ domain.canonical_endpoint.to_s
32
+ # => "https://www.whitehouse.gov"
33
+ domain.canonical_endpoint.sniffer.cms
34
+ # => { :drupal => {}}
35
+ ```
36
+
37
+ ### Command line usage
38
+
39
+ ```
40
+ site-inspector inspect -- inspects a domain
41
+
42
+ Usage:
43
+
44
+ site-inspector inspect <domain> [options]
45
+
46
+ Options:
47
+ -j, --json JSON encode the output
48
+ -a, --all return results for all endpoints (defaults to only the canonical endpoint)
49
+ --sniffer return results for the sniffer check (defaults to all checks unless one or more checks are specified)
50
+ --https return results for the https check (defaults to all checks unless one or more checks are specified)
51
+ --hsts return results for the hsts check (defaults to all checks unless one or more checks are specified)
52
+ --headers return results for the headers check (defaults to all checks unless one or more checks are specified)
53
+ --dns return results for the dns check (defaults to all checks unless one or more checks are specified)
54
+ --content return results for the content check (defaults to all checks unless one or more checks are specified)
55
+ -h, --help Show this message
56
+ -v, --version Print the name and version
57
+ -t, --trace Show the full backtrace when an error occurs
58
+ ```
59
+
60
+ ## What's checked
61
+
62
+ ### Domain
63
+
64
+ * `canonical_endpoint` - The domain's primary endpoint
65
+ * `government` - whether the domain is a government domain
66
+ * `up` - whether any endpoint responds
67
+ * `www` - whether either `www` endpoint responds
68
+ * `root` - whether you can access the domain with `www.`
69
+ * `https` - whether HTTPS is supported
70
+ * `enforces_https` - whether non-htttps endpoints are either down or redirects to https
71
+ * `downgrades_https` - whether the canonical endpoint redirects to an http endpoint
72
+ * `canonically_www` - whether non-www requests are redirected to www (or all non-www endpoints are down)
73
+ * `canonically_https` - whether non-https request are redirected to https (or all http endpoints are down)
74
+ * `redirect` - whether the domain redirects to an external domain
75
+ * `hsts` - does the canonical endpoint have HSTS enabled
76
+ * `hsts_subdomains` - are subdomains included in the HSTS list?
77
+ * `hsts_preload_ready` - can this domain be added to the HSTS preload list?
78
+
79
+ ### Endpoint
80
+
81
+ * `up` - whether the endpoint responds or not
82
+ * `timed_out` - whether the endpoint times out
83
+ * `redirect` - whether the endpoint redirects
84
+ * `external_redirect` - whether the endpoint redirects to another domain
85
+
86
+ ### Checks
87
+
88
+ Each endpoint also returns the following checks:
89
+
90
+ #### Accessibility
91
+
92
+ Uses the `pa11y` CLI to run automated accessibility tests. Requires `node`. To install `pally`: `[sudo] npm install -g pa11y`.
93
+
94
+ * `section508` - Tests against the Section508 standard
95
+ * `wcag2a` - Tests against the WCAG2A standard
96
+ * `wcag2aa` - Tests against the WCAG2AA standard
97
+ * `wcag2aaa` - Tests against the WCAG2AAA standard
98
+
99
+ #### Content
100
+
101
+ * `doctype` - The HTML doctype returned
102
+ * `sitemap_xml` - Whether the endpoint has a sitemap
103
+ * `robots_txt` - whether the endpoint has a `robots.txt` file
104
+
105
+ #### DNS
106
+
107
+ * `dnssec` - is DNSSEC supported
108
+ * `ipv6` - is IPV6 supported
109
+ * `cdn` - the endpoint's CDN, if any
110
+ * `cloud_provider` - the endpoint's cloud provider, if any
111
+ * `google_apps` - whether the domain is using google apps
112
+ * `hostname` - the server hostname
113
+ * `ip` - the server IP
114
+
115
+ #### Headers
116
+
117
+ * `cookies` - does the domain use cookies
118
+ * `strict_transport_security` - whether STS is enabled
119
+ * `content_security_policy` - the endpoint's CSP
120
+ * `click_jacking_protection` - whether an `x-frame-options` header is sent
121
+ * `xss_protection` - whether an `x-xss-protection` header is sent
122
+ * `server` - the server header
123
+ * `secure_cookies` - whether the cookies are secure, or not
124
+
125
+ #### HSTS
126
+
127
+ * `valid` - whether the HSTS header is valid
128
+ * `max_age` - the HSTS max age
129
+ * `include_subdomains` - whether subdomains are included
130
+ * `preload` - whether its preloaded
131
+ * `enabled` - whether HSTS is enabled
132
+ * `preload_ready` - whether HSTS could be preloaded
133
+
134
+ #### HTTPS
135
+
136
+ * `valid` - if the HTTPS response is valid
137
+ * `return_code` - the HTTPS error, if any
138
+
139
+ #### Sniffer
140
+
141
+ * `cms` - the CMS used, if any
142
+ * `analytics` - the analytics providers used, if any
143
+ * `javascript` - the javascript libraries used, if any
144
+ * `advertising` - the advertising providers used, if any
145
+
146
+ ## Adding your own check
147
+
148
+ [Checks](https://github.com/benbalter/site-inspector/tree/master/lib/site-inspector/checks) are special classes that are children of [`SiteInspector::Endpoint::Check`](https://github.com/benbalter/site-inspector/blob/master/lib/site-inspector/checks/check.rb). You can implement your own check like this:
149
+
150
+ ```ruby
151
+ class SiteInspector
152
+ class Endpoint
153
+ class Mention < Check
154
+ def mentions_ben?
155
+ endpoint.content.body =~ /ben/i
156
+ end
157
+ end
158
+ end
159
+ end
160
+ ```
161
+
162
+ This check can then be used as follows:
163
+ ```
164
+ domain.canonical_endpoint.mention.mentions_ben?
165
+ ```
166
+
167
+ Checks can call the `endpoint` object, which, contains the request, response, and other checks. Custom checks are automatically exposed as endpoint methods.
168
+
169
+ ## Contributing
170
+
171
+ ### Bootstrapping locally
172
+
173
+ 1. Clone down the repo
174
+ 2. `script/bootstrap`
175
+
176
+ ### Running tests
177
+
178
+ `script/cibuild`
179
+
180
+ ### Development console
181
+
182
+ `script/console`
183
+
184
+ ### How to contribute
185
+
186
+ 1. Fork the project
187
+ 2. Create a new, descriptively named feature branch
188
+ 3. Make your changes
189
+ 4. Submit a pull request
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/site-inspector'
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run specs'
7
+ RSpec::Core::RakeTask.new do |t|
8
+ t.pattern = 'spec/**/*_spec.rb'
9
+ t.rspec_opts = ['--order', 'rand', '--color']
10
+ end
@@ -1,29 +1,57 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require_relative "../lib/site-inspector"
4
+ require 'mercenary'
5
+ require 'oj'
6
+ require 'yaml'
7
+ require 'colorator'
8
+ require_relative '../lib/site-inspector'
4
9
 
5
- require "oj"
10
+ def stringify_keys_deep!(hash)
11
+ hash.each_key do |k|
12
+ ks = k.respond_to?(:to_s) ? k.to_s : k
13
+ hash[ks] = hash.delete k # Preserve order even when k == ks
14
+ stringify_keys_deep! h[ks] if hash[ks].is_a? Hash
15
+ end
16
+ end
6
17
 
7
- domain = ARGV[0]
8
- http_mode = (ARGV[1] == "--http")
18
+ Mercenary.program(:"site-inspector") do |p|
19
+ p.version SiteInspector::VERSION
20
+ p.description "Returns information about a domain's technology and capabilities"
21
+ p.syntax 'site-inspector <command> <domain> [options]'
9
22
 
10
- if domain.to_s.empty?
11
- puts "Usage: site-inspector [DOMAIN] [--http]"
12
- exit 1
13
- end
23
+ p.command(:inspect) do |c|
24
+ c.syntax 'inspect <domain> [options]'
25
+ c.description 'inspects a domain'
26
+ c.option 'json', '-j', '--json', 'JSON encode the output'
27
+ c.option 'all', '-a', '--all', 'return results for all endpoints (defaults to only the canonical endpoint)'
14
28
 
15
- # HTTP mode:
16
- # * all details for possible endpoints
17
- # * don't follow redirects
18
- # * shorter timeout
19
- if http_mode
20
- site = SiteInspector.new(domain)
21
- details = site.http
22
-
23
- # Normal mode: autodetect canonical domain, sweep every attribute.
24
- else
25
- site = SiteInspector.new(domain)
26
- details = site.to_hash
27
- end
29
+ SiteInspector::Endpoint.checks.each do |check|
30
+ c.option check.name, "--#{check.name}", "return results for the #{check.name} check (defaults to all checks unless one or more checks are specified)"
31
+ end
32
+
33
+ c.action do |args, options|
34
+ next c.logger.fatal 'Must specify a domain' if args.length != 1
35
+
36
+ # Build our domain hash as requested
37
+ domain = SiteInspector.inspect(args[0])
38
+ hash = domain.to_h(options)
39
+ json = Oj.dump(hash, indent: 2, mode: :compat)
28
40
 
29
- puts Oj.dump(details, indent: 2, mode: :compat)
41
+ # Dump the JSON and run
42
+ next puts json if options['json']
43
+
44
+ # This is a dirty, dirty hack, but it's a simple way to stringify keys recursively
45
+ # And format the output in a human-readable way
46
+ yaml = YAML.dump Oj.load(json)
47
+
48
+ # Colorize bools
49
+ yaml.gsub!(/: (true|ok)$/, ": #{'true'.green}")
50
+ yaml.gsub!(/: false$/, ": #{'false'.red}")
51
+
52
+ puts yaml
53
+ end
54
+ end
55
+
56
+ p.default_command(:inspect)
57
+ end