urlscan 0.2.1 → 0.6.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/.travis.yml +2 -5
 - data/README.md +41 -22
 - data/lib/urlscan.rb +11 -1
 - data/lib/urlscan/api.rb +6 -90
 - data/lib/urlscan/cli.rb +3 -55
 - data/lib/urlscan/clients/base.rb +85 -0
 - data/lib/urlscan/clients/community.rb +33 -0
 - data/lib/urlscan/clients/pro.rb +50 -0
 - data/lib/urlscan/commands/base.rb +26 -0
 - data/lib/urlscan/commands/community.rb +50 -0
 - data/lib/urlscan/commands/pro.rb +18 -0
 - data/lib/urlscan/version.rb +1 -1
 - data/renovate.json +5 -0
 - data/urlscan.gemspec +6 -7
 - metadata +26 -33
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 8640ef2ba0a9b73834a5e8999d78223b363fe04643cfcea98a63a8172b486783
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 2957bc3cd06d005275d8179aaaa8faf5a060993aa2c5c41cf261bc28769ed1af
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e882180e835209a6873b0c5032b8587ff2f225760cab8223364e72f7cb914d36f9f99dc9fc9537321ee644371fc0f125824cba4bd720730a5d043b9a0bf58f66
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: be54b70647a26856bdccc0c3e8a0c9abf955186c52e49c284e6e4ed98e499ed87f1629536129227bd0aeac9f9af28fa0fcde897c6fffdfeb50c53ffe89d5b954
         
     | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,12 +1,13 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #  
     | 
