controls 1.0.0.beta.2
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 +7 -0
- data/.gitignore +17 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE.md +20 -0
- data/README.md +78 -0
- data/Rakefile +3 -0
- data/controls.gemspec +30 -0
- data/docs/images/controlsinsight+shield.png +0 -0
- data/docs/images/controlsinsight.png +0 -0
- data/lib/controls.rb +42 -0
- data/lib/controls/authentication.rb +46 -0
- data/lib/controls/client.rb +151 -0
- data/lib/controls/client/assessments.rb +17 -0
- data/lib/controls/client/assets.rb +64 -0
- data/lib/controls/client/configurations.rb +31 -0
- data/lib/controls/client/guidance.rb +46 -0
- data/lib/controls/client/prioritized_guidance.rb +34 -0
- data/lib/controls/client/security_controls.rb +36 -0
- data/lib/controls/client/threat_vectors.rb +29 -0
- data/lib/controls/client/threats.rb +26 -0
- data/lib/controls/configurable.rb +83 -0
- data/lib/controls/default.rb +108 -0
- data/lib/controls/error.rb +132 -0
- data/lib/controls/response.rb +76 -0
- data/lib/controls/response/raise_error.rb +21 -0
- data/lib/controls/version.rb +4 -0
- data/spec/controls_spec.rb +22 -0
- data/spec/helper.rb +42 -0
- metadata +187 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module Controls
|
2
|
+
class Client
|
3
|
+
# A module to encapsulate API methods related to security controls and
|
4
|
+
# configurations
|
5
|
+
# @since API v1.0
|
6
|
+
# @version v1.0.0
|
7
|
+
module Configurations
|
8
|
+
# @!group Configuration Methods
|
9
|
+
|
10
|
+
# @param [String] configuration the name of the configuration to search
|
11
|
+
# for
|
12
|
+
# @return [Array<Hash>] a list of hashes representing configurations
|
13
|
+
def configurations(configuration = nil)
|
14
|
+
if configuration
|
15
|
+
get "/configurations/#{configuration}"
|
16
|
+
else
|
17
|
+
get "/configurations"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param [String] control the security control look up configurations for
|
22
|
+
# @return [Array<Hash>] a list of hashes representing configurations
|
23
|
+
def security_control_configurations(control)
|
24
|
+
get "/security_controls/#{control}/configurations"
|
25
|
+
end
|
26
|
+
alias_method :configurations_by_security_control, :security_control_configurations
|
27
|
+
|
28
|
+
# @!endgroup
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'controls/client/prioritized_guidance'
|
2
|
+
|
3
|
+
module Controls
|
4
|
+
class Client
|
5
|
+
# A module to encapsulate API methods related to guidance
|
6
|
+
# @since API v1.0
|
7
|
+
# @version v1.0.0
|
8
|
+
module Guidance
|
9
|
+
include PrioritizedGuidance
|
10
|
+
|
11
|
+
# @!group Guidance Methods
|
12
|
+
|
13
|
+
# @param [String] name the name of the guidance to search for
|
14
|
+
# @return [Hash] a hash representing the matching guidance
|
15
|
+
def guidance(name)
|
16
|
+
get "/guidance/#{name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [String] configuration the configuration name to search by
|
20
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
21
|
+
def guidance_by_configuration(security_control, configuration)
|
22
|
+
get "/configurations/#{configuration}/guidance"
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [String] security_control the security control name to search by
|
26
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
27
|
+
def guidance_by_security_control(security_control)
|
28
|
+
get "/security_controls/#{security_control}/guidance"
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [String] threat the threat name to search by
|
32
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
33
|
+
def guidance_by_threat(threat)
|
34
|
+
get "/threats/#{threat}/guidance"
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [String] threat_vector the threat name to search by
|
38
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
39
|
+
def guidance_by_threat_vector(threat_vector)
|
40
|
+
get "/threat_vectors/#{threat_vector}/guidance"
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!endgroup
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Controls
|
2
|
+
class Client
|
3
|
+
# A module to encapsulate API methods related to guidance
|
4
|
+
# @since API v1.0
|
5
|
+
# @version v1.0.0
|
6
|
+
module PrioritizedGuidance
|
7
|
+
# @!group Prioritized Guidance Methods
|
8
|
+
|
9
|
+
# @param [String] security_control the security control name to search by
|
10
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
11
|
+
def prioritized_guidance_by_security_control(security_control)
|
12
|
+
get "/security_controls/#{security_control}/prioritized_guidance"
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [String] configuration the configuration name to search by
|
16
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
17
|
+
def prioritized_guidance_by_configuration(configuration)
|
18
|
+
get "/configurations/#{configuration}/prioritized_guidance"
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param [String] threat the threat name to search by
|
22
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
23
|
+
def prioritized_guidance_by_threat(threat)
|
24
|
+
get "/threats/#{threat}/prioritized_guidance"
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [String] threat_vector the threat name to search by
|
28
|
+
# @return [Array<Hash>] an array of "guidance hashes"
|
29
|
+
def prioritized_guidance_by_threat_vector(threat_vector)
|
30
|
+
get "/threat_vectors/#{threat_vector}/prioritized_guidance"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'controls/client/configurations'
|
2
|
+
|
3
|
+
module Controls
|
4
|
+
class Client
|
5
|
+
# A module to encapsulate API methods related to security controls and
|
6
|
+
# configurations
|
7
|
+
# @since API v1.0
|
8
|
+
# @version v1.0.0
|
9
|
+
module SecurityControls
|
10
|
+
include Configurations
|
11
|
+
|
12
|
+
#!@group Security Control Methods
|
13
|
+
|
14
|
+
# @param [String] control the name of the security control name to
|
15
|
+
# retrieve
|
16
|
+
# @return [Hash] a hash representing a security control
|
17
|
+
def security_controls(control = nil)
|
18
|
+
if control
|
19
|
+
get "/security_controls/#{control}"
|
20
|
+
else
|
21
|
+
get '/security_controls'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [String] vector the threat vector to search for securuty controls
|
26
|
+
# by
|
27
|
+
# @return [Array<Hash>] a list of hashes representing threats
|
28
|
+
def threat_vector_security_controls(vector)
|
29
|
+
get "/threat_vectors/#{vector}/security_controls"
|
30
|
+
end
|
31
|
+
alias_method :security_controls_by_threat_vector, :threat_vector_security_controls
|
32
|
+
|
33
|
+
# @!endgroup
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Controls
|
2
|
+
class Client
|
3
|
+
# A module to encapsulate API methods related to threats and threat vectors
|
4
|
+
# @since API v1.0
|
5
|
+
# @version v1.0.0
|
6
|
+
module ThreatVectors
|
7
|
+
# @!group Threat Vector Methods
|
8
|
+
|
9
|
+
# @param [String] vector the threat vector to search for
|
10
|
+
# @return [String] a hash representing the specified threat vector
|
11
|
+
def threat_vectors(vector = nil)
|
12
|
+
if vector
|
13
|
+
get "/threat_vectors/#{vector}"
|
14
|
+
else
|
15
|
+
get '/threat_vectors'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [String] threat the threat to search for threat vectors by
|
20
|
+
# @return [Array<Hash>] a list of hashes representing threats
|
21
|
+
def threat_threat_vectors(threat)
|
22
|
+
get "/threats/#{threat}/threat_vectors"
|
23
|
+
end
|
24
|
+
alias_method :threat_vectors_by_threat, :threat_threat_vectors
|
25
|
+
|
26
|
+
# @!endgroup
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'controls/client/threat_vectors'
|
2
|
+
|
3
|
+
module Controls
|
4
|
+
class Client
|
5
|
+
# A module to encapsulate API methods related to threats and threat vectors
|
6
|
+
# @since API v1.0
|
7
|
+
# @version v1.0.0
|
8
|
+
module Threats
|
9
|
+
include ThreatVectors
|
10
|
+
|
11
|
+
# @!group Threat Methods
|
12
|
+
|
13
|
+
# @param [String] threat the threat name to search for
|
14
|
+
# @return [String] a hash representing the specified threat
|
15
|
+
def threats(threat = nil)
|
16
|
+
if threat
|
17
|
+
get "/threats/#{threat}"
|
18
|
+
else
|
19
|
+
get '/threats'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @!endgroup
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Controls
|
2
|
+
# A module to hold configurable options to be used by other classes such as
|
3
|
+
# the {Controls} eigenclass or the {Controls::Client} class
|
4
|
+
module Configurable
|
5
|
+
# @!attribute api_endpoint
|
6
|
+
# @return [String] the endpoint to connect to. default: https://nexpose.local:3780/insight/controls/api/1.0
|
7
|
+
# @!attribute api_endpoint
|
8
|
+
# @return [String] the endpoint to connect to. default: https://nexpose.local:3780/insight/controls/api/1.0
|
9
|
+
# @!attribute connection_options
|
10
|
+
# @return [Hash] the current connection options (headers, etc.)
|
11
|
+
# @!attribute default_media_type
|
12
|
+
# @return [String] the default media type to send with requests. default: application/json
|
13
|
+
# @!attribute middleware
|
14
|
+
# @return [Faraday::Connection] the middleware used to send requests
|
15
|
+
# @!attribute netrc
|
16
|
+
# @return [Boolean] whether to use the netrc credentials to authentcicate with the **controls**insight API
|
17
|
+
# @!attribute netrc_file
|
18
|
+
# @return [String] the path of the .netrc file to look for credentials in. default: ~/.netrc
|
19
|
+
# @!attribute user_agent
|
20
|
+
# @return [String] the user agent to send with API requests. example: "controls/v1.0.0.beta (ruby; 2.0.0p247; [x86_64-darwin12.4.0]; Faraday v0.8.8)"
|
21
|
+
# @!attribute username
|
22
|
+
# @return [String] the username to use for authentication
|
23
|
+
# @!attribute web_endpoint
|
24
|
+
# @return [String] the endpoint to connect to. default: https://nexpose.local:3780/insight/controls
|
25
|
+
attr_accessor :api_endpoint, :api_version, :connection_options,
|
26
|
+
:default_media_type, :middleware, :netrc, :netrc_file,
|
27
|
+
:user_agent, :username, :web_endpoint
|
28
|
+
|
29
|
+
# @!attribute [w] password
|
30
|
+
# @return [String] the password specified on login
|
31
|
+
attr_writer :password
|
32
|
+
|
33
|
+
class << self
|
34
|
+
# @return [Array<Symbol>] a list of configurable keys
|
35
|
+
def keys
|
36
|
+
@keys ||= [
|
37
|
+
:api_endpoint,
|
38
|
+
:api_version,
|
39
|
+
:connection_options,
|
40
|
+
:default_media_type,
|
41
|
+
:middleware,
|
42
|
+
:netrc,
|
43
|
+
:netrc_file,
|
44
|
+
:password,
|
45
|
+
:user_agent,
|
46
|
+
:username,
|
47
|
+
:web_endpoint
|
48
|
+
]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @yield [self]
|
53
|
+
def configure
|
54
|
+
yield self
|
55
|
+
end
|
56
|
+
|
57
|
+
def netrc?
|
58
|
+
!!@netrc
|
59
|
+
end
|
60
|
+
|
61
|
+
# Configures {Controls::Configurable} to use options found in
|
62
|
+
# {Controls::Default}
|
63
|
+
#
|
64
|
+
# @return [self]
|
65
|
+
def setup
|
66
|
+
Controls::Configurable.keys.each do |key|
|
67
|
+
instance_variable_set(:"@#{key}", Controls::Default.options[key])
|
68
|
+
end
|
69
|
+
|
70
|
+
self
|
71
|
+
end
|
72
|
+
# NOTE: This method currently leaves some "updated defaults" intact
|
73
|
+
# alias_method :reset!, :setup
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# @return [Hash] a hash representation of the options mapping key names to
|
78
|
+
# their instance variable counterpart's value
|
79
|
+
def options
|
80
|
+
Hash[Controls::Configurable.keys.map { |key| [key, instance_variable_get(:"@#{key}")] }]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'controls/version'
|
2
|
+
|
3
|
+
module Controls
|
4
|
+
# Default options merged with environment specific overrides to satisfy the
|
5
|
+
# options specified in the {Controls::Configurable} module
|
6
|
+
module Default
|
7
|
+
# @return [String] the API version to connect to. default: 1.0
|
8
|
+
# @since API v1.0.0
|
9
|
+
API_VERSION = '1.0'.freeze
|
10
|
+
|
11
|
+
# @return [String] the API endpoint to connect to. default: https://nexpose.local:3780/insight/controls/api/1.0
|
12
|
+
# @since API v1.0.0
|
13
|
+
API_ENDPOINT = "https://localhost:3780/insight/controls/api/#{API_VERSION}".freeze
|
14
|
+
|
15
|
+
# @return [String] the default media type to send with requests. default: application/json
|
16
|
+
# @since API v1.0.0
|
17
|
+
MEDIA_TYPE = 'application/json'
|
18
|
+
|
19
|
+
# @return [String] the user agent to send with API requests. example: "controls/v1.0.0.beta (ruby; 2.0.0p247; [x86_64-darwin12.4.0]; Faraday v0.8.8)"
|
20
|
+
USER_AGENT = "controls/v#{Controls::VERSION} (#{(RUBY_DESCRIPTION.split[0..1] + [RUBY_DESCRIPTION.split.last]).join('; ')}; Faraday v#{Faraday::VERSION})".freeze
|
21
|
+
|
22
|
+
# @return [String] the web endpoint to connect to. default: https://nexpose.local:3780/insight/controls
|
23
|
+
WEB_ENDPOINT = 'https://localhost:3780/insight/controls'.freeze
|
24
|
+
|
25
|
+
class << self
|
26
|
+
# @return [Hash] options as a Hash, mapped by keys from {Controls::Configurable}
|
27
|
+
def options
|
28
|
+
Hash[Controls::Configurable.keys.map { |key| [key, send(key)] }]
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] the API endpoint's URI as a URL
|
32
|
+
def api_endpoint
|
33
|
+
endpoint = ENV['CONTROLS_API_ENDPOINT'] || API_ENDPOINT
|
34
|
+
URI.parse(endpoint).to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String] the API version to connect to
|
38
|
+
def api_version
|
39
|
+
if ENV['CONTROLS_API_VERSION'].to_s =~ /\d+.\d+/
|
40
|
+
ENV['CONTROLS_API_VERSION']
|
41
|
+
else
|
42
|
+
API_VERSION
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Hash] the current connection options (headers, etc.)
|
47
|
+
def connection_options
|
48
|
+
{
|
49
|
+
headers: {
|
50
|
+
accept: default_media_type,
|
51
|
+
user_agent: user_agent
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [String] the environment specific default media type.
|
57
|
+
# default: {MEDIA_TYPE}
|
58
|
+
def default_media_type
|
59
|
+
ENV['CONTROLS_MEDIA_TYPE'] || MEDIA_TYPE
|
60
|
+
end
|
61
|
+
|
62
|
+
# REVIEW: Ensure that middleware is unique to the client instance
|
63
|
+
# @return [Faraday::Connection] the middleware used to send requests
|
64
|
+
def middleware
|
65
|
+
@middleware ||= Faraday.new(api_endpoint, connection_options) do |conn|
|
66
|
+
conn.adapter Faraday.default_adapter
|
67
|
+
conn.response :logger if ENV['CONTROLS_DEBUG']
|
68
|
+
conn.use Controls::Response::RaiseError
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Boolean] whether to fallback on authentication using the
|
73
|
+
# specified netrc file
|
74
|
+
def netrc
|
75
|
+
ENV['CONTROLS_NETRC'] || false
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [String] the netrc file to use for authentication.
|
79
|
+
# default: ~/.netrc
|
80
|
+
def netrc_file
|
81
|
+
ENV['CONTROLS_NETRC_FILE'] || File.join(Dir.home, '.netrc')
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# @return [String] the password to use for authentication
|
86
|
+
def password
|
87
|
+
ENV['CONTROLS_PASSWORD']
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [String] the user agent that will be sent along any requests
|
91
|
+
# sent using {#connection_options}
|
92
|
+
def user_agent
|
93
|
+
ENV['CONTROLS_USER_AGENT'] || USER_AGENT
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [String] the username to use for authentication
|
97
|
+
def username
|
98
|
+
ENV['CONTROLS_USERNAME']
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [String] the web endpoint's URI as a URL
|
102
|
+
def web_endpoint
|
103
|
+
endpoint = ENV['CONTROLS_WEB_ENDPOINT'] || WEB_ENDPOINT
|
104
|
+
URI.parse(endpoint).to_s
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Controls
|
2
|
+
# A namespace for errors in the Controls module
|
3
|
+
class Error < StandardError
|
4
|
+
# @!attribute [r] error_message
|
5
|
+
# @return [String] the error message
|
6
|
+
# @!attribute [r] error_status
|
7
|
+
# @return [Fixnum] the error message
|
8
|
+
# @!attribute [r] error_json
|
9
|
+
# @return [Hash] the JSON body from the error message
|
10
|
+
attr_reader :error_json
|
11
|
+
attr_reader :error_message
|
12
|
+
attr_reader :error_status
|
13
|
+
|
14
|
+
# @raise [BadRequest,Unauthorized,NotFound,InternalServerError] a subclass
|
15
|
+
# of {Controls::Error}
|
16
|
+
# @return [nil] if no error was raised
|
17
|
+
def self.from_response(response)
|
18
|
+
error = case response[:status].to_i
|
19
|
+
when 302
|
20
|
+
# TODO: Nexpose/ControlsInsight returns 302 when you either visit a
|
21
|
+
# none existant path (Nexpose) or unauthenticated
|
22
|
+
# (ControlsInsight).
|
23
|
+
Found # if response[:body].empty?
|
24
|
+
when 400 then BadRequest
|
25
|
+
when 401 then Unauthorized
|
26
|
+
when 404 then NotFound
|
27
|
+
when 500 then InternalServerError
|
28
|
+
end
|
29
|
+
|
30
|
+
error.new(response) if error
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [self] generates an error and passes it to super
|
34
|
+
def initialize(response = nil)
|
35
|
+
@response = response
|
36
|
+
super(generate_error)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @return [String] an error message to be used by {#generate_error}
|
42
|
+
def response_message
|
43
|
+
return @response_message if @response_message
|
44
|
+
|
45
|
+
resp = @response[:response]
|
46
|
+
|
47
|
+
if resp.headers['content-type']
|
48
|
+
resp.headers['content-type'][/(\S+);charset=utf-8/i]
|
49
|
+
html = Regexp.last_match && Regexp.last_match[1].eql?('text/html')
|
50
|
+
end
|
51
|
+
|
52
|
+
@response_message = if html
|
53
|
+
doc = Nokogiri::XML.parse(resp.body)
|
54
|
+
|
55
|
+
if doc.css('title').text.eql? 'ControlsInsight'
|
56
|
+
message = ['message'].zip(doc.css('h1').map(&:text))
|
57
|
+
reason = ['reason'].zip([doc.css('p').map(&:text)])
|
58
|
+
Hash[message + reason]
|
59
|
+
else
|
60
|
+
Hash[doc.css('HR').children.map { |elem| elem.text.split(' ', 2) }]
|
61
|
+
end
|
62
|
+
else
|
63
|
+
if resp.body.empty?
|
64
|
+
@error_json = {}
|
65
|
+
else
|
66
|
+
@error_json = JSON.parse(resp.body)
|
67
|
+
@error_message = @error_json['message']
|
68
|
+
@error_status = @error_json['status'].to_i
|
69
|
+
|
70
|
+
@error_json
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [String] the error message passed to super on {#initialize}
|
76
|
+
def generate_error
|
77
|
+
return unless @response
|
78
|
+
|
79
|
+
message = "#{@response[:method]} ".upcase
|
80
|
+
message << "#{@response[:url].path}"
|
81
|
+
|
82
|
+
if response_message.is_a? Hash
|
83
|
+
message << ": #{response_message['message']}\n" if response_message['message']
|
84
|
+
|
85
|
+
if response_message['reason'].respond_to?(:join)
|
86
|
+
message << response_message['reason'].join("\n")
|
87
|
+
elsif response_message['reason']
|
88
|
+
message << response_message['reason'].to_s
|
89
|
+
end
|
90
|
+
elsif response_message.is_a? String
|
91
|
+
message << response_message
|
92
|
+
else
|
93
|
+
message << "#{@response[:status]} -"
|
94
|
+
message << self.class.to_s.split('::', 2).last
|
95
|
+
end
|
96
|
+
|
97
|
+
message.strip
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# @!group Generic errors
|
102
|
+
|
103
|
+
# TODO REVIEW: To be raised when a user hasn't explicitly supplied credentials or set up
|
104
|
+
# any environment defaults.
|
105
|
+
Unauthenticated = Class.new(StandardError)
|
106
|
+
|
107
|
+
# @!endgroup
|
108
|
+
|
109
|
+
# @!group HTTP errors
|
110
|
+
|
111
|
+
# @return [Found] an error to be raised when a status code of 401 is
|
112
|
+
# returned by the API
|
113
|
+
Found = Class.new(Error)
|
114
|
+
|
115
|
+
# @return [Unauthorized] an error to be raised when a status code of 401 is
|
116
|
+
# returned by the API
|
117
|
+
Unauthorized = Class.new(Error)
|
118
|
+
|
119
|
+
# @return [BadRequest] an error to be raised when a status code of 400 is
|
120
|
+
# returned by the API
|
121
|
+
BadRequest = Class.new(Error)
|
122
|
+
|
123
|
+
# @return [NotFound] an error to be raised when a status code of 404 is
|
124
|
+
# returned by the API
|
125
|
+
NotFound = Class.new(Error)
|
126
|
+
|
127
|
+
# @return [InternalServerError] an error to be raised when a status code of
|
128
|
+
# 500 is returned by the API
|
129
|
+
InternalServerError = Class.new(Error)
|
130
|
+
|
131
|
+
# @!endgroup
|
132
|
+
end
|