controls 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +9 -0
- data/README.md +2 -0
- data/Rakefile +6 -1
- data/apiary.apib +60 -0
- data/controls.gemspec +0 -3
- data/lib/controls/client.rb +11 -4
- data/lib/controls/client/events.rb +21 -0
- data/lib/controls/client/guidance.rb +0 -4
- data/lib/controls/client/security_controls.rb +0 -4
- data/lib/controls/client/threats.rb +0 -4
- data/lib/controls/default.rb +2 -1
- data/lib/controls/ext/dish/plate.rb +8 -10
- data/lib/controls/objects.rb +4 -0
- data/lib/controls/objects/coverage_information.rb +0 -1
- data/lib/controls/objects/event.rb +18 -0
- data/lib/controls/objects/product_change_event_payload.rb +4 -0
- data/lib/controls/objects/security_control_change_event_payload.rb +4 -0
- data/lib/controls/objects/site_change_event_payload.rb +4 -0
- data/lib/controls/version.rb +1 -1
- data/spec/controls/client/assessments_spec.rb +24 -0
- data/spec/controls/client/events_spec.rb +54 -0
- data/spec/matchers.rb +46 -0
- data/spec/spec_helper.rb +14 -0
- metadata +17 -71
- data/docs/Gemfile +0 -10
- data/docs/Rules +0 -31
- data/docs/content/index.md +0 -8
- data/docs/content/v1.md +0 -8
- data/docs/content/v1/authentication.md +0 -3
- data/docs/content/v1/search.md +0 -11
- data/docs/content/v1/troubleshooting.md +0 -3
- data/docs/layouts/default.html +0 -46
- data/docs/layouts/home.html +0 -51
- data/docs/lib/default.rb +0 -2
- data/docs/nanoc.yaml +0 -43
- data/docs/static/css/bootstrap-theme.css +0 -397
- data/docs/static/css/bootstrap-theme.min.css +0 -7
- data/docs/static/css/bootstrap.css +0 -7118
- data/docs/static/css/bootstrap.min.css +0 -7
- data/docs/static/fonts/glyphicons-halflings-regular.eot +0 -0
- data/docs/static/fonts/glyphicons-halflings-regular.svg +0 -229
- data/docs/static/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/docs/static/fonts/glyphicons-halflings-regular.woff +0 -0
- data/docs/static/images/controlsinsight-shield.png +0 -0
- data/docs/static/images/controlsinsight.png +0 -0
- data/docs/static/js/bootstrap.js +0 -2006
- data/docs/static/js/bootstrap.min.js +0 -7
- data/spec/controls_spec.rb +0 -22
- data/spec/helper.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c454bb91456860e8b28060cca709a3955d7e227e
|
4
|
+
data.tar.gz: d1069c59e852f48ebb04e6fb3acfa517177dd320
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a61b496ef91f6570129fea1491fca80862715227c5a8556dfd9aaa1c46d81d20e3a4273de70fb96b47d6442872951ebdcf3bc99e9cb87f138fe59b67ad5c8153
|
7
|
+
data.tar.gz: c2e8ce4004164c97f9650fd6e63c5078a47674f840ee460cfcd7f2075178f0838acfe00e53aea27e3bae40442e6dca7a38a2f8f7988c12c149797ce0062a0762
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# controlsinsight client gem
|
2
|
+
[![Build Status](https://travis-ci.org/erran/controls.rb.png?branch=master)](https://travis-ci.org/erran/controls.rb)
|
3
|
+
|
2
4
|
The **controls**insight (controls) gem interfaces with [Rapid7's **controls**insight API](http://rapid7.github.io/controlsinsight.rb).
|
3
5
|
|
4
6
|
## Installation
|
data/Rakefile
CHANGED
data/apiary.apib
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
FORMAT: 1A
|
2
|
+
HOST: https://nexpose.local:3780/insight/controls/api/
|
3
|
+
|
4
|
+
# ControlsInsight
|
5
|
+
Notes API is a *short texts saving* service similar to its physical paper presence on your table.
|
6
|
+
|
7
|
+
# Group Assessments
|
8
|
+
## Assessment Collection [/assessments]
|
9
|
+
### Assessments [GET]
|
10
|
+
|
11
|
+
+ Response 200 (application/json)
|
12
|
+
|
13
|
+
{
|
14
|
+
"id": 1,
|
15
|
+
"assessing": false,
|
16
|
+
"highRiskAssetCount": 0,
|
17
|
+
"mediumRiskAssetCount": 24,
|
18
|
+
"lowRiskAssetCount": 0,
|
19
|
+
"totalAssetCount": 24,
|
20
|
+
"overallRiskScore": 4.004146038088617,
|
21
|
+
"timestamp": 1393184605912
|
22
|
+
}
|
23
|
+
|
24
|
+
## Assessment [/assessments/{assessment_id}]
|
25
|
+
### Assessment by ID [GET]
|
26
|
+
|
27
|
+
+ Parameters
|
28
|
+
+ assessment_id (optional, integer, `1`) ... The ID of the assessment to retreive.
|
29
|
+
|
30
|
+
+ Response 200 (application/json)
|
31
|
+
|
32
|
+
{
|
33
|
+
"id": 1,
|
34
|
+
"assessing": false,
|
35
|
+
"highRiskAssetCount": 0,
|
36
|
+
"mediumRiskAssetCount": 24,
|
37
|
+
"lowRiskAssetCount": 0,
|
38
|
+
"totalAssetCount": 24,
|
39
|
+
"overallRiskScore": 4.004146038088617,
|
40
|
+
"timestamp": 1393184605912
|
41
|
+
}
|
42
|
+
|
43
|
+
# Group Search
|
44
|
+
## Assets [/assets/search?query={query}]
|
45
|
+
### Asset Search [GET]
|
46
|
+
|
47
|
+
+ Parameters
|
48
|
+
+ query (required, string, `10.4.19`) ... The free text query. This can be a full/partial hostname or IP address.
|
49
|
+
|
50
|
+
+ Response 200 (application/json)
|
51
|
+
|
52
|
+
[
|
53
|
+
{
|
54
|
+
"uuid": "db899a57-347c-4df9-9ce2-6932dc4adf38>",
|
55
|
+
"riskScore": 5.554266115196547,
|
56
|
+
"riskLevel": "MEDIUM",
|
57
|
+
"hostName": "CMMNCTR2K7R2-U",
|
58
|
+
"ipaddress": "10.4.19.25"
|
59
|
+
}
|
60
|
+
]
|
data/controls.gemspec
CHANGED
@@ -24,7 +24,4 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
26
26
|
spec.add_development_dependency 'netrc'
|
27
|
-
spec.add_development_dependency 'rake'
|
28
|
-
spec.add_development_dependency 'vcr'
|
29
|
-
spec.add_development_dependency 'yard'
|
30
27
|
end
|
data/lib/controls/client.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'faraday'
|
3
|
-
require 'nokogiri'
|
4
3
|
require 'rack/utils'
|
5
4
|
require 'controls/authentication'
|
6
5
|
require 'controls/configurable'
|
7
6
|
require 'controls/client/assessments'
|
8
7
|
require 'controls/client/assets'
|
8
|
+
require 'controls/client/events'
|
9
9
|
require 'controls/client/coverage'
|
10
|
+
require 'controls/client/configurations'
|
10
11
|
require 'controls/client/guidance'
|
12
|
+
require 'controls/client/prioritized_guidance'
|
11
13
|
require 'controls/client/security_controls'
|
12
14
|
require 'controls/client/threats'
|
15
|
+
require 'controls/client/threat_vectors'
|
13
16
|
require 'controls/client/trends'
|
14
17
|
require 'controls/response'
|
15
18
|
|
@@ -20,10 +23,14 @@ module Controls
|
|
20
23
|
include Controls::Configurable
|
21
24
|
include Controls::Client::Assessments
|
22
25
|
include Controls::Client::Assets
|
26
|
+
include Controls::Client::Events
|
23
27
|
include Controls::Client::Coverage
|
28
|
+
include Controls::Client::Configurations
|
24
29
|
include Controls::Client::Guidance
|
30
|
+
include Controls::Client::PrioritizedGuidance
|
25
31
|
include Controls::Client::SecurityControls
|
26
32
|
include Controls::Client::Threats
|
33
|
+
include Controls::Client::ThreatVectors
|
27
34
|
include Controls::Client::Trends
|
28
35
|
|
29
36
|
# A few messages to show the user of Controls::Client in the case that a bad certificate is encountered
|
@@ -94,7 +101,7 @@ module Controls
|
|
94
101
|
path: path
|
95
102
|
}
|
96
103
|
|
97
|
-
if !resp.headers['content-type']
|
104
|
+
if !resp.headers['content-type'] =~ /^application\/json/
|
98
105
|
fail exception('Invalid content-type error')
|
99
106
|
end
|
100
107
|
|
@@ -119,7 +126,7 @@ module Controls
|
|
119
126
|
path: path
|
120
127
|
}
|
121
128
|
|
122
|
-
if !resp.headers['content-type']
|
129
|
+
if !resp.headers['content-type'] =~ /^application\/json/
|
123
130
|
fail exception('Invalid content-type error')
|
124
131
|
end
|
125
132
|
|
@@ -194,7 +201,7 @@ module Controls
|
|
194
201
|
path: path
|
195
202
|
}
|
196
203
|
|
197
|
-
if !resp.headers['content-type']
|
204
|
+
if !resp.headers['content-type'] =~ /^application\/json/
|
198
205
|
fail exception('Invalid content-type error')
|
199
206
|
end
|
200
207
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Controls
|
2
|
+
class Client
|
3
|
+
# A module to encapsulate API methods related to events
|
4
|
+
# @since API v1.0
|
5
|
+
# @version v1.6.0
|
6
|
+
module Events
|
7
|
+
# @!group Event Methods
|
8
|
+
|
9
|
+
|
10
|
+
# Either returns a list of all events or all events by type
|
11
|
+
#
|
12
|
+
# @param [Hash] params the query parameters to send with the request
|
13
|
+
# @option params [String] :filter (:all) the event type to filter by
|
14
|
+
# @raise [Controls::NotFound] if the uuid didn't match any events
|
15
|
+
# @return [Hash] a hash representing the matching event
|
16
|
+
def events(params = {})
|
17
|
+
get '/events', params
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,13 +1,9 @@
|
|
1
|
-
require 'controls/client/prioritized_guidance'
|
2
|
-
|
3
1
|
module Controls
|
4
2
|
class Client
|
5
3
|
# A module to encapsulate API methods related to guidance
|
6
4
|
# @since API v1.0
|
7
5
|
# @version v1.0.0
|
8
6
|
module Guidance
|
9
|
-
include PrioritizedGuidance
|
10
|
-
|
11
7
|
# @!group Guidance Methods
|
12
8
|
|
13
9
|
# @param [String] name the name of the guidance to search for
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'controls/client/configurations'
|
2
|
-
|
3
1
|
module Controls
|
4
2
|
class Client
|
5
3
|
# A module to encapsulate API methods related to security controls and
|
@@ -7,8 +5,6 @@ module Controls
|
|
7
5
|
# @since API v1.0
|
8
6
|
# @version v1.0.0
|
9
7
|
module SecurityControls
|
10
|
-
include Configurations
|
11
|
-
|
12
8
|
#!@group Security Control Methods
|
13
9
|
|
14
10
|
# @param [String] control the name of the security control name to
|
@@ -1,13 +1,9 @@
|
|
1
|
-
require 'controls/client/threat_vectors'
|
2
|
-
|
3
1
|
module Controls
|
4
2
|
class Client
|
5
3
|
# A module to encapsulate API methods related to threats and threat vectors
|
6
4
|
# @since API v1.0
|
7
5
|
# @version v1.0.0
|
8
6
|
module Threats
|
9
|
-
include ThreatVectors
|
10
|
-
|
11
7
|
# @!group Threat Methods
|
12
8
|
|
13
9
|
# @param [String] threat the threat name to search for
|
data/lib/controls/default.rb
CHANGED
@@ -31,7 +31,8 @@ module Controls
|
|
31
31
|
# @return [String] the API endpoint's URI as a URL
|
32
32
|
def api_endpoint
|
33
33
|
endpoint = ENV['CONTROLS_API_ENDPOINT'] || API_ENDPOINT
|
34
|
-
URI
|
34
|
+
# [todo] - this raises an exception, it is only used for URI validation so it's being commented out for now
|
35
|
+
# URI.parse(endpoint).to_s
|
35
36
|
end
|
36
37
|
|
37
38
|
# @return [String] the API version to connect to
|
@@ -5,18 +5,17 @@ module Dish
|
|
5
5
|
camel_case_key = method.split('_').map(&:capitalize).join
|
6
6
|
camel_case_key[0] = camel_case_key[0].downcase
|
7
7
|
|
8
|
-
if method.end_with?
|
8
|
+
if method.end_with? '?'
|
9
9
|
key = camel_case_key[0..-2]
|
10
10
|
_check_for_presence(key)
|
11
|
-
elsif method.end_with?
|
11
|
+
elsif method.end_with? '='
|
12
12
|
key = camel_case_key[0..-2]
|
13
13
|
_set_value(key, args.first)
|
14
14
|
else
|
15
|
-
|
16
|
-
|
17
|
-
super(method.to_sym, *args, &block)
|
15
|
+
if @_original_hash.key?(camel_case_key)
|
16
|
+
_get_value(camel_case_key)
|
18
17
|
else
|
19
|
-
|
18
|
+
super(method.to_sym, *args, &block)
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
@@ -42,18 +41,17 @@ module Dish
|
|
42
41
|
"#<#{self.class}: #{vars.join(', ')}>"
|
43
42
|
end
|
44
43
|
|
44
|
+
alias_method :to_h, :as_hash
|
45
|
+
|
45
46
|
def to_json(*args)
|
46
47
|
as_hash.to_json(*args)
|
47
48
|
end
|
48
49
|
|
49
50
|
private
|
51
|
+
|
50
52
|
def _set_value(key, value)
|
51
53
|
value = _convert_value(value, self.class.coercions[key])
|
52
54
|
@_original_hash[key] = value
|
53
55
|
end
|
54
|
-
|
55
|
-
def _allowed_keys
|
56
|
-
[]
|
57
|
-
end
|
58
56
|
end
|
59
57
|
end
|
data/lib/controls/objects.rb
CHANGED
@@ -2,10 +2,14 @@ require 'dish'
|
|
2
2
|
require 'controls/ext/dish/plate'
|
3
3
|
require 'controls/objects/assessment'
|
4
4
|
require 'controls/objects/asset'
|
5
|
+
require 'controls/objects/event'
|
6
|
+
require 'controls/objects/product_change_event_payload'
|
5
7
|
require 'controls/objects/configuration'
|
6
8
|
require 'controls/objects/guidance'
|
7
9
|
require 'controls/objects/security_control'
|
10
|
+
require 'controls/objects/security_control_change_event_payload'
|
8
11
|
require 'controls/objects/security_control_coverage'
|
12
|
+
require 'controls/objects/site_change_event_payload'
|
9
13
|
require 'controls/objects/threat'
|
10
14
|
require 'controls/objects/threat_vector'
|
11
15
|
require 'controls/objects/trend'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Controls
|
2
|
+
class Event < Dish::Plate
|
3
|
+
coerce :createdAt, ->(value) { Time.at(value / 1000) if value }
|
4
|
+
|
5
|
+
def payload
|
6
|
+
value = _get_value('payload')
|
7
|
+
Dish(value, Controls.const_get("#{type}Payload"))
|
8
|
+
end
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
super.sub('Event', type)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/controls/version.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
describe '/api/assessments' do
|
2
|
+
before do
|
3
|
+
login_to_environment
|
4
|
+
end
|
5
|
+
|
6
|
+
context 'GET /api/assessments' do
|
7
|
+
it 'returns a list of assessments' do
|
8
|
+
assessments = Controls.assessments
|
9
|
+
|
10
|
+
expect(assessments).to match_assessment_format
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'GET /api/assessments/1' do
|
15
|
+
it 'returns a single assessment' do
|
16
|
+
assessment = Controls.assessments(1)
|
17
|
+
|
18
|
+
expect(assessment).to match_assessment_format
|
19
|
+
expect(assessment.id).to eq(1)
|
20
|
+
expect(assessment.assessing?).to be_false
|
21
|
+
expect(assessment.overall_risk_score).to be_within(5.0).of(5.0)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#describe '/api/events' do
|
2
|
+
# before do
|
3
|
+
# login_to_environment
|
4
|
+
# end
|
5
|
+
#
|
6
|
+
# context 'GET /api/events' do
|
7
|
+
# it 'returns a list of events' do
|
8
|
+
# events = Controls.events
|
9
|
+
#
|
10
|
+
# expect(events).to match_format(event_format)
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# context 'GET /api/events?filter=ProductChangeEvent' do
|
15
|
+
# it 'returns a list of events' do
|
16
|
+
# events = Controls.events filter: 'ProductChangeEvent'
|
17
|
+
#
|
18
|
+
# expect(events).to match_format(event_format)
|
19
|
+
# expect(events.map(&:payload)).to match_format(product_change_format)
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# context 'GET /api/events?filter=SecurityControlChangeEvent' do
|
24
|
+
# it 'returns a list of events' do
|
25
|
+
# events = Controls.events filter: 'SecurityControlChangeEvent'
|
26
|
+
# expected_payload_format = security_control_change_format
|
27
|
+
#
|
28
|
+
# expect(events).to match_format(event_format)
|
29
|
+
# expect(events.map(&:payload)).to match_format(expected_payload_format)
|
30
|
+
#
|
31
|
+
# events.map(&:payload).each do |payload|
|
32
|
+
# payload.keys.map(&:to_sym).each do |key|
|
33
|
+
# expect(payload.send(key)).to match_format(expected_payload_format[key].last)
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# context 'GET /api/events?filter=SiteChangeEvent' do
|
40
|
+
# it 'returns a list of events' do
|
41
|
+
# events = Controls.events filter: 'SiteChangeEvent'
|
42
|
+
# expected_payload_format = site_change_format
|
43
|
+
#
|
44
|
+
# expect(events).to match_format(event_format)
|
45
|
+
# expect(events.map(&:payload)).to match_format(expected_payload_format)
|
46
|
+
#
|
47
|
+
# events.map(&:payload).each do |payload|
|
48
|
+
# payload.keys.map(&:to_sym).each do |key|
|
49
|
+
# expect(payload.send(key)).to match_format(expected_payload_format[key].last)
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#end
|