vulndbhq 0.0.1.beta
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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +16 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +64 -0
- data/Rakefile +8 -0
- data/lib/vulndbhq.rb +36 -0
- data/lib/vulndbhq/base.rb +95 -0
- data/lib/vulndbhq/client.rb +130 -0
- data/lib/vulndbhq/configurable.rb +29 -0
- data/lib/vulndbhq/default.rb +51 -0
- data/lib/vulndbhq/identity_map.rb +10 -0
- data/lib/vulndbhq/private_page.rb +5 -0
- data/lib/vulndbhq/response/parse_json.rb +26 -0
- data/lib/vulndbhq/version.rb +15 -0
- data/spec/faraday_spec.rb +25 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/webmock.rb +5 -0
- data/spec/vulndbhq/base_spec.rb +49 -0
- data/spec/vulndbhq/client_spec.rb +13 -0
- data/spec/vulndbhq/private_page_spec.rb +20 -0
- data/spec/vulndbhq_spec.rb +36 -0
- data/vulndbhq.gemspec +24 -0
- metadata +159 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Daniel Martin, Security Roots Ltd.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# VulnDB HQ Ruby Gem [][travis] [][gemnasium]
|
2
|
+
|
3
|
+
This gem provides a Ruby wrapper to the VulnDB HQ API (http://vulndbhq.com).
|
4
|
+
|
5
|
+
[travis]: http://travis-ci.org/securityroots/vulndbhq
|
6
|
+
[gemnasium]: https://gemnasium.com/securityroots/vulndbhq
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
DANGER, WILL ROBINSON!
|
11
|
+
DANGER, WILL ROBINSON!
|
12
|
+
DANGER, WILL ROBINSON!
|
13
|
+
THIS GEM IS IN EARLY BETA STAGE. EVERYTHING CAN CHANGE AT ANY POINT!!
|
14
|
+
|
15
|
+
THIS GEM USES API v2 WHICH WILL BE AVAILABLE SOON
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
gem 'vulndbhq'
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install vulndbhq
|
28
|
+
|
29
|
+
|
30
|
+
## Configuration
|
31
|
+
|
32
|
+
To provide your access credentials:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'vulndbhq'
|
36
|
+
|
37
|
+
client = VulnDBHQ::client
|
38
|
+
client.host = 'https://you.vulndbhq.com'
|
39
|
+
client.user = 'your@email.com'
|
40
|
+
client.password = 'password'
|
41
|
+
```
|
42
|
+
|
43
|
+
## Usage examples
|
44
|
+
|
45
|
+
Return the first PrivatePage:
|
46
|
+
|
47
|
+
VulnDBHQ.private_pages
|
48
|
+
|
49
|
+
Get a PrivatePage by id:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
private_page = client.private_page(1)
|
53
|
+
|
54
|
+
puts private_page.name
|
55
|
+
puts private_page.content
|
56
|
+
```
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
|
60
|
+
1. Fork it
|
61
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
63
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/vulndbhq.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'vulndbhq/client'
|
2
|
+
|
3
|
+
module VulnDBHQ
|
4
|
+
class << self
|
5
|
+
|
6
|
+
include VulnDBHQ::Configurable
|
7
|
+
|
8
|
+
def client
|
9
|
+
VulnDBHQ::Client.new(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Delegate to a VulnDBHQ::Client
|
13
|
+
def respond_to?(method, include_private=false)
|
14
|
+
self.client.respond_to?(method, include_private) || super
|
15
|
+
end
|
16
|
+
|
17
|
+
def options
|
18
|
+
@options = {}
|
19
|
+
VulnDBHQ::Configurable.keys.each do |key|
|
20
|
+
@options[key] = instance_variable_get("@#{key}")
|
21
|
+
end
|
22
|
+
@options
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset!
|
26
|
+
VulnDBHQ::Configurable.keys.each do |key|
|
27
|
+
instance_variable_set("@#{key}", VulnDBHQ::Default.options[key])
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
alias setup reset!
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
VulnDBHQ.setup
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'vulndbhq/identity_map'
|
2
|
+
|
3
|
+
module VulnDBHQ
|
4
|
+
class Base
|
5
|
+
attr_reader :attrs
|
6
|
+
alias to_hash attrs
|
7
|
+
|
8
|
+
@@identity_map = IdentityMap.new
|
9
|
+
|
10
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
11
|
+
#
|
12
|
+
# @overload self. attr_reader(attr)
|
13
|
+
# @param attr [Symbol]
|
14
|
+
# @overload self. attr_reader(attrs)
|
15
|
+
# @param attrs [Array<Symbol>]
|
16
|
+
def self.attr_reader(*attrs)
|
17
|
+
attrs.each do |attribute|
|
18
|
+
class_eval do
|
19
|
+
define_method attribute do
|
20
|
+
@attrs[attribute.to_sym]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Initializes a new object
|
27
|
+
#
|
28
|
+
# @param attrs [Hash]
|
29
|
+
# @return [VulnDBHQ::Base]
|
30
|
+
def initialize(attrs={})
|
31
|
+
self.update(attrs)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Update the attributes of an object
|
35
|
+
#
|
36
|
+
# @param attrs [Hash]
|
37
|
+
# @return [VulnDBHQ::Base]
|
38
|
+
def update(attrs)
|
39
|
+
@attrs ||= {}
|
40
|
+
@attrs.update(attrs)
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creates a new object and stores it in the identity map.
|
45
|
+
#
|
46
|
+
# @param attrs [Hash]
|
47
|
+
# @return [VulnDBHQ::Base]
|
48
|
+
def self.create(attrs={})
|
49
|
+
object = self.new(attrs)
|
50
|
+
self.store(object)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Retrieves an object from the identity map.
|
54
|
+
#
|
55
|
+
# @param attrs [Hash]
|
56
|
+
# @return [VulnDBHQ::Base]
|
57
|
+
def self.fetch(attrs)
|
58
|
+
@@identity_map[self] ||= {}
|
59
|
+
if object = @@identity_map[self][Marshal.dump(attrs)]
|
60
|
+
return object
|
61
|
+
end
|
62
|
+
|
63
|
+
return yield if block_given?
|
64
|
+
raise VulnDBHQ::IdentityMapKeyError, 'key not found'
|
65
|
+
end
|
66
|
+
|
67
|
+
# Stores an object in the identity map.
|
68
|
+
#
|
69
|
+
# @param attrs [Hash]
|
70
|
+
# @return [VulnDBHQ::Base]
|
71
|
+
def self.store(object)
|
72
|
+
@@identity_map[self] ||= {}
|
73
|
+
@@identity_map[self][Marshal.dump(object.attrs)] = object
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns a new object based on the response hash
|
77
|
+
#
|
78
|
+
# @param attrs [Hash]
|
79
|
+
# @return [VulnDBHQ::Base]
|
80
|
+
def self.from_response(response={})
|
81
|
+
self.fetch_or_create(response[:body])
|
82
|
+
end
|
83
|
+
|
84
|
+
# Retrieves an object from the identity map, or stores it in the
|
85
|
+
# identity map if it doesn't already exist.
|
86
|
+
#
|
87
|
+
# @param attrs [Hash]
|
88
|
+
# @return [VulnDBHQ::Base]
|
89
|
+
def self.fetch_or_create(attrs={})
|
90
|
+
self.fetch(attrs) do
|
91
|
+
self.create(attrs)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
require 'vulndbhq/base'
|
5
|
+
require 'vulndbhq/configurable'
|
6
|
+
require 'vulndbhq/default'
|
7
|
+
require 'vulndbhq/private_page'
|
8
|
+
require 'vulndbhq/response/parse_json'
|
9
|
+
require 'vulndbhq/version'
|
10
|
+
|
11
|
+
module VulnDBHQ
|
12
|
+
# Wrapper for the VulnDB HQ REST API
|
13
|
+
#
|
14
|
+
# @note All methods have been separated into modules as described in the API docs
|
15
|
+
# @see http://support.securityroots.com
|
16
|
+
class Client
|
17
|
+
include VulnDBHQ::Configurable
|
18
|
+
|
19
|
+
# Initializes a new Client object
|
20
|
+
#
|
21
|
+
# @param options [Hash]
|
22
|
+
# @return [VulnDBHQ::Client]
|
23
|
+
def initialize(options={})
|
24
|
+
VulnDBHQ::Configurable.keys.each do |key|
|
25
|
+
instance_variable_set("@#{key}", options[key] || VulnDBHQ.options[key])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a private page
|
30
|
+
#
|
31
|
+
# @see http://support.securityroots.com/vulndbhq_api_v2.html#model-private-page
|
32
|
+
|
33
|
+
# @authentication_required Yes
|
34
|
+
# @raise [VulnDBHQ::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
35
|
+
# @return [VulnDBHQ::PrivatePage] The requested messages.
|
36
|
+
# @param id [Integer] A VulnDB HQ private page ID.
|
37
|
+
# @param options [Hash] A customizable set of options.
|
38
|
+
# @example Return the private page with the id 87
|
39
|
+
# VulnDBHQ.private_page(87)
|
40
|
+
def private_page(id, options={})
|
41
|
+
response = get("/api/private_pages/#{id}", options)
|
42
|
+
VulnDBHQ::PrivatePage.from_response(response)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the collection of VulnDBHQ::PrivatePage for the account
|
46
|
+
#
|
47
|
+
# @see http://support.securityroots.com/vulndbhq_api_v2.html#model-private-page
|
48
|
+
# @authentication_required Yes
|
49
|
+
# @raise [VulnDBHQ::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
50
|
+
# @return [Array<VulnDBHQ::PrivatePage>] PrivatePages in the account associated with this user.
|
51
|
+
# @param options [Hash] A customizable set of options.
|
52
|
+
# @option options [nil] no options are supported yet.
|
53
|
+
# @example Return the private pages for the account
|
54
|
+
# VulnDBHQ.private_pages
|
55
|
+
def private_pages(options={})
|
56
|
+
response = get("/api/private_pages", options)
|
57
|
+
# collection_from_array(response[:body], VulnDBHQ::PrivatePage)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Perform an HTTP GET request
|
61
|
+
def get(path, params={}, options={})
|
62
|
+
request(:get, path, params, options)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Check whether credentials are present
|
66
|
+
#
|
67
|
+
# @return [Boolean]
|
68
|
+
def credentials?
|
69
|
+
credentials.values.all?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def collection_from_array(array, klass)
|
75
|
+
array.map do |element|
|
76
|
+
klass.fetch_or_create(element)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns a Faraday::Connection object
|
81
|
+
#
|
82
|
+
# @return [Faraday::Connection]
|
83
|
+
def connection
|
84
|
+
@connection ||= Faraday.new(@host, @connection_options.merge(:builder => @middleware))
|
85
|
+
end
|
86
|
+
|
87
|
+
# Perform an HTTP request
|
88
|
+
def request(method, path, params, options)
|
89
|
+
uri = options[:host] || @host
|
90
|
+
uri = URI(uri) unless uri.respond_to?(:host)
|
91
|
+
uri += path
|
92
|
+
request_headers = {}
|
93
|
+
if self.credentials?
|
94
|
+
# When posting a file, don't sign any params
|
95
|
+
# signature_params = if [:post, :put].include?(method.to_sym) && params.values.any?{|value| value.is_a?(File) || (value.is_a?(Hash) && (value[:io].is_a?(IO) || value[:io].is_a?(StringIO)))}
|
96
|
+
# {}
|
97
|
+
# else
|
98
|
+
# params
|
99
|
+
# end
|
100
|
+
# authorization = SimpleOAuth::Header.new(method, uri, signature_params, credentials)
|
101
|
+
# request_headers[:authorization] = authorization.to_s
|
102
|
+
connection.basic_auth(credentials[:user], credentials[:password])
|
103
|
+
end
|
104
|
+
connection.url_prefix = options[:host] || @host
|
105
|
+
connection.run_request(method.to_sym, path, nil, request_headers) do |request|
|
106
|
+
unless params.empty?
|
107
|
+
case request.method
|
108
|
+
when :post, :put
|
109
|
+
request.body = params
|
110
|
+
else
|
111
|
+
request.params.update(params)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
yield request if block_given?
|
115
|
+
end.env
|
116
|
+
rescue Faraday::Error::ClientError
|
117
|
+
raise VulnDBHQ::Error::ClientError
|
118
|
+
end
|
119
|
+
|
120
|
+
# Credentials hash
|
121
|
+
#
|
122
|
+
# @return [Hash]
|
123
|
+
def credentials
|
124
|
+
{
|
125
|
+
:user => @user,
|
126
|
+
:password => @password
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module VulnDBHQ
|
2
|
+
# Defines constants and methods related to configuration
|
3
|
+
module Configurable
|
4
|
+
|
5
|
+
# Convenience method to allow configuration options to be set in a block
|
6
|
+
def configure
|
7
|
+
yield self
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
# An array of valid keys in the options hash when configuring a {VulnDBHQ::Client}
|
12
|
+
CONFIG_KEYS = [
|
13
|
+
:connection_options,
|
14
|
+
:host,
|
15
|
+
:middleware
|
16
|
+
]
|
17
|
+
attr_accessor *CONFIG_KEYS
|
18
|
+
|
19
|
+
AUTH_KEYS = [
|
20
|
+
:user,
|
21
|
+
:password
|
22
|
+
]
|
23
|
+
attr_writer *AUTH_KEYS
|
24
|
+
|
25
|
+
def self.keys
|
26
|
+
@keys ||= CONFIG_KEYS + AUTH_KEYS
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module VulnDBHQ
|
2
|
+
module Default
|
3
|
+
|
4
|
+
def self.options
|
5
|
+
Hash[VulnDBHQ::Configurable.keys.map{|key| [key, send(key)]}]
|
6
|
+
end
|
7
|
+
|
8
|
+
# The Faraday connection options if none is set
|
9
|
+
def self.connection_options
|
10
|
+
@connection_options ||= {
|
11
|
+
:headers => {
|
12
|
+
:accept => 'application/vnd.vulndbhq; v=2',
|
13
|
+
:user_agent => "VulnDBHQ Ruby Gem #{VulnDBHQ::Version}"
|
14
|
+
},
|
15
|
+
:open_timeout => 5,
|
16
|
+
:raw => true,
|
17
|
+
:ssl => {:verify => false},
|
18
|
+
:timeout => 10,
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
|
23
|
+
# @see https://github.com/technoweenie/faraday#advanced-middleware-usage
|
24
|
+
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
25
|
+
def self.middleware
|
26
|
+
@middleware ||= Faraday::Builder.new(
|
27
|
+
&Proc.new do |builder|
|
28
|
+
builder.use Faraday::Request::UrlEncoded # Convert request params as "www-form-urlencoded"
|
29
|
+
builder.use VulnDBHQ::Response::ParseJson # Parse JSON response bodies using MultiJson
|
30
|
+
builder.adapter Faraday.default_adapter # Set Faraday's HTTP adapter
|
31
|
+
end
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
# The VulnDB HQ host
|
36
|
+
def self.host
|
37
|
+
ENV['VULNDBHQ_HOST']
|
38
|
+
end
|
39
|
+
|
40
|
+
# The VulnDB HQ user if none is set
|
41
|
+
def self.user
|
42
|
+
ENV['VULNDBHQ_USER']
|
43
|
+
end
|
44
|
+
|
45
|
+
# The VulnDB HQ password if none is set
|
46
|
+
def self.password
|
47
|
+
ENV['VULNDBHQ_PASSWORD']
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module VulnDBHQ
|
2
|
+
# Tracks objects to help ensure that each object gets loaded only once.
|
3
|
+
# See: http://www.martinfowler.com/eaaCatalog/identityMap.html
|
4
|
+
class IdentityMap < Hash
|
5
|
+
end
|
6
|
+
|
7
|
+
# Inherit from KeyError when Ruby 1.8 compatibility is removed
|
8
|
+
class IdentityMapKeyError < ::IndexError
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module VulnDBHQ
|
2
|
+
module Response
|
3
|
+
class ParseJson < Faraday::Response::Middleware
|
4
|
+
|
5
|
+
def parse(body)
|
6
|
+
case body
|
7
|
+
when ''
|
8
|
+
nil
|
9
|
+
when 'true'
|
10
|
+
true
|
11
|
+
when 'false'
|
12
|
+
false
|
13
|
+
else
|
14
|
+
MultiJson.load(body, :symbolize_keys => true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_complete(env)
|
19
|
+
if respond_to?(:parse)
|
20
|
+
env[:body] = parse(env[:body]) unless [204, 304].include?(env[:status])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe 'Faraday response' do
|
2
|
+
|
3
|
+
context "for valid object" do
|
4
|
+
let(:middleware) { VulnDBHQ::Response::ParseJson.new(lambda{|env| Faraday::Response.new(env)}) }
|
5
|
+
|
6
|
+
def process(body, content_type = nil)
|
7
|
+
env = {:body => body, :request_headers => Faraday::Utils::Headers.new}
|
8
|
+
env[:request_headers]['content-type'] = content_type if content_type
|
9
|
+
middleware.call(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "parses response body (JSON) into a Hash" do
|
13
|
+
response = process('{"a":1,"b":"dos"}', 'application/json')
|
14
|
+
response.body.should be_a_kind_of(Hash)
|
15
|
+
response.body.keys.should include(:a)
|
16
|
+
response.body.keys.should include(:b)
|
17
|
+
response.body[:b].should eq('dos')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "for invalid object" do
|
22
|
+
let(:client) { VulnDBHQ::Client.new }
|
23
|
+
pending "handles 404 responses"
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'Although not required, bundler is recommended for running the tests.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# load the library
|
8
|
+
require 'vulndbhq'
|
9
|
+
|
10
|
+
# test libraries
|
11
|
+
require 'webmock/rspec'
|
12
|
+
|
13
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
14
|
+
# in spec/support/ and its subdirectories.
|
15
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
16
|
+
|
17
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
config.filter_run :focus
|
22
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VulnDBHQ::Base do
|
4
|
+
|
5
|
+
before do
|
6
|
+
object = VulnDBHQ::Base.new(:id => 1)
|
7
|
+
@base = VulnDBHQ::Base.store(object)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#to_hash" do
|
11
|
+
it "returns a hash" do
|
12
|
+
@base.to_hash.should be_a Hash
|
13
|
+
@base.to_hash[:id].should eq 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.fetch' do
|
18
|
+
it 'returns existing objects' do
|
19
|
+
VulnDBHQ::Base.fetch(:id => 1).should be
|
20
|
+
VulnDBHQ::Base.fetch(:id => 1).object_id.should eq(@base.object_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "raises an error on objects that don't exist" do
|
24
|
+
lambda {
|
25
|
+
VulnDBHQ::Base.fetch(:id => 6)
|
26
|
+
}.should raise_error(VulnDBHQ::IdentityMapKeyError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.store' do
|
31
|
+
it 'stores VulnDBHQ::Base objects' do
|
32
|
+
object = VulnDBHQ::Base.new(:id => 4)
|
33
|
+
VulnDBHQ::Base.store(object).should be_a VulnDBHQ::Base
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '.fetch_or_create' do
|
38
|
+
it 'returns existing objects' do
|
39
|
+
VulnDBHQ::Base.fetch_or_create(:id => 1).should be
|
40
|
+
VulnDBHQ::Base.fetch(:id => 1).object_id.should eq(@base.object_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'creates new objects and stores them' do
|
44
|
+
VulnDBHQ::Base.fetch_or_create(:id => 2).should be
|
45
|
+
|
46
|
+
VulnDBHQ::Base.fetch(:id => 2).should be
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VulnDBHQ::Client do
|
4
|
+
|
5
|
+
pending "catches Faraday errors"
|
6
|
+
# it "catches Faraday errors" do
|
7
|
+
# subject.stub!(:connection).and_raise(Faraday::Error::ClientError.new("Oups"))
|
8
|
+
# lambda do
|
9
|
+
# subject.request(:get, "/path", {}, {})
|
10
|
+
# end.should raise_error(VulnDBHQ::Error::ClientError, "Oups")
|
11
|
+
# end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VulnDBHQ::PrivatePage do
|
4
|
+
|
5
|
+
it "loads :name and :content from the server's JSON body" do
|
6
|
+
stub_get('/api/private_pages/1').
|
7
|
+
to_return(:status => 200,
|
8
|
+
:body => "{\"content\":\"#[Title]#\\r\\nThis is my Private Page\\r\\n\\r\\n\",\"id\":1,\"name\":\"MyPrivatePage\"}",
|
9
|
+
:headers => {'Content-Type' => 'application/json; charset=utf-8'})
|
10
|
+
client = VulnDBHQ::client
|
11
|
+
client.host = TEST_ENDPOINT
|
12
|
+
|
13
|
+
private_page = client.private_page(1)
|
14
|
+
private_page.should be
|
15
|
+
private_page.should be_a(VulnDBHQ::PrivatePage)
|
16
|
+
private_page.name.should eq('MyPrivatePage')
|
17
|
+
private_page.content.should eq("#[Title]#\r\nThis is my Private Page\r\n\r\n")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VulnDBHQ do
|
4
|
+
|
5
|
+
describe '.respond_to?' do
|
6
|
+
it "delegates to VulnDBHQ::Client" do
|
7
|
+
VulnDBHQ.respond_to?(:private_pages).should be_true
|
8
|
+
end
|
9
|
+
it "takes an optional argument" do
|
10
|
+
VulnDBHQ.respond_to?(:private_pages, true).should be_true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".client" do
|
15
|
+
it "returns a VulnDBHQ::Client" do
|
16
|
+
VulnDBHQ.client.should be_a VulnDBHQ::Client
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".configure" do
|
21
|
+
VulnDBHQ::Configurable.keys.each do |key|
|
22
|
+
it "sets the #{key.to_s.gsub('_', ' ')}" do
|
23
|
+
VulnDBHQ.configure do |config|
|
24
|
+
config.send("#{key}=", key)
|
25
|
+
end
|
26
|
+
VulnDBHQ.instance_variable_get("@#{key}").should eq key
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
VulnDBHQ::Configurable::CONFIG_KEYS.each do |key|
|
32
|
+
it "has a default #{key.to_s.gsub('_', ' ')}" do
|
33
|
+
VulnDBHQ.send(key).should eq VulnDBHQ::Default.options[key]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/vulndbhq.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/vulndbhq/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Daniel Martin']
|
6
|
+
gem.email = ['<daniel@securityroots.com>']
|
7
|
+
gem.description = %q{A Ruby wrapper for the VulnDB HQ API.}
|
8
|
+
gem.summary = %q{VulnDB HQ API wrapper}
|
9
|
+
gem.homepage = 'http://vulndbhq.com'
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = 'vulndbhq'
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = VulnDBHQ::Version
|
17
|
+
|
18
|
+
gem.add_runtime_dependency 'faraday', '~> 0.8'
|
19
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.3'
|
20
|
+
|
21
|
+
gem.add_development_dependency 'rake', '~> 0.8'
|
22
|
+
gem.add_development_dependency 'rspec', '~> 2.8'
|
23
|
+
gem.add_development_dependency 'webmock'
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vulndbhq
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.beta
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Daniel Martin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.8'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.8'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: multi_json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.8'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.8'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.8'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '2.8'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webmock
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: A Ruby wrapper for the VulnDB HQ API.
|
95
|
+
email:
|
96
|
+
- <daniel@securityroots.com>
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .rspec
|
103
|
+
- .travis.yml
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- lib/vulndbhq.rb
|
109
|
+
- lib/vulndbhq/base.rb
|
110
|
+
- lib/vulndbhq/client.rb
|
111
|
+
- lib/vulndbhq/configurable.rb
|
112
|
+
- lib/vulndbhq/default.rb
|
113
|
+
- lib/vulndbhq/identity_map.rb
|
114
|
+
- lib/vulndbhq/private_page.rb
|
115
|
+
- lib/vulndbhq/response/parse_json.rb
|
116
|
+
- lib/vulndbhq/version.rb
|
117
|
+
- spec/faraday_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
- spec/support/webmock.rb
|
120
|
+
- spec/vulndbhq/base_spec.rb
|
121
|
+
- spec/vulndbhq/client_spec.rb
|
122
|
+
- spec/vulndbhq/private_page_spec.rb
|
123
|
+
- spec/vulndbhq_spec.rb
|
124
|
+
- vulndbhq.gemspec
|
125
|
+
homepage: http://vulndbhq.com
|
126
|
+
licenses: []
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
hash: -4202230674895239362
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>'
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.3.1
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 1.8.24
|
149
|
+
signing_key:
|
150
|
+
specification_version: 3
|
151
|
+
summary: VulnDB HQ API wrapper
|
152
|
+
test_files:
|
153
|
+
- spec/faraday_spec.rb
|
154
|
+
- spec/spec_helper.rb
|
155
|
+
- spec/support/webmock.rb
|
156
|
+
- spec/vulndbhq/base_spec.rb
|
157
|
+
- spec/vulndbhq/client_spec.rb
|
158
|
+
- spec/vulndbhq/private_page_spec.rb
|
159
|
+
- spec/vulndbhq_spec.rb
|