hibp-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +66 -0
- data/.rspec +3 -0
- data/.travis.yml +13 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +189 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/hibp.gemspec +37 -0
- data/lib/hibp.rb +30 -0
- data/lib/hibp/client.rb +162 -0
- data/lib/hibp/helpers/attribute_assignment.rb +40 -0
- data/lib/hibp/helpers/json_conversion.rb +47 -0
- data/lib/hibp/models/breach.rb +115 -0
- data/lib/hibp/models/password.rb +28 -0
- data/lib/hibp/models/paste.rb +62 -0
- data/lib/hibp/parsers/breach.rb +42 -0
- data/lib/hibp/parsers/json.rb +62 -0
- data/lib/hibp/parsers/password.rb +36 -0
- data/lib/hibp/parsers/paste.rb +24 -0
- data/lib/hibp/query.rb +85 -0
- data/lib/hibp/request.rb +106 -0
- data/lib/hibp/service_error.rb +53 -0
- data/lib/hibp/version.rb +5 -0
- metadata +143 -0
data/lib/hibp/query.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hibp
|
4
|
+
# Hibp::Query
|
5
|
+
#
|
6
|
+
# Used to build and execute request to the HIBP API
|
7
|
+
#
|
8
|
+
class Query
|
9
|
+
attr_reader :endpoint, :headers, :parser
|
10
|
+
|
11
|
+
# @param endpoint [String] -
|
12
|
+
# A specific API endpoint to call appropriate method
|
13
|
+
#
|
14
|
+
# @param headers [Hash] -
|
15
|
+
# Specific request headers
|
16
|
+
#
|
17
|
+
# @param parser [Hibp::Parser] -
|
18
|
+
# A tool to parse and convert data into appropriate models
|
19
|
+
#
|
20
|
+
def initialize(endpoint:, headers: {}, parser: Parsers::Json.new)
|
21
|
+
@endpoint = endpoint
|
22
|
+
@headers = headers
|
23
|
+
|
24
|
+
@parser = parser
|
25
|
+
@query_params = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
# Apply query filtration
|
29
|
+
#
|
30
|
+
# @param filters [Hash] - (optional, default: {})
|
31
|
+
# Additional filtration params
|
32
|
+
#
|
33
|
+
# @option filters [String] :domain -
|
34
|
+
# Filters the result set to only breaches against the domain specified.
|
35
|
+
# It is possible that one site (and consequently domain), is compromised on multiple occasions.
|
36
|
+
# (breaches and account_breaches queries)
|
37
|
+
#
|
38
|
+
# @option filters [Boolean] :truncate - (default: true)
|
39
|
+
# Short/Full data switcher(only name or full breach data)
|
40
|
+
# (only for account_breaches query)
|
41
|
+
#
|
42
|
+
# @option filters [Boolean] :unverified -
|
43
|
+
# Returns breaches that have been flagged as "unverified".
|
44
|
+
# (only for account_breaches query)
|
45
|
+
#
|
46
|
+
# @return [Hibp::Query]
|
47
|
+
#
|
48
|
+
def where(filters = {})
|
49
|
+
tap do
|
50
|
+
@query_params.merge!(convert_filters(filters))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Perform query execution(data fetching)
|
55
|
+
#
|
56
|
+
# @return [
|
57
|
+
# Array<String>,
|
58
|
+
# Array<Hibp::Models::Breach>,
|
59
|
+
# Array<Hibp::Models::Paste>,
|
60
|
+
# Hibp::Models::Breach
|
61
|
+
# ]
|
62
|
+
#
|
63
|
+
def fetch
|
64
|
+
confugure_request.get(headers: @headers, params: @query_params)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def confugure_request
|
70
|
+
Request.new(parser: @parser, endpoint: @endpoint)
|
71
|
+
end
|
72
|
+
|
73
|
+
def convert_filters(params)
|
74
|
+
mappings = {
|
75
|
+
truncate: 'truncateResponse',
|
76
|
+
domain: 'domain',
|
77
|
+
unverified: 'includeUnverified'
|
78
|
+
}
|
79
|
+
|
80
|
+
params.each_with_object({}) do |(origin_key, value), acc|
|
81
|
+
acc[mappings.fetch(origin_key)] = value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/hibp/request.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hibp
|
4
|
+
# Hibp::Request
|
5
|
+
#
|
6
|
+
# Used to make requests to the hibp API
|
7
|
+
#
|
8
|
+
# @see https://haveibeenpwned.com/API/v3
|
9
|
+
#
|
10
|
+
class Request
|
11
|
+
attr_reader :headers
|
12
|
+
|
13
|
+
# @param parser [Hibp::Parser] -
|
14
|
+
# A tool to parse and convert data into appropriate models
|
15
|
+
#
|
16
|
+
# @param endpoint [String] -
|
17
|
+
# A specific API endpoint to call appropriate method
|
18
|
+
#
|
19
|
+
def initialize(endpoint:, parser: Parsers::Json.new)
|
20
|
+
@endpoint = endpoint
|
21
|
+
@parser = parser
|
22
|
+
|
23
|
+
@headers = {
|
24
|
+
'Content-Type' => 'application/json',
|
25
|
+
'User-Agent' => "Ruby HIBP-Client #{Hibp::VERSION}"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Perform a GET request
|
30
|
+
#
|
31
|
+
# @param params [Hash] -
|
32
|
+
# Additional query params
|
33
|
+
#
|
34
|
+
# @param headers [Hash] -
|
35
|
+
# Additional HTTP headers
|
36
|
+
#
|
37
|
+
# @raise [Hibp::ServiceError]
|
38
|
+
#
|
39
|
+
def get(params: nil, headers: nil)
|
40
|
+
response = rest_client.get(@endpoint) do |request|
|
41
|
+
configure_request(request: request, params: params, headers: headers)
|
42
|
+
end
|
43
|
+
|
44
|
+
@parser ? @parser.parse_response(response) : response.body
|
45
|
+
rescue Faraday::ClientError::ResourceNotFound
|
46
|
+
nil
|
47
|
+
rescue StandardError => e
|
48
|
+
handle_error(e)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def rest_client
|
54
|
+
Faraday.new do |faraday|
|
55
|
+
faraday.headers = @headers
|
56
|
+
|
57
|
+
faraday.response(:raise_error)
|
58
|
+
faraday.adapter(Faraday.default_adapter)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def configure_request(request: nil, params: nil, headers: nil, body: nil)
|
63
|
+
return if request.nil?
|
64
|
+
|
65
|
+
request.params.merge!(params) if params
|
66
|
+
request.headers.merge!(headers) if headers
|
67
|
+
request.body = body if body
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle_error(error)
|
71
|
+
error_params = parsable_error?(error) ? parse_error(error) : {}
|
72
|
+
|
73
|
+
error_to_raise = ServiceError.new(error.message, error_params)
|
74
|
+
|
75
|
+
raise error_to_raise
|
76
|
+
end
|
77
|
+
|
78
|
+
def parsable_error?(error)
|
79
|
+
error.is_a?(Faraday::Error::ClientError) && error.response
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_error(error)
|
83
|
+
error_params = {
|
84
|
+
status_code: error.response[:status],
|
85
|
+
raw_body: error.response[:body]
|
86
|
+
}
|
87
|
+
|
88
|
+
begin
|
89
|
+
parsed_response = Oj.load(error.response[:body], {})
|
90
|
+
|
91
|
+
return error_params unless parsed_response
|
92
|
+
|
93
|
+
error_params[:body] = parsed_response
|
94
|
+
|
95
|
+
%w[title detail].each do |section|
|
96
|
+
next if parsed_response[section].nil?
|
97
|
+
|
98
|
+
error_params[section.to_sym] = parsed_response[section]
|
99
|
+
end
|
100
|
+
rescue Oj::ParseError
|
101
|
+
end
|
102
|
+
|
103
|
+
error_params
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hibp
|
4
|
+
# Hibp::ServiceError
|
5
|
+
#
|
6
|
+
# Used to represent an error that may occur when performing a request to the API
|
7
|
+
#
|
8
|
+
class ServiceError < StandardError
|
9
|
+
attr_reader :body, :raw_body, :status_code
|
10
|
+
|
11
|
+
# @param message [String] - (optional, '') Message to describe an error
|
12
|
+
# @param params [Hash] - (optional, {}) Additional error information
|
13
|
+
#
|
14
|
+
# @option params [String] :body -
|
15
|
+
# A JSON formatted error object that provides more details about the specifics of the error
|
16
|
+
#
|
17
|
+
# @option params [String] :title -
|
18
|
+
# Error summary
|
19
|
+
#
|
20
|
+
# @option params [String] :detail -
|
21
|
+
# Error detailed description
|
22
|
+
#
|
23
|
+
# @option params [String] :raw_body -
|
24
|
+
# Raw body from response
|
25
|
+
#
|
26
|
+
# @option params [String] :status_code -
|
27
|
+
# Http status code
|
28
|
+
#
|
29
|
+
def initialize(message = '', params = {})
|
30
|
+
@body = params[:body]
|
31
|
+
@raw_body = params[:raw_body]
|
32
|
+
@status_code = params[:status_code]
|
33
|
+
|
34
|
+
super(message)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
"#{super} #{instance_variables_to_s}"
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def instance_variables_to_s
|
44
|
+
attr_values = %i[body raw_body status_code].map do |attr|
|
45
|
+
attr_value = send(attr)
|
46
|
+
|
47
|
+
"@#{attr}=#{attr_value.inspect}"
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_values.join(', ')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/hibp/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hibp-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Warshavski
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.9.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.9.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: oj
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.6.13
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.6.13
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
description: A simple tool to check if an account(email address and username) has
|
84
|
+
been compromised in a data breach
|
85
|
+
email:
|
86
|
+
- p.warshavski@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/setup
|
100
|
+
- hibp.gemspec
|
101
|
+
- lib/hibp.rb
|
102
|
+
- lib/hibp/client.rb
|
103
|
+
- lib/hibp/helpers/attribute_assignment.rb
|
104
|
+
- lib/hibp/helpers/json_conversion.rb
|
105
|
+
- lib/hibp/models/breach.rb
|
106
|
+
- lib/hibp/models/password.rb
|
107
|
+
- lib/hibp/models/paste.rb
|
108
|
+
- lib/hibp/parsers/breach.rb
|
109
|
+
- lib/hibp/parsers/json.rb
|
110
|
+
- lib/hibp/parsers/password.rb
|
111
|
+
- lib/hibp/parsers/paste.rb
|
112
|
+
- lib/hibp/query.rb
|
113
|
+
- lib/hibp/request.rb
|
114
|
+
- lib/hibp/service_error.rb
|
115
|
+
- lib/hibp/version.rb
|
116
|
+
homepage: https://github.com/Warshavski/hibp
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata:
|
120
|
+
homepage_uri: https://github.com/Warshavski/hibp
|
121
|
+
source_code_uri: https://github.com/Warshavski/hibp
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.7.6
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: A simple tool to check if an account(email address and username) has been
|
142
|
+
compromised in a data breach
|
143
|
+
test_files: []
|