urlscan 0.3.0 → 0.4.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 +4 -4
- data/README.md +29 -15
- data/lib/urlscan.rb +9 -0
- data/lib/urlscan/api.rb +6 -92
- data/lib/urlscan/cli.rb +3 -63
- data/lib/urlscan/clients/base.rb +82 -0
- data/lib/urlscan/clients/community.rb +36 -0
- data/lib/urlscan/clients/pro.rb +53 -0
- data/lib/urlscan/commands/base.rb +26 -0
- data/lib/urlscan/commands/community.rb +51 -0
- data/lib/urlscan/commands/pro.rb +18 -0
- data/lib/urlscan/version.rb +1 -1
- data/urlscan.gemspec +1 -2
- metadata +10 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 798702a904c93cd2895f683aae28dd0dc3d44dfea5b17d247168a6189bcb9c21
|
|
4
|
+
data.tar.gz: 3fbca0a7a6210fa2062ea02f84bb83492544bbb53aa5d7d5e0cad09077fa271e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4cfebe6cd4c4673e3afaa2575b4af09e5b46d357097ce3701c26200dc2ff565124a04b57a1bdccb652e3330a5886e1fbf2550b93f00e73f12f7000d52c61768c
|
|
7
|
+
data.tar.gz: 6239d851913a5b67fd54c4688106145f3ffe4faea8908faf928d92c6ed8263c8d78c4891719ba1dc0f799d233ea99b8af498773fef8221c016e9e625443921c9
|
data/README.md
CHANGED
|
@@ -18,7 +18,7 @@ gem install urlscan
|
|
|
18
18
|
## API usage
|
|
19
19
|
|
|
20
20
|
```ruby
|
|
21
|
-
require
|
|
21
|
+
require "urlscan"
|
|
22
22
|
|
|
23
23
|
# when given nothing, it tries to load your API key from ENV["URLSCAN_API_KEY"]
|
|
24
24
|
api = UrlScan::API.new
|
|
@@ -27,32 +27,34 @@ api = UrlScan::API.new(api_key)
|
|
|
27
27
|
|
|
28
28
|
# Submit a URL to scan
|
|
29
29
|
res = api.submit("https://wikipedia.org")
|
|
30
|
-
puts res["result"] # => "https://urlscan.io/result/ac04bc14-4efe-439d-b356-8384843daf75/"
|
|
31
30
|
|
|
32
31
|
# Get a scan result
|
|
33
32
|
res = api.result("ac04bc14-4efe-439d-b356-8384843daf75")
|
|
34
|
-
p res # => See the following URL as an example of the response.
|
|
35
|
-
# https://gist.github.com/ninoseki/a974d7e95629813615b380c30e737825#file-result-json
|
|
36
33
|
|
|
37
34
|
# Get a DOM
|
|
38
35
|
res = api.dom("ac04bc14-4efe-439d-b356-8384843daf75")
|
|
39
|
-
p res
|
|
40
36
|
|
|
41
37
|
# Search
|
|
42
38
|
res = api.search("wikipedia.org")
|
|
43
|
-
p res # => See the following URL as an example of the reponse.
|
|
44
|
-
# https://gist.github.com/ninoseki/a974d7e95629813615b380c30e737825#file-search-json
|
|
45
39
|
```
|
|
46
40
|
|
|
47
|
-
|
|
41
|
+
## Supported API endpoints
|
|
48
42
|
|
|
49
|
-
| HTTP Method | URI | API method
|
|
50
|
-
|
|
51
|
-
| POST | /scan | `UrlScan::
|
|
52
|
-
| GET | /result/`uuid`/ | `UrlScan::
|
|
53
|
-
| GET | /dom/`uuid`/ | `UrlScan::
|
|
54
|
-
| GET | /screenshots/`uuid`.png | `UrlScan::
|
|
55
|
-
| GET | /search | `UrlScan::
|
|
43
|
+
| HTTP Method | URI | API method |
|
|
44
|
+
|-------------|-------------------------|-------------------------------------------------------------------------------|
|
|
45
|
+
| POST | /scan | `UrlScan::Clients::Community#submit(url, is_public = true)` |
|
|
46
|
+
| GET | /result/`uuid`/ | `UrlScan::Clients::Community#result(uuid)` |
|
|
47
|
+
| GET | /dom/`uuid`/ | `UrlScan::Clients::Community#dom(uuid)` |
|
|
48
|
+
| GET | /screenshots/`uuid`.png | `UrlScan::Clients::Community#screenshot(uuid)` |
|
|
49
|
+
| GET | /search | `UrlScan::Clients::Community#search(q, size: 100, offset: 0, sort: "_score")` |
|
|
50
|
+
|
|
51
|
+
### Pro
|
|
52
|
+
|
|
53
|
+
| HTTP Method | URI | API method |
|
|
54
|
+
|-------------|---------|-------------------------------------------------------------------|
|
|
55
|
+
| GET | /search | `UrlScan::Clients::Pro#search(query: nil, filter: nil, size: 50)` |
|
|
56
|
+
| GET | /brands | `UrlScan::Clients::Pro#brands` |
|
|
57
|
+
| GET | /kits | `UrlScan::Clients::Pro#kits` |
|
|
56
58
|
|
|
57
59
|
## CLI usage
|
|
58
60
|
|
|
@@ -70,3 +72,15 @@ Options:
|
|
|
70
72
|
[--API-KEY=API_KEY]
|
|
71
73
|
|
|
72
74
|
```
|
|
75
|
+
|
|
76
|
+
### Pro
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
$ urlscan pro
|
|
80
|
+
Commands:
|
|
81
|
+
urlscan pro help [COMMAND] # Describe subcommands or one specific subcommand
|
|
82
|
+
urlscan pro search # search for scans
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
[--API-KEY=API_KEY]
|
|
86
|
+
```
|
data/lib/urlscan.rb
CHANGED
|
@@ -2,5 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
require "urlscan/version"
|
|
4
4
|
require "urlscan/exceptions"
|
|
5
|
+
|
|
6
|
+
require "urlscan/clients/base"
|
|
7
|
+
require "urlscan/clients/community"
|
|
8
|
+
require "urlscan/clients/pro"
|
|
9
|
+
|
|
10
|
+
require "urlscan/commands/base"
|
|
11
|
+
require "urlscan/commands/community"
|
|
12
|
+
require "urlscan/commands/pro"
|
|
13
|
+
|
|
5
14
|
require "urlscan/api"
|
|
6
15
|
require "urlscan/cli"
|
data/lib/urlscan/api.rb
CHANGED
|
@@ -1,104 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
4
|
-
require "json"
|
|
3
|
+
require "forwardable"
|
|
5
4
|
|
|
6
5
|
module UrlScan
|
|
7
6
|
class API
|
|
8
|
-
|
|
9
|
-
HOST = "urlscan.io"
|
|
10
|
-
URL = "https://#{HOST}/api/v#{VERSION}"
|
|
7
|
+
extend Forwardable
|
|
11
8
|
|
|
12
|
-
attr_reader :
|
|
9
|
+
attr_reader :pro
|
|
13
10
|
|
|
14
11
|
def initialize(key = ENV["URLSCAN_API_KEY"])
|
|
15
|
-
@
|
|
12
|
+
@community = Clients::Community.new(key)
|
|
13
|
+
@pro = Clients::Pro.new(key)
|
|
16
14
|
end
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
def submit(url, is_public = true)
|
|
20
|
-
raise ArgumentError, "API key is required for this method." if key.nil?
|
|
21
|
-
|
|
22
|
-
params = { url: url, public: is_public ? "on" : "off" }
|
|
23
|
-
post("/scan/", params) { |json| json }
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @return [Hash]
|
|
27
|
-
def result(uuid)
|
|
28
|
-
get("/result/#{uuid}") { |json| json }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @return [String]
|
|
32
|
-
def dom(uuid)
|
|
33
|
-
get("/dom/#{uuid}/") { |dom| dom }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def screenshot(uuid)
|
|
37
|
-
get("/screenshots/#{uuid}.png") { |png| png }
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# @return [Hash]
|
|
41
|
-
def search(q, size: 100, offset: 0, sort: "_score")
|
|
42
|
-
params = { q: q, size: size, offset: offset, sort: sort }
|
|
43
|
-
query = URI.encode_www_form(params)
|
|
44
|
-
get("/search/?#{query}") { |json| json }
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def url_for(path)
|
|
48
|
-
URI(URL + path)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def https_options
|
|
52
|
-
if proxy = ENV["HTTPS_PROXY"]
|
|
53
|
-
uri = URI(proxy)
|
|
54
|
-
{
|
|
55
|
-
proxy_address: uri.hostname,
|
|
56
|
-
proxy_port: uri.port,
|
|
57
|
-
proxy_from_env: false,
|
|
58
|
-
use_ssl: true
|
|
59
|
-
}
|
|
60
|
-
else
|
|
61
|
-
{ use_ssl: true }
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def request(req)
|
|
66
|
-
Net::HTTP.start(HOST, 443, https_options) do |http|
|
|
67
|
-
response = http.request(req)
|
|
68
|
-
|
|
69
|
-
case response.code
|
|
70
|
-
when "200"
|
|
71
|
-
if response["Content-Type"].to_s.include? "application/json"
|
|
72
|
-
yield JSON.parse(response.body)
|
|
73
|
-
else
|
|
74
|
-
yield response.body
|
|
75
|
-
end
|
|
76
|
-
when "400" then raise ProcessingError, response.body
|
|
77
|
-
when "401" then raise AuthenticationError, response.body
|
|
78
|
-
when "404" then raise NotFound, response.body
|
|
79
|
-
when "429" then raise RateLimited, response.body
|
|
80
|
-
when "500" then raise InternalServerError, response.body
|
|
81
|
-
else
|
|
82
|
-
raise ResponseError, response.body
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def auth_header
|
|
88
|
-
{ "API-KEY": key }
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def get(path, &block)
|
|
92
|
-
get = Net::HTTP::Get.new(url_for(path))
|
|
93
|
-
request(get, &block)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def post(path, json, &block)
|
|
97
|
-
post = Net::HTTP::Post.new(url_for(path), auth_header)
|
|
98
|
-
post.content_type = "application/json"
|
|
99
|
-
post.body = json.to_json
|
|
100
|
-
|
|
101
|
-
request(post, &block)
|
|
102
|
-
end
|
|
16
|
+
def_delegators :@community, :submit, :result, :dom, :screenshot, :search
|
|
103
17
|
end
|
|
104
18
|
end
|
data/lib/urlscan/cli.rb
CHANGED
|
@@ -1,68 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "json"
|
|
4
|
-
require "thor"
|
|
5
|
-
|
|
6
3
|
module UrlScan
|
|
7
|
-
class CLI <
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
desc "submit [URL]", "submit a scan to [URL]"
|
|
11
|
-
method_option :public, type: :boolean, default: true
|
|
12
|
-
def submit(url)
|
|
13
|
-
with_error_handling do
|
|
14
|
-
res = api.submit(url, options[:public])
|
|
15
|
-
puts JSON.pretty_generate(res)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
desc "result [UUID]", "get the result of a scan using the scan id [UUID]"
|
|
20
|
-
def result(uuid)
|
|
21
|
-
with_error_handling do
|
|
22
|
-
res = api.result(uuid)
|
|
23
|
-
puts JSON.pretty_generate(res)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
desc "search [QUERY]", "search for scans by [QUERY]"
|
|
28
|
-
method_option :size, type: :numeric, default: 100
|
|
29
|
-
method_option :offset, type: :numeric, default: 0
|
|
30
|
-
method_option :sort, type: :string, default: "_score"
|
|
31
|
-
def search(query)
|
|
32
|
-
with_error_handling do
|
|
33
|
-
res = api.search(query, size: options["size"], offset: options["offset"], sort: options["sort"])
|
|
34
|
-
puts JSON.pretty_generate(res)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
desc "dom [UUID]", "get the DOM of a scan using the scan id [UUID]"
|
|
39
|
-
def dom(uuid)
|
|
40
|
-
with_error_handling do
|
|
41
|
-
res = api.dom(uuid)
|
|
42
|
-
puts res
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
desc "screenshot [UUID]", "get the screenshot(image/png) of a scan using the scan id [UUID]"
|
|
47
|
-
def screenshot(uuid)
|
|
48
|
-
with_error_handling do
|
|
49
|
-
res = api.screenshot(uuid)
|
|
50
|
-
puts res
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
no_commands do
|
|
55
|
-
def api
|
|
56
|
-
options["API_KEY"] ? API.new(options["API_KEY"]) : API.new
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def with_error_handling
|
|
60
|
-
yield
|
|
61
|
-
rescue ArgumentError => _e
|
|
62
|
-
puts "Warning: please specify your urlscan.io API key via ENV['URLSCAN_API_KEY'] or --API-KEY"
|
|
63
|
-
rescue ResponseError => e
|
|
64
|
-
puts "Warning: #{e}"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
4
|
+
class CLI < Commands::Community
|
|
5
|
+
desc "pro", "PRO api commands"
|
|
6
|
+
subcommand "pro", Commands::Pro
|
|
67
7
|
end
|
|
68
8
|
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/https"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module UrlScan
|
|
7
|
+
module Clients
|
|
8
|
+
class Base
|
|
9
|
+
VERSION = 1
|
|
10
|
+
HOST = "urlscan.io"
|
|
11
|
+
|
|
12
|
+
attr_reader :key
|
|
13
|
+
|
|
14
|
+
def initialize(key = ENV["URLSCAN_API_KEY"])
|
|
15
|
+
@key = key
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def url
|
|
21
|
+
@url ||= "https://#{self.class::HOST}/api/v#{self.class::VERSION}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def url_for(path)
|
|
25
|
+
URI(url + path)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def https_options
|
|
29
|
+
if proxy = ENV["HTTPS_PROXY"]
|
|
30
|
+
uri = URI(proxy)
|
|
31
|
+
{
|
|
32
|
+
proxy_address: uri.hostname,
|
|
33
|
+
proxy_port: uri.port,
|
|
34
|
+
proxy_from_env: false,
|
|
35
|
+
use_ssl: true
|
|
36
|
+
}
|
|
37
|
+
else
|
|
38
|
+
{ use_ssl: true }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def request(req)
|
|
43
|
+
Net::HTTP.start(HOST, 443, https_options) do |http|
|
|
44
|
+
response = http.request(req)
|
|
45
|
+
|
|
46
|
+
case response.code
|
|
47
|
+
when "200"
|
|
48
|
+
if response["Content-Type"].to_s.include? "application/json"
|
|
49
|
+
yield JSON.parse(response.body)
|
|
50
|
+
else
|
|
51
|
+
yield response.body
|
|
52
|
+
end
|
|
53
|
+
when "400" then raise ProcessingError, response.body
|
|
54
|
+
when "401" then raise AuthenticationError, response.body
|
|
55
|
+
when "404" then raise NotFound, response.body
|
|
56
|
+
when "429" then raise RateLimited, response.body
|
|
57
|
+
when "500" then raise InternalServerError, response.body
|
|
58
|
+
else
|
|
59
|
+
raise ResponseError, response.body
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def auth_header
|
|
65
|
+
{ "API-KEY": key }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def get(path, &block)
|
|
69
|
+
get = Net::HTTP::Get.new(url_for(path))
|
|
70
|
+
request(get, &block)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def post(path, json, &block)
|
|
74
|
+
post = Net::HTTP::Post.new(url_for(path), auth_header)
|
|
75
|
+
post.content_type = "application/json"
|
|
76
|
+
post.body = json.to_json
|
|
77
|
+
|
|
78
|
+
request(post, &block)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module UrlScan
|
|
4
|
+
module Clients
|
|
5
|
+
class Community < Base
|
|
6
|
+
# @return [Hash]
|
|
7
|
+
def submit(url, is_public = true)
|
|
8
|
+
raise ArgumentError, "API key is required for this method." if key.nil?
|
|
9
|
+
|
|
10
|
+
params = { url: url, public: is_public ? "on" : "off" }
|
|
11
|
+
post("/scan/", params) { |json| json }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [Hash]
|
|
15
|
+
def result(uuid)
|
|
16
|
+
get("/result/#{uuid}") { |json| json }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [String]
|
|
20
|
+
def dom(uuid)
|
|
21
|
+
get("/dom/#{uuid}/") { |dom| dom }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def screenshot(uuid)
|
|
25
|
+
get("/screenshots/#{uuid}.png") { |png| png }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Hash]
|
|
29
|
+
def search(q, size: 100, offset: 0, sort: "_score")
|
|
30
|
+
params = { q: q, size: size, offset: offset, sort: sort }
|
|
31
|
+
query = URI.encode_www_form(params)
|
|
32
|
+
get("/search/?#{query}") { |json| json }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module UrlScan
|
|
4
|
+
module Clients
|
|
5
|
+
class Pro < Base
|
|
6
|
+
VERSION = 1
|
|
7
|
+
HOST = "pro.urlscan.com"
|
|
8
|
+
|
|
9
|
+
def initialize(key = ENV["URLSCAN_API_KEY"])
|
|
10
|
+
super key
|
|
11
|
+
|
|
12
|
+
raise ArgumentError, "API key is required for this class." if key.nil?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Hash]
|
|
16
|
+
def search(query: nil, filter: nil, size: 50)
|
|
17
|
+
filter = build_filter(filter)
|
|
18
|
+
params = { q: query, size: size }.compact
|
|
19
|
+
uri_query = URI.encode_www_form(params)
|
|
20
|
+
uri_query << "&filter=#{filter}" if filter
|
|
21
|
+
|
|
22
|
+
get("/search?#{uri_query}") { |json| json }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Hash]
|
|
26
|
+
def brands
|
|
27
|
+
get("/brands") { |json| json }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Hash]
|
|
31
|
+
def kits
|
|
32
|
+
get("/kits") { |json| json }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def build_filter(filter)
|
|
38
|
+
return nil unless filter
|
|
39
|
+
|
|
40
|
+
filter.start_with?("$") ? filter : "$#{filter}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def url
|
|
44
|
+
@url ||= "https://#{self.class::HOST}/api/v#{self.class::VERSION}/pro"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def get(path, &block)
|
|
48
|
+
get = Net::HTTP::Get.new(url_for(path), auth_header)
|
|
49
|
+
request(get, &block)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "thor"
|
|
5
|
+
|
|
6
|
+
module UrlScan
|
|
7
|
+
module Commands
|
|
8
|
+
class Base < Thor
|
|
9
|
+
class_option :API_KEY, type: :string
|
|
10
|
+
|
|
11
|
+
no_commands do
|
|
12
|
+
def api
|
|
13
|
+
options.key?("API_KEY") ? API.new(options["API_KEY"]) : API.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def with_error_handling
|
|
17
|
+
yield
|
|
18
|
+
rescue ArgumentError => _e
|
|
19
|
+
puts "Warning: please specify your urlscan.io API key via ENV['URLSCAN_API_KEY'] or --API-KEY"
|
|
20
|
+
rescue ResponseError => e
|
|
21
|
+
puts "Warning: #{e}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module UrlScan
|
|
4
|
+
module Commands
|
|
5
|
+
class Community < Base
|
|
6
|
+
desc "submit [URL]", "submit a scan to [URL]"
|
|
7
|
+
method_option :public, type: :boolean, default: true
|
|
8
|
+
def submit(url)
|
|
9
|
+
with_error_handling do
|
|
10
|
+
res = api.submit(url, options[:public])
|
|
11
|
+
puts JSON.pretty_generate(res)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc "result [UUID]", "get the result of a scan using the scan id [UUID]"
|
|
16
|
+
def result(uuid)
|
|
17
|
+
with_error_handling do
|
|
18
|
+
res = api.result(uuid)
|
|
19
|
+
puts JSON.pretty_generate(res)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
desc "search [QUERY]", "search for scans by [QUERY]"
|
|
24
|
+
method_option :size, type: :numeric, default: 100
|
|
25
|
+
method_option :offset, type: :numeric, default: 0
|
|
26
|
+
method_option :sort, type: :string, default: "_score"
|
|
27
|
+
def search(query)
|
|
28
|
+
with_error_handling do
|
|
29
|
+
res = api.search(query, size: options["size"], offset: options["offset"], sort: options["sort"])
|
|
30
|
+
puts JSON.pretty_generate(res)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc "dom [UUID]", "get the DOM of a scan using the scan id [UUID]"
|
|
35
|
+
def dom(uuid)
|
|
36
|
+
with_error_handling do
|
|
37
|
+
res = api.dom(uuid)
|
|
38
|
+
puts res
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc "screenshot [UUID]", "get the screenshot(image/png) of a scan using the scan id [UUID]"
|
|
43
|
+
def screenshot(uuid)
|
|
44
|
+
with_error_handling do
|
|
45
|
+
res = api.screenshot(uuid)
|
|
46
|
+
puts res
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module UrlScan
|
|
4
|
+
module Commands
|
|
5
|
+
class Pro < Base
|
|
6
|
+
desc "search", "search for scans"
|
|
7
|
+
method_option :size, type: :numeric, default: 50
|
|
8
|
+
method_option :query, type: :string
|
|
9
|
+
method_option :filter, type: :string
|
|
10
|
+
def search
|
|
11
|
+
with_error_handling do
|
|
12
|
+
res = api.pro.search(query: options["query"], filter: options["filter"], size: options["size"])
|
|
13
|
+
puts JSON.pretty_generate(res)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/urlscan/version.rb
CHANGED
data/urlscan.gemspec
CHANGED
|
@@ -23,11 +23,10 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 2.0"
|
|
25
25
|
spec.add_development_dependency "coveralls", "~> 0.8"
|
|
26
|
-
spec.add_development_dependency "dotenv", "~> 2.5"
|
|
27
26
|
spec.add_development_dependency "rake", "~> 12.3"
|
|
28
27
|
spec.add_development_dependency "rspec", "~> 3.8"
|
|
29
28
|
spec.add_development_dependency "vcr", "~> 5.0"
|
|
30
|
-
spec.add_development_dependency "webmock", "~> 3.
|
|
29
|
+
spec.add_development_dependency "webmock", "~> 3.7"
|
|
31
30
|
|
|
32
31
|
spec.add_runtime_dependency "thor", "~> 0.20"
|
|
33
32
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: urlscan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Manabu Niseki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-09-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -38,20 +38,6 @@ dependencies:
|
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0.8'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: dotenv
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '2.5'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '2.5'
|
|
55
41
|
- !ruby/object:Gem::Dependency
|
|
56
42
|
name: rake
|
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,14 +86,14 @@ dependencies:
|
|
|
100
86
|
requirements:
|
|
101
87
|
- - "~>"
|
|
102
88
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '3.
|
|
89
|
+
version: '3.7'
|
|
104
90
|
type: :development
|
|
105
91
|
prerelease: false
|
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
93
|
requirements:
|
|
108
94
|
- - "~>"
|
|
109
95
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '3.
|
|
96
|
+
version: '3.7'
|
|
111
97
|
- !ruby/object:Gem::Dependency
|
|
112
98
|
name: thor
|
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -143,6 +129,12 @@ files:
|
|
|
143
129
|
- lib/urlscan.rb
|
|
144
130
|
- lib/urlscan/api.rb
|
|
145
131
|
- lib/urlscan/cli.rb
|
|
132
|
+
- lib/urlscan/clients/base.rb
|
|
133
|
+
- lib/urlscan/clients/community.rb
|
|
134
|
+
- lib/urlscan/clients/pro.rb
|
|
135
|
+
- lib/urlscan/commands/base.rb
|
|
136
|
+
- lib/urlscan/commands/community.rb
|
|
137
|
+
- lib/urlscan/commands/pro.rb
|
|
146
138
|
- lib/urlscan/exceptions.rb
|
|
147
139
|
- lib/urlscan/version.rb
|
|
148
140
|
- urlscan.gemspec
|