| 
      
 1 
     | 
    
         
            +
            # urlscan
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            [](https://badge.fury.io/rb/urlscan)
         
     | 
| 
      
 4 
     | 
    
         
            +
            [](https://travis-ci.com/ninoseki/urlscan)
         
     | 
| 
       4 
5 
     | 
    
         
             
            [](https://codeclimate.com/github/ninoseki/urlscan/maintainability)
         
     | 
| 
       5 
6 
     | 
    
         
             
            [](https://coveralls.io/github/ninoseki/urlscan?branch=master)
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
8 
     | 
    
         
             
            ## Description
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
            [urlscan.io](https://urlscan.io/) API wrapper for Ruby.
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
            ## Installation
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
         @@ -17,7 +18,7 @@ gem install urlscan 
     | 
|
| 
       17 
18 
     | 
    
         
             
            ## API usage
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
       19 
20 
     | 
    
         
             
            ```ruby
         
     | 
| 
       20 
     | 
    
         
            -
            require  
     | 
| 
      
 21 
     | 
    
         
            +
            require "urlscan"
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
            # when given nothing, it tries to load your API key from ENV["URLSCAN_API_KEY"]
         
     | 
| 
       23 
24 
     | 
    
         
             
            api = UrlScan::API.new
         
     | 
| 
         @@ -26,44 +27,62 @@ api = UrlScan::API.new(api_key) 
     | 
|
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
            # Submit a URL to scan
         
     | 
| 
       28 
29 
     | 
    
         
             
            res = api.submit("https://wikipedia.org")
         
     | 
| 
       29 
     | 
    
         
            -
            puts res["result"] # => "https://urlscan.io/result/ac04bc14-4efe-439d-b356-8384843daf75/"
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            # Get a scan result
         
     | 
| 
       32 
32 
     | 
    
         
             
            res = api.result("ac04bc14-4efe-439d-b356-8384843daf75")
         
     | 
| 
       33 
     | 
    
         
            -
            p res # => See the following URL as an example of the response.
         
     | 
| 
       34 
     | 
    
         
            -
                  #    https://gist.github.com/ninoseki/a974d7e95629813615b380c30e737825#file-result-json
         
     | 
| 
       35 
33 
     | 
    
         | 
| 
       36 
34 
     | 
    
         
             
            # Get a DOM
         
     | 
| 
       37 
35 
     | 
    
         
             
            res = api.dom("ac04bc14-4efe-439d-b356-8384843daf75")
         
     | 
| 
       38 
     | 
    
         
            -
            p res
         
     | 
| 
       39 
36 
     | 
    
         | 
| 
       40 
37 
     | 
    
         
             
            # Search
         
     | 
| 
       41 
38 
     | 
    
         
             
            res = api.search("wikipedia.org")
         
     | 
| 
       42 
     | 
    
         
            -
            p res  # => See the following URL as an example of the reponse.
         
     | 
| 
       43 
     | 
    
         
            -
                   #    https://gist.github.com/ninoseki/a974d7e95629813615b380c30e737825#file-search-json
         
     | 
| 
       44 
39 
     | 
    
         
             
            ```
         
     | 
| 
       45 
40 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 41 
     | 
    
         
            +
            ## Supported API endpoints
         
     | 
| 
       47 
42 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
            | HTTP Method | URI 
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
            | POST        | /scan 
     | 
| 
       51 
     | 
    
         
            -
            | GET         | /result 
     | 
| 
       52 
     | 
    
         
            -
            | GET         | /dom 
     | 
| 
       53 
     | 
    
         
            -
            | GET         | / 
     | 
| 
      
 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, search_after: nil)` |
         
     | 
| 
      
 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`                                      |
         
     | 
| 
      
 58 
     | 
    
         
            +
            | GET         | /phishfeed              | `UrlScan::Clients::Pro#phishfeed`                                 |
         
     | 
| 
      
 59 
     | 
    
         
            +
            | GET         | /result/`uuid`/similar/ | `UrlScan::Clients::Pro#similar(uuid)`                             |
         
     | 
| 
       54 
60 
     | 
    
         | 
| 
       55 
61 
     | 
    
         
             
            ## CLI usage
         
     | 
| 
       56 
62 
     | 
    
         | 
| 
       57 
63 
     | 
    
         
             
            ```bash
         
     | 
| 
       58 
64 
     | 
    
         
             
            $ urlscan
         
     | 
| 
       59 
65 
     | 
    
         
             
            Commands:
         
     | 
| 
       60 
     | 
    
         
            -
              urlscan dom [UUID] 
     | 
| 
       61 
     | 
    
         
            -
              urlscan help [COMMAND] 
     | 
| 
       62 
     | 
    
         
            -
              urlscan result [UUID] 
     | 
| 
       63 
     | 
    
         
            -
              urlscan  
     | 
| 
       64 
     | 
    
         
            -
              urlscan  
     | 
| 
      
 66 
     | 
    
         
            +
              urlscan dom [UUID]         # get the DOM of a scan using the scan id [UUID]
         
     | 
| 
      
 67 
     | 
    
         
            +
              urlscan help [COMMAND]     # Describe available commands or one specific command
         
     | 
| 
      
 68 
     | 
    
         
            +
              urlscan result [UUID]      # get the result of a scan using the scan id [UUID]
         
     | 
| 
      
 69 
     | 
    
         
            +
              urlscan screenshot [UUID]  # get the screenshot(image/png) of a scan using the scan id [UUID]
         
     | 
| 
      
 70 
     | 
    
         
            +
              urlscan search [QUERY]     # search for scans by [QUERY]
         
     | 
| 
      
 71 
     | 
    
         
            +
              urlscan submit [URL]       # submit a scan to [URL]
         
     | 
| 
       65 
72 
     | 
    
         | 
| 
       66 
73 
     | 
    
         
             
            Options:
         
     | 
| 
       67 
74 
     | 
    
         
             
              [--API-KEY=API_KEY]
         
     | 
| 
       68 
75 
     | 
    
         | 
| 
       69 
76 
     | 
    
         
             
            ```
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            ### Pro
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 81 
     | 
    
         
            +
            $ urlscan pro
         
     | 
| 
      
 82 
     | 
    
         
            +
            Commands:
         
     | 
| 
      
 83 
     | 
    
         
            +
              urlscan pro help [COMMAND]  # Describe subcommands or one specific subcommand
         
     | 
| 
      
 84 
     | 
    
         
            +
              urlscan pro search          # search for scans
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            Options:
         
     | 
| 
      
 87 
     | 
    
         
            +
              [--API-KEY=API_KEY]
         
     | 
| 
      
 88 
     | 
    
         
            +
            ```
         
     | 
    
        data/lib/urlscan.rb
    CHANGED
    
    | 
         @@ -1,5 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require "urlscan/version"
         
     | 
| 
      
 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 
     | 
    
         
            +
             
     | 
| 
       3 
14 
     | 
    
         
             
            require "urlscan/api"
         
     | 
| 
       4 
15 
     | 
    
         
             
            require "urlscan/cli"
         
     | 
| 
       5 
     | 
    
         
            -
            require "urlscan/version"
         
     | 
    
        data/lib/urlscan/api.rb
    CHANGED
    
    | 
         @@ -1,102 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
            require 'json'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            require 'urlscan/exceptions'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "forwardable"
         
     | 
| 
       7 
4 
     | 
    
         | 
| 
       8 
5 
     | 
    
         
             
            module UrlScan
         
     | 
| 
       9 
6 
     | 
    
         
             
              class API
         
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
                HOST = "urlscan.io"
         
     | 
| 
       12 
     | 
    
         
            -
                URL = "https://#{HOST}/api/v#{VERSION}"
         
     | 
| 
      
 7 
     | 
    
         
            +
                extend Forwardable
         
     | 
| 
       13 
8 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                attr_reader : 
     | 
| 
      
 9 
     | 
    
         
            +
                attr_reader :pro
         
     | 
| 
       15 
10 
     | 
    
         | 
| 
       16 
11 
     | 
    
         
             
                def initialize(key = ENV["URLSCAN_API_KEY"])
         
     | 
| 
       17 
     | 
    
         
            -
                  @ 
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                # @return [Hash]
         
     | 
| 
       21 
     | 
    
         
            -
                def submit(url, is_public = true)
         
     | 
| 
       22 
     | 
    
         
            -
                  raise ArgumentError, "API key is required for this method." if key.nil?
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                  params = { url: url, public: is_public ? "on" : "off" }
         
     | 
| 
       25 
     | 
    
         
            -
                  post("/scan/", params) { |json| json }
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                # @return [Hash]
         
     | 
| 
       29 
     | 
    
         
            -
                def result(uuid)
         
     | 
| 
       30 
     | 
    
         
            -
                  get("/result/#{uuid}") { |json| json }
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                # @return [String]
         
     | 
| 
       34 
     | 
    
         
            -
                def dom(uuid)
         
     | 
| 
       35 
     | 
    
         
            -
                  get("/dom/#{uuid}/") { |dom| dom }
         
     | 
| 
       36 
     | 
    
         
            -
                end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                # @return [Hash]
         
     | 
| 
       39 
     | 
    
         
            -
                def search(q, size = 100, offset = 0, sort = "_score")
         
     | 
| 
       40 
     | 
    
         
            -
                  params = { q: q, size: size, offset: offset, sort: sort }
         
     | 
| 
       41 
     | 
    
         
            -
                  query = URI.encode_www_form(params)
         
     | 
| 
       42 
     | 
    
         
            -
                  get("/search/?#{query}") { |json| json }
         
     | 
| 
       43 
     | 
    
         
            -
                end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                def url_for(path)
         
     | 
| 
       46 
     | 
    
         
            -
                  URI(URL + path)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @community = Clients::Community.new(key)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @pro = Clients::Pro.new(key)
         
     | 
| 
       47 
14 
     | 
    
         
             
                end
         
     | 
| 
       48 
15 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                 
     | 
| 
       50 
     | 
    
         
            -
                  if proxy = ENV["HTTPS_PROXY"]
         
     | 
| 
       51 
     | 
    
         
            -
                    uri = URI(proxy)
         
     | 
| 
       52 
     | 
    
         
            -
                    {
         
     | 
| 
       53 
     | 
    
         
            -
                      proxy_address: uri.hostname,
         
     | 
| 
       54 
     | 
    
         
            -
                      proxy_port: uri.port,
         
     | 
| 
       55 
     | 
    
         
            -
                      proxy_from_env: false,
         
     | 
| 
       56 
     | 
    
         
            -
                      use_ssl: true
         
     | 
| 
       57 
     | 
    
         
            -
                    }
         
     | 
| 
       58 
     | 
    
         
            -
                  else
         
     | 
| 
       59 
     | 
    
         
            -
                    { use_ssl: true }
         
     | 
| 
       60 
     | 
    
         
            -
                  end
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                def request(req)
         
     | 
| 
       64 
     | 
    
         
            -
                  Net::HTTP.start(HOST, 443, https_options) do |http|
         
     | 
| 
       65 
     | 
    
         
            -
                    response = http.request(req)
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                    case response.code
         
     | 
| 
       68 
     | 
    
         
            -
                    when '200'
         
     | 
| 
       69 
     | 
    
         
            -
                      if response["Content-Type"].to_s.include? "application/json"
         
     | 
| 
       70 
     | 
    
         
            -
                        yield JSON.parse(response.body)
         
     | 
| 
       71 
     | 
    
         
            -
                      else
         
     | 
| 
       72 
     | 
    
         
            -
                        yield response.body
         
     | 
| 
       73 
     | 
    
         
            -
                      end
         
     | 
| 
       74 
     | 
    
         
            -
                    when '400' then raise ProcessingError, response.body
         
     | 
| 
       75 
     | 
    
         
            -
                    when '401' then raise AuthenticationError, response.body
         
     | 
| 
       76 
     | 
    
         
            -
                    when '404' then raise NotFound, response.body
         
     | 
| 
       77 
     | 
    
         
            -
                    when '429' then raise RateLimited, response.body
         
     | 
| 
       78 
     | 
    
         
            -
                    when '500' then raise InternalServerError, response.body
         
     | 
| 
       79 
     | 
    
         
            -
                    else
         
     | 
| 
       80 
     | 
    
         
            -
                      raise ResponseError, response.body
         
     | 
| 
       81 
     | 
    
         
            -
                    end
         
     | 
| 
       82 
     | 
    
         
            -
                  end
         
     | 
| 
       83 
     | 
    
         
            -
                end
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                def auth_header
         
     | 
| 
       86 
     | 
    
         
            -
                  { "API-KEY": key }
         
     | 
| 
       87 
     | 
    
         
            -
                end
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                def get(path, &block)
         
     | 
| 
       90 
     | 
    
         
            -
                  get = Net::HTTP::Get.new(url_for(path))
         
     | 
| 
       91 
     | 
    
         
            -
                  request(get, &block)
         
     | 
| 
       92 
     | 
    
         
            -
                end
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
                def post(path, json, &block)
         
     | 
| 
       95 
     | 
    
         
            -
                  post = Net::HTTP::Post.new(url_for(path), auth_header)
         
     | 
| 
       96 
     | 
    
         
            -
                  post.content_type = 'application/json'
         
     | 
| 
       97 
     | 
    
         
            -
                  post.body = json.to_json
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
                  request(post, &block)
         
     | 
| 
       100 
     | 
    
         
            -
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                def_delegators :@community, :submit, :result, :dom, :screenshot, :search
         
     | 
| 
       101 
17 
     | 
    
         
             
              end
         
     | 
| 
       102 
18 
     | 
    
         
             
            end
         
     | 
    
        data/lib/urlscan/cli.rb
    CHANGED
    
    | 
         @@ -1,60 +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 [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, options[:size], options[:offset], 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 [UUID]"
         
     | 
| 
       39 
     | 
    
         
            -
                def dom(uuid)
         
     | 
| 
       40 
     | 
    
         
            -
                  with_error_handling do
         
     | 
| 
       41 
     | 
    
         
            -
                    res = api.dom(uuid)
         
     | 
| 
       42 
     | 
    
         
            -
                    puts res
         
     | 
| 
       43 
     | 
    
         
            -
                  end
         
     | 
| 
       44 
     | 
    
         
            -
                end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                no_commands do
         
     | 
| 
       47 
     | 
    
         
            -
                  def api
         
     | 
| 
       48 
     | 
    
         
            -
                    options[:API_KEY] ? API.new(options[:API_KEY]) : API.new
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  def with_error_handling
         
     | 
| 
       52 
     | 
    
         
            -
                    yield
         
     | 
| 
       53 
     | 
    
         
            -
                  rescue ArgumentError => _e
         
     | 
| 
       54 
     | 
    
         
            -
                    puts "Warning: please specify your urlscan.io API key via ENV['URLSCAN_API_KEY] or --API-KEY"
         
     | 
| 
       55 
     | 
    
         
            -
                  rescue ResponseError => _e
         
     | 
| 
       56 
     | 
    
         
            -
                    puts "Warning: #{_e}"
         
     | 
| 
       57 
     | 
    
         
            -
                  end
         
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
      
 4 
     | 
    
         
            +
              class CLI < Commands::Community
         
     | 
| 
      
 5 
     | 
    
         
            +
                desc "pro", "PRO api commands"
         
     | 
| 
      
 6 
     | 
    
         
            +
                subcommand "pro", Commands::Pro
         
     | 
| 
       59 
7 
     | 
    
         
             
              end
         
     | 
| 
       60 
8 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 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://#{HOST}/api/v#{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 default_headers
         
     | 
| 
      
 65 
     | 
    
         
            +
                    @default_headers ||= { "API-KEY": key }.compact
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  def get(path, params = {}, &block)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    uri = url_for(path)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    uri.query = URI.encode_www_form(params)
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                    get = Net::HTTP::Get.new(uri, default_headers)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    request(get, &block)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def post(path, json, &block)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    post = Net::HTTP::Post.new(url_for(path), default_headers)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    post.content_type = "application/json"
         
     | 
| 
      
 79 
     | 
    
         
            +
                    post.body = json.to_json
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    request(post, &block)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
                    params = { url: url, public: is_public ? "on" : "off" }
         
     | 
| 
      
 9 
     | 
    
         
            +
                    post("/scan/", params) { |json| json }
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  def result(uuid)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    get("/result/#{uuid}") { |json| json }
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def dom(uuid)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    get("/dom/#{uuid}/") { |dom| dom }
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def screenshot(uuid)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    get("/screenshots/#{uuid}.png") { |png| png }
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def search(q, size: 100, search_after: nil)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    params = { q: q, size: size, search_after: search_after }.compact
         
     | 
| 
      
 29 
     | 
    
         
            +
                    get("/search/", params) { |json| json }
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def search(query: nil, filter: nil, size: 50)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    filter = build_filter(filter)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    params = { q: query, size: size, filter: filter }.compact
         
     | 
| 
      
 13 
     | 
    
         
            +
                    get("/search", params) { |json| json }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def brands
         
     | 
| 
      
 18 
     | 
    
         
            +
                    get("/brands") { |json| json }
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def kits
         
     | 
| 
      
 23 
     | 
    
         
            +
                    get("/kits") { |json| json }
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def phishfeed(q: "result.task.time:>now-24h", format: "json")
         
     | 
| 
      
 28 
     | 
    
         
            +
                    params = { q: q, format: format }
         
     | 
| 
      
 29 
     | 
    
         
            +
                    get("/phishfeed", params) { |json| json }
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 33 
     | 
    
         
            +
                  def similar(uuid)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    get("/result/#{uuid}/similar") { |json| json }
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  private
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def build_filter(filter)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    return nil unless filter
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    filter.start_with?("$") ? filter : "$#{filter}"
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def url
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @url ||= "https://#{HOST}/api/v#{VERSION}/pro"
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            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,50 @@ 
     | 
|
| 
      
 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 :search_after, type: :string
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def search(query)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    with_error_handling do
         
     | 
| 
      
 28 
     | 
    
         
            +
                      res = api.search(query, size: options["size"], search_after: options["search_after"])
         
     | 
| 
      
 29 
     | 
    
         
            +
                      puts JSON.pretty_generate(res)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  desc "dom [UUID]", "get the DOM of a scan using the scan id [UUID]"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def dom(uuid)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    with_error_handling do
         
     | 
| 
      
 36 
     | 
    
         
            +
                      res = api.dom(uuid)
         
     | 
| 
      
 37 
     | 
    
         
            +
                      puts res
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  desc "screenshot [UUID]", "get the screenshot(image/png) of a scan using the scan id [UUID]"
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def screenshot(uuid)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    with_error_handling do
         
     | 
| 
      
 44 
     | 
    
         
            +
                      res = api.screenshot(uuid)
         
     | 
| 
      
 45 
     | 
    
         
            +
                      puts res
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            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
    
    | 
         @@ -21,13 +21,12 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       21 
21 
     | 
    
         
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         
     | 
| 
       22 
22 
     | 
    
         
             
              spec.require_paths = ["lib"]
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
              spec.add_development_dependency "bundler", "~> 2. 
     | 
| 
      
 24 
     | 
    
         
            +
              spec.add_development_dependency "bundler", "~> 2.1"
         
     | 
| 
       25 
25 
     | 
    
         
             
              spec.add_development_dependency "coveralls", "~> 0.8"
         
     | 
| 
       26 
     | 
    
         
            -
              spec.add_development_dependency " 
     | 
| 
       27 
     | 
    
         
            -
              spec.add_development_dependency " 
     | 
| 
       28 
     | 
    
         
            -
              spec.add_development_dependency " 
     | 
| 
       29 
     | 
    
         
            -
              spec.add_development_dependency " 
     | 
| 
       30 
     | 
    
         
            -
              spec.add_development_dependency "webmock", "~> 3.6"
         
     | 
| 
      
 26 
     | 
    
         
            +
              spec.add_development_dependency "rake", "~> 13.0"
         
     | 
| 
      
 27 
     | 
    
         
            +
              spec.add_development_dependency "rspec", "~> 3.9"
         
     | 
| 
      
 28 
     | 
    
         
            +
              spec.add_development_dependency "vcr", "~> 6.0"
         
     | 
| 
      
 29 
     | 
    
         
            +
              spec.add_development_dependency "webmock", "~> 3.8"
         
     | 
| 
       31 
30 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
              spec.add_runtime_dependency "thor", "~> 0 
     | 
| 
      
 31 
     | 
    
         
            +
              spec.add_runtime_dependency "thor", "~> 1.0"
         
     | 
| 
       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.6.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Manabu Niseki
         
     | 
| 
       8 
     | 
    
         
            -
            autorequire: 
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-08-16 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: bundler
         
     | 
| 
         @@ -16,14 +16,14 @@ dependencies: 
     | 
|
| 
       16 
16 
     | 
    
         
             
                requirements:
         
     | 
| 
       17 
17 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       18 
18 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       19 
     | 
    
         
            -
                    version: '2. 
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '2.1'
         
     | 
| 
       20 
20 
     | 
    
         
             
              type: :development
         
     | 
| 
       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: '2. 
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '2.1'
         
     | 
| 
       27 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       28 
28 
     | 
    
         
             
              name: coveralls
         
     | 
| 
       29 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -38,91 +38,77 @@ 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
         
     | 
| 
       58 
44 
     | 
    
         
             
                requirements:
         
     | 
| 
       59 
45 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       60 
46 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       61 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '13.0'
         
     | 
| 
       62 
48 
     | 
    
         
             
              type: :development
         
     | 
| 
       63 
49 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       64 
50 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       65 
51 
     | 
    
         
             
                requirements:
         
     | 
| 
       66 
52 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       67 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       68 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '13.0'
         
     | 
| 
       69 
55 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       70 
56 
     | 
    
         
             
              name: rspec
         
     | 
| 
       71 
57 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       72 
58 
     | 
    
         
             
                requirements:
         
     | 
| 
       73 
59 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       74 
60 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       75 
     | 
    
         
            -
                    version: '3. 
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '3.9'
         
     | 
| 
       76 
62 
     | 
    
         
             
              type: :development
         
     | 
| 
       77 
63 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       78 
64 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       79 
65 
     | 
    
         
             
                requirements:
         
     | 
| 
       80 
66 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       81 
67 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       82 
     | 
    
         
            -
                    version: '3. 
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '3.9'
         
     | 
| 
       83 
69 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       84 
70 
     | 
    
         
             
              name: vcr
         
     | 
| 
       85 
71 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       86 
72 
     | 
    
         
             
                requirements:
         
     | 
| 
       87 
73 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       88 
74 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       89 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '6.0'
         
     | 
| 
       90 
76 
     | 
    
         
             
              type: :development
         
     | 
| 
       91 
77 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       92 
78 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       93 
79 
     | 
    
         
             
                requirements:
         
     | 
| 
       94 
80 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       95 
81 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       96 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '6.0'
         
     | 
| 
       97 
83 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       98 
84 
     | 
    
         
             
              name: webmock
         
     | 
| 
       99 
85 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       100 
86 
     | 
    
         
             
                requirements:
         
     | 
| 
       101 
87 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       102 
88 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       103 
     | 
    
         
            -
                    version: '3. 
     | 
| 
      
 89 
     | 
    
         
            +
                    version: '3.8'
         
     | 
| 
       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.8'
         
     | 
| 
       111 
97 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       112 
98 
     | 
    
         
             
              name: thor
         
     | 
| 
       113 
99 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       114 
100 
     | 
    
         
             
                requirements:
         
     | 
| 
       115 
101 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       116 
102 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       117 
     | 
    
         
            -
                    version: '0 
     | 
| 
      
 103 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
       118 
104 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       119 
105 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       120 
106 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       121 
107 
     | 
    
         
             
                requirements:
         
     | 
| 
       122 
108 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       123 
109 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       124 
     | 
    
         
            -
                    version: '0 
     | 
| 
       125 
     | 
    
         
            -
            description: 
     | 
| 
      
 110 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 111 
     | 
    
         
            +
            description:
         
     | 
| 
       126 
112 
     | 
    
         
             
            email:
         
     | 
| 
       127 
113 
     | 
    
         
             
            - manabu.niseki@gmail.com
         
     | 
| 
       128 
114 
     | 
    
         
             
            executables:
         
     | 
| 
         @@ -143,14 +129,21 @@ 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
         
     | 
| 
      
 140 
     | 
    
         
            +
            - renovate.json
         
     | 
| 
       148 
141 
     | 
    
         
             
            - urlscan.gemspec
         
     | 
| 
       149 
142 
     | 
    
         
             
            homepage: https://github.com/ninoseki/urlscan
         
     | 
| 
       150 
143 
     | 
    
         
             
            licenses:
         
     | 
| 
       151 
144 
     | 
    
         
             
            - MIT
         
     | 
| 
       152 
145 
     | 
    
         
             
            metadata: {}
         
     | 
| 
       153 
     | 
    
         
            -
            post_install_message: 
     | 
| 
      
 146 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
       154 
147 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       155 
148 
     | 
    
         
             
            require_paths:
         
     | 
| 
       156 
149 
     | 
    
         
             
            - lib
         
     | 
| 
         @@ -165,8 +158,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       165 
158 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       166 
159 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       167 
160 
     | 
    
         
             
            requirements: []
         
     | 
| 
       168 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
       169 
     | 
    
         
            -
            signing_key: 
     | 
| 
      
 161 
     | 
    
         
            +
            rubygems_version: 3.1.2
         
     | 
| 
      
 162 
     | 
    
         
            +
            signing_key:
         
     | 
| 
       170 
163 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       171 
164 
     | 
    
         
             
            summary: Ruby API client for urlscan.io
         
     | 
| 
       172 
165 
     | 
    
         
             
            test_files: []
         
     |