vulndbhq 0.0.1.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://secure.travis-ci.org/securityroots/vulndbhq.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/securityroots/vulndbhq.png?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
|