sonar-client 0.1.3 → 0.2.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 +5 -5
- data/.travis.yml +10 -2
- data/lib/sonar/cli/cli.rb +35 -19
- data/lib/sonar/client.rb +7 -6
- data/lib/sonar/search.rb +30 -15
- data/lib/sonar/version.rb +1 -1
- data/lib/sonar.rb +0 -1
- data/sonar-client.gemspec +7 -4
- data/spec/fixtures/sonar-stock.rc +1 -1
- data/spec/sonar/cli_spec.rb +21 -34
- data/spec/sonar/search_spec.rb +35 -127
- data/spec/sonar_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +76 -37
- data/spec/sonar/certificate_spec.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ce2404af83297d350bc601dc221e8e730421b0cbcb58eececceaa4bd276c0545
|
4
|
+
data.tar.gz: 5780f69f285064bdc1c1e987190835bc1eaef7c54386402ac022e82bc83a9c9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50368c89bc42beb8ef0c835eb66fe61516eb0404b8dce326661f8e8ab79f1a9ae8072820903d7e8bcecd46549a8f3057fa87934f546ebeb5d458b875acde257d
|
7
|
+
data.tar.gz: 4f1ed1482aeb61cf6646b58d786a56a8f8d770aaf074ffa94b6262cef8ada673361680c545e474dad10e09ad6815b1f41e8c46d39284c6a2d0ab17014b3d0bb1
|
data/.travis.yml
CHANGED
@@ -2,14 +2,22 @@ language: ruby
|
|
2
2
|
sudo: false
|
3
3
|
cache: bundler
|
4
4
|
rvm:
|
5
|
-
- 2.
|
6
|
-
-
|
5
|
+
- '2.4.5'
|
6
|
+
- '2.5.5'
|
7
|
+
- '2.6.5'
|
8
|
+
- '2.7.1'
|
9
|
+
- 'jruby-head'
|
7
10
|
before_install:
|
11
|
+
- gem install bundler
|
12
|
+
- gem update bundler
|
8
13
|
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
9
14
|
- rake --version
|
10
15
|
before_script:
|
11
16
|
- bundle exec rake --version
|
12
17
|
script: bundle exec rspec
|
18
|
+
notifications:
|
19
|
+
email:
|
20
|
+
- r7_labs@rapid7.com
|
13
21
|
#
|
14
22
|
# Environment variables should be set in Travis repository settings per
|
15
23
|
# https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings
|
data/lib/sonar/cli/cli.rb
CHANGED
@@ -2,11 +2,14 @@
|
|
2
2
|
|
3
3
|
require 'thor'
|
4
4
|
require 'sonar/cli/rcfile'
|
5
|
+
require 'sonar/search'
|
6
|
+
require 'sonar/request'
|
5
7
|
require 'awesome_print'
|
8
|
+
require 'table_print'
|
6
9
|
|
7
10
|
module Sonar
|
8
11
|
class CLI < Thor
|
9
|
-
class_option 'format', type: :string, desc: 'Flat JSON, JSON lines, or pretty printed [flat/lines/pretty]'
|
12
|
+
class_option 'format', type: :string, desc: 'Flat JSON (include empty collections), JSON lines of collection data (default), or pretty printed [flat/lines/pretty]'
|
10
13
|
|
11
14
|
def initialize(*)
|
12
15
|
@config = Sonar::RCFile.instance.load_file
|
@@ -24,34 +27,32 @@ module Sonar
|
|
24
27
|
ap @client.usage
|
25
28
|
end
|
26
29
|
|
27
|
-
desc 'search [QUERY TYPE] [QUERY TERM]', 'Search
|
30
|
+
desc 'search [QUERY TYPE] [QUERY TERM]', 'Search any query type from Sonar or specify \'all\' as QUERY TYPE to search them all.'
|
28
31
|
method_option 'record_limit', type: :numeric, aliases: '-n', desc: 'Maximum number of records to fetch'
|
29
|
-
method_option 'exact', type: :boolean, aliases: '-e', desc: 'Search for the query string exactly, do not include partial string matches'
|
30
|
-
|
31
32
|
def search(type, term)
|
32
|
-
|
33
|
-
@query[type.to_sym] = term
|
34
|
-
@query[:limit] = options['record_limit']
|
35
|
-
@query[:exact] = options['exact']
|
36
|
-
resp = @client.search(@query)
|
33
|
+
types = [type]
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
if type == 'all'
|
36
|
+
if term =~ Search::IS_IP
|
37
|
+
types = @client.ip_search_type_names
|
38
|
+
else
|
39
|
+
types = @client.domain_search_type_names
|
43
40
|
end
|
44
|
-
else
|
45
|
-
errors += 1 if resp.key?('errors') || resp.key?('error')
|
46
|
-
print_json(cleanup_data(resp), options['format'])
|
47
41
|
end
|
48
42
|
|
49
|
-
|
43
|
+
types.each do |type|
|
44
|
+
@query = {}
|
45
|
+
@query[type.to_sym] = term
|
46
|
+
@query[:limit] = options['record_limit']
|
47
|
+
resp = @client.search(@query)
|
48
|
+
handle_search_response(resp)
|
49
|
+
end
|
50
50
|
end
|
51
51
|
|
52
52
|
desc 'types', 'List all Sonar query types'
|
53
53
|
def types
|
54
|
-
|
54
|
+
tp.set :io, $stdout
|
55
|
+
tp Search::QUERY_TYPES, :name, { description: { width: 100 } }, :input
|
55
56
|
end
|
56
57
|
|
57
58
|
desc 'config', 'Sonar config file location'
|
@@ -79,6 +80,21 @@ module Sonar
|
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
83
|
+
def handle_search_response(resp)
|
84
|
+
errors = 0
|
85
|
+
if resp.is_a?(Sonar::Request::RequestIterator)
|
86
|
+
resp.each do |data|
|
87
|
+
errors += 1 if data.key?('errors') || data.key?('error')
|
88
|
+
print_json(cleanup_data(data), options['format'])
|
89
|
+
end
|
90
|
+
else
|
91
|
+
errors += 1 if resp.key?('errors') || resp.key?('error')
|
92
|
+
print_json(cleanup_data(resp), options['format'])
|
93
|
+
end
|
94
|
+
|
95
|
+
raise Search::SearchError.new("Encountered #{errors} errors while searching") if errors > 0
|
96
|
+
end
|
97
|
+
|
82
98
|
# Clean up whitespace and parse JSON values in responses
|
83
99
|
def cleanup_data(data)
|
84
100
|
return data unless data.is_a?(Hash) && data.has_key?('collection')
|
data/lib/sonar/client.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'faraday'
|
3
|
-
require '
|
3
|
+
require 'faraday/follow_redirects'
|
4
|
+
require 'faraday/rashify'
|
4
5
|
require 'forwardable'
|
5
6
|
require 'sonar/request'
|
6
|
-
require 'sonar/certificate'
|
7
7
|
require 'sonar/search'
|
8
8
|
require 'sonar/user'
|
9
9
|
require 'sonar/cli/cli'
|
@@ -14,7 +14,6 @@ module Sonar
|
|
14
14
|
extend Forwardable
|
15
15
|
|
16
16
|
include Request
|
17
|
-
include Certificate
|
18
17
|
include Search
|
19
18
|
include User
|
20
19
|
include Registration
|
@@ -39,9 +38,11 @@ module Sonar
|
|
39
38
|
def connection
|
40
39
|
params = {}
|
41
40
|
@conn = Faraday.new(url: api_url, params: params, headers: default_headers, ssl: { verify: true }) do |faraday|
|
42
|
-
faraday.use
|
43
|
-
faraday.use
|
44
|
-
faraday.
|
41
|
+
faraday.use Faraday::FollowRedirects::Middleware
|
42
|
+
faraday.use Faraday::Rashify::Middleware
|
43
|
+
faraday.request :json
|
44
|
+
|
45
|
+
faraday.response :json
|
45
46
|
faraday.adapter Faraday.default_adapter
|
46
47
|
end
|
47
48
|
@conn.headers['X-Sonar-Token'] = access_token
|
data/lib/sonar/search.rb
CHANGED
@@ -2,21 +2,16 @@
|
|
2
2
|
|
3
3
|
module Sonar
|
4
4
|
module Search
|
5
|
+
|
6
|
+
# Allow IP queries to be in the form of "1.", "1.2.", "1.2.3.", and "1.2.3.4"
|
7
|
+
IS_IP = /^(\d{1,3}\.|\d{1,3}\.\d{1,3}\.|\d{1,3}\.\d{1,3}\.\d{1,3}\.|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/
|
8
|
+
|
5
9
|
# Implemented search query types
|
6
|
-
|
7
|
-
'
|
8
|
-
'
|
9
|
-
'
|
10
|
-
|
11
|
-
'ipcerts' => 'IP to Certificates',
|
12
|
-
'namecerts' => 'Domain to Certificates',
|
13
|
-
'links_to' => 'HTTP References to Domain',
|
14
|
-
'ports' => 'Open Ports',
|
15
|
-
'processed' => 'Open Ports (Processed)',
|
16
|
-
'raw' => 'Open Ports (Raw)',
|
17
|
-
'sslcert' => 'Certificate Details',
|
18
|
-
'whois_ip' => 'Whois (IP)'
|
19
|
-
}
|
10
|
+
QUERY_TYPES = [
|
11
|
+
{ name: 'fdns', description: 'Domains to IP or IPs to Domain', input: 'domain' },
|
12
|
+
{ name: 'ports', description: 'Open Ports', input: 'ip' },
|
13
|
+
{ name: 'all', description: 'Search all appropriate search types for an IP or domain', input: 'all' }
|
14
|
+
]
|
20
15
|
|
21
16
|
##
|
22
17
|
# Generic exception for errors encountered while searching
|
@@ -24,6 +19,26 @@ module Sonar
|
|
24
19
|
class SearchError < StandardError
|
25
20
|
end
|
26
21
|
|
22
|
+
def ip_search_type_names
|
23
|
+
ip_search_types.map { |type| type[:name] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def domain_search_type_names
|
27
|
+
domain_search_types.map { |type| type[:name] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def ip_search_types
|
31
|
+
QUERY_TYPES.select { |type| type[:input] == 'ip' }
|
32
|
+
end
|
33
|
+
|
34
|
+
def domain_search_types
|
35
|
+
QUERY_TYPES.select { |type| type[:input] == 'domain' }
|
36
|
+
end
|
37
|
+
|
38
|
+
def query_type_names
|
39
|
+
QUERY_TYPES.map { |type| type[:name] }
|
40
|
+
end
|
41
|
+
|
27
42
|
##
|
28
43
|
# Get search
|
29
44
|
#
|
@@ -32,7 +47,7 @@ module Sonar
|
|
32
47
|
#
|
33
48
|
# @return [Hashie::Mash] with response of search
|
34
49
|
def search(params = {})
|
35
|
-
type_query = params.select { |k, _v|
|
50
|
+
type_query = params.select { |k, _v| query_type_names.include?(k.to_s) }.first
|
36
51
|
fail ArgumentError, "The query type provided is invalid or not yet implemented." unless type_query
|
37
52
|
type = type_query[0].to_sym
|
38
53
|
params[:q] = type_query[1]
|
data/lib/sonar/version.rb
CHANGED
data/lib/sonar.rb
CHANGED
data/sonar-client.gemspec
CHANGED
@@ -18,11 +18,15 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency '
|
22
|
-
spec.add_dependency '
|
21
|
+
spec.add_dependency 'faraday'
|
22
|
+
spec.add_dependency 'faraday-rashify'
|
23
|
+
spec.add_dependency 'rash_alt'
|
24
|
+
spec.add_dependency 'faraday-follow_redirects'
|
25
|
+
spec.add_dependency 'hashie'
|
23
26
|
spec.add_dependency 'multi_json'
|
24
27
|
spec.add_dependency 'thor'
|
25
28
|
spec.add_dependency 'awesome_print'
|
29
|
+
spec.add_dependency 'table_print'
|
26
30
|
|
27
31
|
spec.add_development_dependency "bundler"
|
28
32
|
spec.add_development_dependency "rake"
|
@@ -30,8 +34,7 @@ Gem::Specification.new do |spec|
|
|
30
34
|
spec.add_development_dependency "simplecov"
|
31
35
|
spec.add_development_dependency "simplecov-rcov"
|
32
36
|
spec.add_development_dependency "yard"
|
33
|
-
spec.add_development_dependency "vcr"
|
37
|
+
spec.add_development_dependency "vcr"
|
34
38
|
spec.add_development_dependency "shoulda"
|
35
|
-
spec.add_development_dependency "webmock", '~> 1.8.0'
|
36
39
|
spec.add_development_dependency "api_matchers"
|
37
40
|
end
|
data/spec/sonar/cli_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe Sonar::CLI do
|
|
7
7
|
Sonar::RCFile.instance.path = "#{fixtures_path}/sonar-stock.rc"
|
8
8
|
end
|
9
9
|
it 'throws an exception because of errors' do
|
10
|
-
expect { run_command('search
|
10
|
+
expect { run_command('search fdns 8.8.8.8') }.to raise_error(Sonar::Search::SearchError)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -35,17 +35,6 @@ describe Sonar::CLI do
|
|
35
35
|
expect(output).to eq('{"address":"192.168.1.1"}')
|
36
36
|
end
|
37
37
|
end
|
38
|
-
context 'client that returns sslcert reply with nested json' do
|
39
|
-
before do
|
40
|
-
allow_any_instance_of(Sonar::Client).to receive(:search).and_return(
|
41
|
-
Sonar::Client.new.search(sslcert: '152a0a633aaf13f02c428ac1a3e672e895512bfd')
|
42
|
-
)
|
43
|
-
end
|
44
|
-
it 'parses the nested values in an array' do
|
45
|
-
output = run_command('search sslcert 152a0a633aaf13f02c428ac1a3e672e895512bfd')
|
46
|
-
expect(JSON.parse(output)['collection'].first['details'].first['subject']['ST']).to eq('California')
|
47
|
-
end
|
48
|
-
end
|
49
38
|
context 'client that returns processed reply with nested json' do
|
50
39
|
before do
|
51
40
|
allow_any_instance_of(Sonar::Client).to receive(:search).and_return(
|
@@ -57,29 +46,27 @@ describe Sonar::CLI do
|
|
57
46
|
expect(JSON.parse(output)['collection'].first['value']['ip']).to eq('8.8.8.8')
|
58
47
|
end
|
59
48
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
49
|
+
|
50
|
+
describe 'sonar types command' do
|
51
|
+
it 'returns all sonar search types' do
|
52
|
+
output = run_command('types')
|
53
|
+
expect(output).to match(/Open Ports/)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'search all command' do
|
58
|
+
before do
|
59
|
+
allow_any_instance_of(Sonar::Client).to receive(:search).and_return(
|
60
|
+
Sonar::Client.new.search(fdns: '208.118.227.20', exact: true)
|
61
|
+
)
|
62
|
+
end
|
63
|
+
it 'returns results when searching for an IP' do
|
64
|
+
output = run_command('search all 208.118.227.20')
|
65
|
+
expect(output).to match(/rapid7\.com/)
|
72
66
|
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
Sonar::Client.new.search(fdns: '208.118.227.20')
|
77
|
-
)
|
78
|
-
end
|
79
|
-
it 'matches exactly without --exact' do
|
80
|
-
output = run_command('search fdns 208.118.227.20')
|
81
|
-
expect(JSON.parse(output)['collection'].size).to be > 1
|
82
|
-
end
|
67
|
+
it 'returns results when searching for a domain' do
|
68
|
+
output = run_command('search all rapid7.com')
|
69
|
+
expect(output).to match(/208\.118\.227\.20/)
|
83
70
|
end
|
84
71
|
end
|
85
72
|
end
|
data/spec/sonar/search_spec.rb
CHANGED
@@ -2,8 +2,29 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Sonar::Search do
|
5
|
+
let(:dummy_class) {
|
6
|
+
Class.new { extend Sonar::Search }
|
7
|
+
}
|
5
8
|
let(:client) { Sonar::Client.new }
|
6
9
|
|
10
|
+
describe "#ip_search_type_names" do
|
11
|
+
it 'includes ports' do
|
12
|
+
expect(dummy_class.ip_search_type_names).to include('ports')
|
13
|
+
end
|
14
|
+
it 'does not include fdns' do
|
15
|
+
expect(dummy_class.ip_search_type_names).to_not include('fdns')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#domain_search_type_names" do
|
20
|
+
it 'includes fdns' do
|
21
|
+
expect(dummy_class.domain_search_type_names).to include('fdns')
|
22
|
+
end
|
23
|
+
it 'does not include rdns' do
|
24
|
+
expect(dummy_class.domain_search_type_names).to_not include('rdns')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
7
28
|
describe "parameters" do
|
8
29
|
describe "query type" do
|
9
30
|
context "with an invalid query type" do
|
@@ -13,92 +34,45 @@ describe Sonar::Search do
|
|
13
34
|
end
|
14
35
|
end
|
15
36
|
|
16
|
-
describe "exact" do
|
17
|
-
it "shouldn't match anything when #exact is true" do
|
18
|
-
resp = client.search(rdns: "1.1.", exact: true)
|
19
|
-
expect(resp["collection"].size).to eq(0)
|
20
|
-
end
|
21
|
-
it "should match when #exact is false" do
|
22
|
-
resp = client.search(rdns: "1.1.", exact: false)
|
23
|
-
expect(resp["collection"].first["address"]).to match(/^1.1./)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
37
|
describe "limit" do
|
28
|
-
# The default size from APIv1/v2 is
|
38
|
+
# The default size from APIv1/v2 is 25 records
|
29
39
|
context "specifying the :limit to 3000 on #search" do
|
30
|
-
let(:resp) { client.search(
|
40
|
+
let(:resp) { client.search(fdns: '.hp.com', limit: 3000) }
|
31
41
|
|
32
42
|
it "should return a RequestIterator" do
|
33
43
|
expect(resp.class).to eq(Sonar::Request::RequestIterator)
|
34
44
|
end
|
35
|
-
it "should return
|
45
|
+
it "should return 120 x 25-record blocks" do
|
36
46
|
num_blocks = 0
|
37
47
|
resp.each do |resp_block|
|
38
|
-
|
39
|
-
|
48
|
+
if resp_block
|
49
|
+
expect(resp_block['collection'].size).to eq(25)
|
50
|
+
num_blocks += 1
|
51
|
+
end
|
40
52
|
end
|
41
|
-
expect(num_blocks).to eq(
|
53
|
+
expect(num_blocks).to eq(120)
|
42
54
|
end
|
43
55
|
end
|
44
56
|
end
|
45
57
|
end
|
46
58
|
|
47
|
-
context "certificate" do
|
48
|
-
let(:resp) { client.search(certificate: '.hp.com') }
|
49
|
-
|
50
|
-
it "should provide certificate details" do
|
51
|
-
expect(resp).to have_key('collection')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "rdns" do
|
56
|
-
context "rdnsname" do
|
57
|
-
let(:resp) { client.search(rdns: '208.118.227.10.rapid7.com') }
|
58
|
-
|
59
|
-
it "returns hashie response of search" do
|
60
|
-
expect(resp.class).to eq(Hashie::Mash)
|
61
|
-
end
|
62
|
-
it "rdnsname finds 208.118.227.10 for 208.118.227.10.rapid7.com" do
|
63
|
-
expect(resp['collection'].any? { |x| x['address'] == '208.118.227.10' }).to be(true)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context "rdnsip" do
|
68
|
-
let(:resp) { client.search(rdns: '188.40.56.11') }
|
69
|
-
|
70
|
-
it "rdnsip finds static.11.56.40.188.clients.your-server.de for 188.40.56.11" do
|
71
|
-
expect(resp['collection'].any? { |x| x['name'] == 'static.11.56.40.188.clients.your-server.de' }).to be(true)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context "validation" do
|
76
|
-
let(:resp) { client.search(rdns: '188.40.56.11@#&#') }
|
77
|
-
|
78
|
-
it "should error for invalid domain query type" do
|
79
|
-
expect(resp["error"]).to eq("Invalid query")
|
80
|
-
expect(resp["errors"].first).to eq("Expected a domain but got '188.40.56.11@#&#'")
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
59
|
describe "fdns" do
|
86
60
|
context "fdnsname" do
|
87
61
|
let(:resp) { client.search(fdns: 'rapid7.com') }
|
88
62
|
|
89
63
|
it "returns hashie response of search" do
|
90
|
-
expect(resp.class).to eq(Hashie::Mash)
|
64
|
+
expect(resp.class).to eq(Hashie::Mash::Rash)
|
91
65
|
end
|
92
|
-
it "finds fdnsname
|
93
|
-
expect(resp['collection'].
|
66
|
+
it "finds fdnsname multiple IP addresses for rapid7.com" do
|
67
|
+
expect(resp['collection'].select { |x| x['address'] }.size).to be >= 2
|
94
68
|
end
|
95
69
|
end
|
96
70
|
|
97
71
|
context "fdnsip" do
|
98
72
|
let(:resp) { client.search(fdns: '208.118.227.10') }
|
99
73
|
|
100
|
-
it "finds fdnsip rapid7
|
101
|
-
expect(resp['collection'].any? { |x| x['address'].match('
|
74
|
+
it "finds fdnsip rapid7 domains at 208.118.227.10" do
|
75
|
+
expect(resp['collection'].any? { |x| x['address'].match('rapidseven') }).to be(true)
|
102
76
|
end
|
103
77
|
end
|
104
78
|
|
@@ -107,77 +81,11 @@ describe Sonar::Search do
|
|
107
81
|
|
108
82
|
it "should error for invalid domain query type" do
|
109
83
|
expect(resp["error"]).to eq("Invalid query")
|
110
|
-
expect(resp["errors"].first).to eq("
|
84
|
+
expect(resp["errors"].first).to eq("An unsupported gTLD or ccTLD was specified for: 188.40.56.11@#&#")
|
111
85
|
end
|
112
86
|
end
|
113
87
|
end
|
114
88
|
|
115
|
-
context "links_to" do
|
116
|
-
let(:resp) { client.search(links_to: 'rapid7.com') }
|
117
|
-
|
118
|
-
it "should provide links_to details" do
|
119
|
-
expect(resp).to have_key('collection')
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
context "ipcerts" do
|
124
|
-
let(:resp) { client.search(ipcerts: '208.118.227.10') }
|
125
|
-
|
126
|
-
it "should provide ipcerts details" do
|
127
|
-
expect(resp).to have_key('collection')
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context "certips" do
|
132
|
-
let(:resp) { client.search(certips: '1e80c24b97c928bb1db7d4d3c05475a6a40a1186') }
|
133
|
-
|
134
|
-
it "should provide certips details" do
|
135
|
-
expect(resp).to have_key('collection')
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
context "namecerts" do
|
140
|
-
let(:resp) { client.search(namecerts: '.rapid7.com') }
|
141
|
-
|
142
|
-
it "should provide namecerts details" do
|
143
|
-
expect(resp).to have_key('collection')
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context "sslcert" do
|
148
|
-
let(:resp) { client.search(sslcert: '1e80c24b97c928bb1db7d4d3c05475a6a40a1186') }
|
149
|
-
|
150
|
-
it "should provide sslcert details" do
|
151
|
-
expect(resp).to have_key('collection')
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
context "whois_ip" do
|
156
|
-
let(:resp) { client.search(whois_ip: '208.118.227.10') }
|
157
|
-
|
158
|
-
xit "should find rapid7.com" do
|
159
|
-
expect(resp['name']).to eq('TWDX-208-118-227-0-1')
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
# TODO: actually check response
|
164
|
-
context "raw" do
|
165
|
-
let(:resp) { client.search(raw: '208.118.227.10') }
|
166
|
-
|
167
|
-
it "should return a collection" do
|
168
|
-
expect(resp).to have_key('collection')
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# TODO: actually check response
|
173
|
-
context "processed" do
|
174
|
-
let(:resp) { client.search(processed: '208.118.227.10') }
|
175
|
-
|
176
|
-
it "should return a collection" do
|
177
|
-
expect(resp).to have_key('collection')
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
89
|
# TODO: actually check response
|
182
90
|
context "ports" do
|
183
91
|
let(:resp) { client.search(ports: '208.118.227.10') }
|
data/spec/sonar_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -20,7 +20,7 @@ end
|
|
20
20
|
VCR.configure do |c|
|
21
21
|
c.allow_http_connections_when_no_cassette = true
|
22
22
|
c.cassette_library_dir = 'spec/cassette'
|
23
|
-
c.hook_into :
|
23
|
+
c.hook_into :faraday
|
24
24
|
c.configure_rspec_metadata!
|
25
25
|
c.default_cassette_options = { record: :new_episodes }
|
26
26
|
end
|
metadata
CHANGED
@@ -1,43 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sonar-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Deardorff & HD Moore
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: faraday
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday-rashify
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rash_alt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday-follow_redirects
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: hashie
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
30
72
|
requirements:
|
31
|
-
- - "
|
73
|
+
- - ">="
|
32
74
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
75
|
+
version: '0'
|
34
76
|
type: :runtime
|
35
77
|
prerelease: false
|
36
78
|
version_requirements: !ruby/object:Gem::Requirement
|
37
79
|
requirements:
|
38
|
-
- - "
|
80
|
+
- - ">="
|
39
81
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
82
|
+
version: '0'
|
41
83
|
- !ruby/object:Gem::Dependency
|
42
84
|
name: multi_json
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,13 +123,13 @@ dependencies:
|
|
81
123
|
- !ruby/object:Gem::Version
|
82
124
|
version: '0'
|
83
125
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
126
|
+
name: table_print
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
86
128
|
requirements:
|
87
129
|
- - ">="
|
88
130
|
- !ruby/object:Gem::Version
|
89
131
|
version: '0'
|
90
|
-
type: :
|
132
|
+
type: :runtime
|
91
133
|
prerelease: false
|
92
134
|
version_requirements: !ruby/object:Gem::Requirement
|
93
135
|
requirements:
|
@@ -95,7 +137,7 @@ dependencies:
|
|
95
137
|
- !ruby/object:Gem::Version
|
96
138
|
version: '0'
|
97
139
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
140
|
+
name: bundler
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
100
142
|
requirements:
|
101
143
|
- - ">="
|
@@ -109,7 +151,7 @@ dependencies:
|
|
109
151
|
- !ruby/object:Gem::Version
|
110
152
|
version: '0'
|
111
153
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
154
|
+
name: rake
|
113
155
|
requirement: !ruby/object:Gem::Requirement
|
114
156
|
requirements:
|
115
157
|
- - ">="
|
@@ -123,7 +165,7 @@ dependencies:
|
|
123
165
|
- !ruby/object:Gem::Version
|
124
166
|
version: '0'
|
125
167
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
168
|
+
name: rspec
|
127
169
|
requirement: !ruby/object:Gem::Requirement
|
128
170
|
requirements:
|
129
171
|
- - ">="
|
@@ -137,7 +179,7 @@ dependencies:
|
|
137
179
|
- !ruby/object:Gem::Version
|
138
180
|
version: '0'
|
139
181
|
- !ruby/object:Gem::Dependency
|
140
|
-
name: simplecov
|
182
|
+
name: simplecov
|
141
183
|
requirement: !ruby/object:Gem::Requirement
|
142
184
|
requirements:
|
143
185
|
- - ">="
|
@@ -151,7 +193,7 @@ dependencies:
|
|
151
193
|
- !ruby/object:Gem::Version
|
152
194
|
version: '0'
|
153
195
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
196
|
+
name: simplecov-rcov
|
155
197
|
requirement: !ruby/object:Gem::Requirement
|
156
198
|
requirements:
|
157
199
|
- - ">="
|
@@ -165,21 +207,21 @@ dependencies:
|
|
165
207
|
- !ruby/object:Gem::Version
|
166
208
|
version: '0'
|
167
209
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
210
|
+
name: yard
|
169
211
|
requirement: !ruby/object:Gem::Requirement
|
170
212
|
requirements:
|
171
|
-
- - "
|
213
|
+
- - ">="
|
172
214
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
215
|
+
version: '0'
|
174
216
|
type: :development
|
175
217
|
prerelease: false
|
176
218
|
version_requirements: !ruby/object:Gem::Requirement
|
177
219
|
requirements:
|
178
|
-
- - "
|
220
|
+
- - ">="
|
179
221
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
222
|
+
version: '0'
|
181
223
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
224
|
+
name: vcr
|
183
225
|
requirement: !ruby/object:Gem::Requirement
|
184
226
|
requirements:
|
185
227
|
- - ">="
|
@@ -193,19 +235,19 @@ dependencies:
|
|
193
235
|
- !ruby/object:Gem::Version
|
194
236
|
version: '0'
|
195
237
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
238
|
+
name: shoulda
|
197
239
|
requirement: !ruby/object:Gem::Requirement
|
198
240
|
requirements:
|
199
|
-
- - "
|
241
|
+
- - ">="
|
200
242
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
243
|
+
version: '0'
|
202
244
|
type: :development
|
203
245
|
prerelease: false
|
204
246
|
version_requirements: !ruby/object:Gem::Requirement
|
205
247
|
requirements:
|
206
|
-
- - "
|
248
|
+
- - ">="
|
207
249
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
250
|
+
version: '0'
|
209
251
|
- !ruby/object:Gem::Dependency
|
210
252
|
name: api_matchers
|
211
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -252,7 +294,6 @@ files:
|
|
252
294
|
- spec/cassette/valid_ms_registration.yml
|
253
295
|
- spec/fixtures/sonar-stock.rc
|
254
296
|
- spec/fixtures/sonar.rc
|
255
|
-
- spec/sonar/certificate_spec.rb
|
256
297
|
- spec/sonar/cli_spec.rb
|
257
298
|
- spec/sonar/client_spec.rb
|
258
299
|
- spec/sonar/registration_spec.rb
|
@@ -264,7 +305,7 @@ homepage: https://sonar.labs.rapid7.com
|
|
264
305
|
licenses:
|
265
306
|
- MIT
|
266
307
|
metadata: {}
|
267
|
-
post_install_message:
|
308
|
+
post_install_message:
|
268
309
|
rdoc_options: []
|
269
310
|
require_paths:
|
270
311
|
- lib
|
@@ -279,16 +320,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
279
320
|
- !ruby/object:Gem::Version
|
280
321
|
version: '0'
|
281
322
|
requirements: []
|
282
|
-
rubyforge_project:
|
283
|
-
rubygems_version: 2.
|
284
|
-
signing_key:
|
323
|
+
rubyforge_project:
|
324
|
+
rubygems_version: 2.7.9
|
325
|
+
signing_key:
|
285
326
|
specification_version: 4
|
286
327
|
summary: API Wrapper for Sonar
|
287
328
|
test_files:
|
288
329
|
- spec/cassette/valid_ms_registration.yml
|
289
330
|
- spec/fixtures/sonar-stock.rc
|
290
331
|
- spec/fixtures/sonar.rc
|
291
|
-
- spec/sonar/certificate_spec.rb
|
292
332
|
- spec/sonar/cli_spec.rb
|
293
333
|
- spec/sonar/client_spec.rb
|
294
334
|
- spec/sonar/registration_spec.rb
|
@@ -296,4 +336,3 @@ test_files:
|
|
296
336
|
- spec/sonar/user_spec.rb
|
297
337
|
- spec/sonar_spec.rb
|
298
338
|
- spec/spec_helper.rb
|
299
|
-
has_rdoc:
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe Sonar::Search do
|
5
|
-
let(:client) { Sonar::Client.new }
|
6
|
-
|
7
|
-
context "sha1 #get_certificate" do
|
8
|
-
it "should find the link to certificate by sha1" do
|
9
|
-
res = client.get_certificate(sha1: "1e80c24b97c928bb1db7d4d3c05475a6a40a1186")
|
10
|
-
expect(res._links.self.href).to match(/certificates/)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|