hibp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +1 -0
- data/bin/hibp +125 -0
- data/hibp.gemspec +29 -0
- data/lib/hibp.rb +30 -0
- data/lib/hibp/api.rb +18 -0
- data/lib/hibp/http_client.rb +99 -0
- data/lib/hibp/report.rb +24 -0
- data/lib/hibp/version.rb +3 -0
- metadata +173 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Michael Henriksen
|
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
|
+
# Have I Been Pwned?
|
2
|
+
|
3
|
+
A simple tool to check a bunch of email addresses against the [Have I Been Pwned?](https://haveibeenpwned.com/) API.
|
4
|
+
|
5
|
+
![HIBP extracting emails from a web page](http://i.imgur.com/7gIS39J.png)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
$ gem install hibp
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
HIBP supports different ways of feeding it email addresses:
|
14
|
+
|
15
|
+
### Give it a list:
|
16
|
+
|
17
|
+
$ hibp -l "somone@gmail.com,someoneelse@yahoo.com,johndoe@hotmail.com"
|
18
|
+
|
19
|
+
### Find emails in a file
|
20
|
+
|
21
|
+
$ hibp -f /path/to/some/file.txt
|
22
|
+
|
23
|
+
The file does not need to only contain email addresses, they will be extracted with a regular expression.
|
24
|
+
|
25
|
+
### Find emails on a web page
|
26
|
+
|
27
|
+
$ hibp -w http://somecompany.com/about/employees
|
28
|
+
|
29
|
+
Extracts all e-mails on the web page.
|
30
|
+
|
31
|
+
For more options, see `$ hibp --help`.
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create new Pull Request
|
40
|
+
|
41
|
+
## License
|
42
|
+
|
43
|
+
Copyright (c) 2014 Michael Henriksen
|
44
|
+
|
45
|
+
MIT License
|
46
|
+
|
47
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
48
|
+
a copy of this software and associated documentation files (the
|
49
|
+
"Software"), to deal in the Software without restriction, including
|
50
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
51
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
52
|
+
permit persons to whom the Software is furnished to do so, subject to
|
53
|
+
the following conditions:
|
54
|
+
|
55
|
+
The above copyright notice and this permission notice shall be
|
56
|
+
included in all copies or substantial portions of the Software.
|
57
|
+
|
58
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
59
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
60
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
61
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
62
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
63
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
64
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/hibp
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
require 'net/http'
|
6
|
+
require 'methadone'
|
7
|
+
require 'paint'
|
8
|
+
require 'ruby-progressbar'
|
9
|
+
require 'thread/pool'
|
10
|
+
require 'hibp'
|
11
|
+
|
12
|
+
class App
|
13
|
+
include Methadone::Main
|
14
|
+
|
15
|
+
class FileNotReadableError < StandardError; end
|
16
|
+
|
17
|
+
def self.print_report(report)
|
18
|
+
puts Paint["\n [☠] BREACHED ACCOUNTS:", :red]
|
19
|
+
|
20
|
+
report.breached_accounts.each_pair do |email, pwned_websites|
|
21
|
+
puts Paint[" * #{email}: Found in: #{pwned_websites.join(', ')}", :red]
|
22
|
+
end
|
23
|
+
|
24
|
+
puts "\n ---------------------------------------- \n\n"
|
25
|
+
|
26
|
+
puts Paint[" [✔] CLEAN ACCOUNTS:", :green]
|
27
|
+
|
28
|
+
report.clean_accounts.each do |email|
|
29
|
+
puts Paint[" * #{email}", :green]
|
30
|
+
end
|
31
|
+
|
32
|
+
puts "\n"
|
33
|
+
|
34
|
+
if !report.failed_accounts.count.zero?
|
35
|
+
puts "---------------------------------------- \n\n"
|
36
|
+
|
37
|
+
puts Paint[" [⚡] ACCOUNT CHECKS THAT ENCOUNTERED ERROR:", :red]
|
38
|
+
|
39
|
+
report.failed_accounts.each_pair do |email, exception|
|
40
|
+
puts Paint[" * #{email}: #{exception.class}: #{exception.message}", :red]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
main do
|
46
|
+
begin
|
47
|
+
|
48
|
+
if options.include?('no-color')
|
49
|
+
Paint.mode = 0
|
50
|
+
end
|
51
|
+
|
52
|
+
if !options.include?('no-banner')
|
53
|
+
puts Paint[Hibp.banner, :blue]
|
54
|
+
end
|
55
|
+
|
56
|
+
if options[:list]
|
57
|
+
emails = Hibp.extract_emails(options[:list])
|
58
|
+
elsif options[:file]
|
59
|
+
if File.readable?(options[:file])
|
60
|
+
emails = Hibp.extract_emails(File.read(options[:file]))
|
61
|
+
else
|
62
|
+
raise FileNotReadableError.new("#{options[:file]} does not exist or is not readable")
|
63
|
+
end
|
64
|
+
elsif options[:web]
|
65
|
+
http_client = Hibp::HttpClient.new
|
66
|
+
response = http_client.do_get(options[:web])
|
67
|
+
emails = Hibp.extract_emails(response.body)
|
68
|
+
else
|
69
|
+
help_now!("You must give me some e-mails to check...")
|
70
|
+
end
|
71
|
+
|
72
|
+
if emails.count.zero?
|
73
|
+
puts Paint[" Sorry, I could not find any emails to check; exiting.", :red]
|
74
|
+
exit!
|
75
|
+
end
|
76
|
+
|
77
|
+
puts Paint[" Checking #{emails.count} #{emails.count == 1 ? 'email' : 'emails'}...\n", :blue]
|
78
|
+
|
79
|
+
progress_bar = ProgressBar.create(:total => emails.count, :format => ' %a %B %p%% %t |%e')
|
80
|
+
report = Hibp::Report.new
|
81
|
+
thread_pool = Thread.pool(options[:threads].to_i)
|
82
|
+
|
83
|
+
emails.each do |email|
|
84
|
+
thread_pool.process do
|
85
|
+
begin
|
86
|
+
if pwned_websites = Hibp::Api.breached_account?(email)
|
87
|
+
report.add_breached_account(email, pwned_websites)
|
88
|
+
else
|
89
|
+
report.add_clean_account(email)
|
90
|
+
end
|
91
|
+
rescue => ex
|
92
|
+
report.add_failed_account(email, ex)
|
93
|
+
end
|
94
|
+
progress_bar.increment
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
thread_pool.shutdown
|
99
|
+
print_report(report)
|
100
|
+
|
101
|
+
rescue Exception => e
|
102
|
+
if !e.is_a?(Interrupt)
|
103
|
+
puts Paint[" [⚡] WARP CORE BREACH!", :red]
|
104
|
+
puts Paint[" * #{e.class}: #{e.message}", :red]
|
105
|
+
else
|
106
|
+
print_report(report) if defined?(report)
|
107
|
+
exit!
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
options['threads'] = 3
|
113
|
+
|
114
|
+
on("-l EMAILS", "--list", "List of emails")
|
115
|
+
on("-f FILE", "--file", "Path to a file containing emails")
|
116
|
+
on("-w URL", "--web", "URL to extract emails from")
|
117
|
+
on("-t THREADS", "--threads", "Number of concurrent threads to use")
|
118
|
+
on("--no-banner", "Don't display HIBP banner")
|
119
|
+
on("--no-color", "Don't colorize output")
|
120
|
+
|
121
|
+
description "A simple tool to check a bunch of emails against the haveibeenpwned.com API."
|
122
|
+
version Hibp::VERSION
|
123
|
+
|
124
|
+
go!
|
125
|
+
end
|
data/hibp.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hibp/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hibp"
|
8
|
+
spec.version = Hibp::VERSION
|
9
|
+
spec.authors = ["Michael Henriksen"]
|
10
|
+
spec.email = ["michenriksen@neomailbox.ch"]
|
11
|
+
spec.description = %q{A simple tool to check a bunch of email addresses against the Have I Been Pwned? API.}
|
12
|
+
spec.summary = %q{A simple tool to check a bunch of email addresses against the Have I Been Pwned? API.}
|
13
|
+
spec.homepage = "https://github.com/michenriksen/hibp"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'httparty'
|
22
|
+
spec.add_dependency 'methadone'
|
23
|
+
spec.add_dependency 'paint'
|
24
|
+
spec.add_dependency 'ruby-progressbar'
|
25
|
+
spec.add_dependency 'thread'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
28
|
+
spec.add_development_dependency 'rake'
|
29
|
+
end
|
data/lib/hibp.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'httparty'
|
5
|
+
|
6
|
+
require 'hibp/version'
|
7
|
+
require 'hibp/http_client'
|
8
|
+
require 'hibp/api'
|
9
|
+
require 'hibp/report'
|
10
|
+
|
11
|
+
module Hibp
|
12
|
+
EMAIL_REGEX = /[-0-9a-zA-Z.+_]+@[-0-9a-zA-Z.+_]+\.[a-zA-Z]{2,4}/
|
13
|
+
|
14
|
+
def self.banner
|
15
|
+
banner = <<EOB
|
16
|
+
|
17
|
+
### ### # # ### ###### ######
|
18
|
+
### ### # # # # # # #
|
19
|
+
# # # # # # # #
|
20
|
+
# ### ##### ##### ####### # ###### ######
|
21
|
+
### # # # # # #
|
22
|
+
# # # # # # #
|
23
|
+
# # # ### ###### #
|
24
|
+
EOB
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.extract_emails(haystack)
|
28
|
+
haystack.scan(EMAIL_REGEX)
|
29
|
+
end
|
30
|
+
end
|
data/lib/hibp/api.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Hibp
|
2
|
+
class Api
|
3
|
+
BASE_URI = 'https://haveibeenpwned.com/api'
|
4
|
+
|
5
|
+
def self.breached_account?(email)
|
6
|
+
JSON.parse(http_client.do_get("#{BASE_URI}/breachedaccount/#{CGI.escape(email)}").body)
|
7
|
+
rescue Hibp::HttpClient::ClientError => ex
|
8
|
+
return false if ex.status == 404
|
9
|
+
raise ex
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def self.http_client
|
15
|
+
@http_client ||= Hibp::HttpClient.new()
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Hibp
|
2
|
+
class HttpClient
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
class HttpError < StandardError; end
|
6
|
+
class ConnectionError < HttpError; end
|
7
|
+
|
8
|
+
class RequestError < HttpError
|
9
|
+
attr_reader :status, :body
|
10
|
+
|
11
|
+
def initialize(method, path, status, body, options)
|
12
|
+
@status = status
|
13
|
+
@body = body
|
14
|
+
super("#{method} to #{path} returned status #{status} - options: #{options.inspect}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ClientError < RequestError; end
|
19
|
+
class ServerError < RequestError; end
|
20
|
+
|
21
|
+
class UnhandledError < StandardError; end
|
22
|
+
|
23
|
+
DEFAULT_TIMEOUT = 0.5 #seconds
|
24
|
+
DEFAULT_RETRIES = 3
|
25
|
+
|
26
|
+
Response = Struct.new(:status, :headers, :body)
|
27
|
+
|
28
|
+
HANDLED_EXCEPTIONS = [
|
29
|
+
ServerError,
|
30
|
+
ClientError,
|
31
|
+
Timeout::Error,
|
32
|
+
Errno::ETIMEDOUT,
|
33
|
+
Errno::ECONNRESET,
|
34
|
+
Errno::ECONNREFUSED,
|
35
|
+
Errno::ENETUNREACH,
|
36
|
+
Errno::EHOSTUNREACH,
|
37
|
+
EOFError
|
38
|
+
]
|
39
|
+
|
40
|
+
def initialize(config = {})
|
41
|
+
@config = {
|
42
|
+
:timeout => DEFAULT_TIMEOUT,
|
43
|
+
:retries => DEFAULT_RETRIES,
|
44
|
+
}.merge(config)
|
45
|
+
default_timeout = @config[:timeout]
|
46
|
+
end
|
47
|
+
|
48
|
+
def do_get(path, params=nil, opt={})
|
49
|
+
do_request(:get, path, {:query => params}.merge(opt))
|
50
|
+
end
|
51
|
+
|
52
|
+
def do_post(path, params=nil, opt={})
|
53
|
+
do_request(:post, path, {:body => params}.merge(opt))
|
54
|
+
end
|
55
|
+
|
56
|
+
def do_put(path, params=nil, opt={})
|
57
|
+
do_request(:put, path, {:body => params}.merge(opt))
|
58
|
+
end
|
59
|
+
|
60
|
+
def do_delete(path, params=nil, opt={})
|
61
|
+
do_request(:delete, path, {:query => params}.merge(opt))
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def do_request(method, path, options)
|
67
|
+
with_retries do
|
68
|
+
response = self.class.send(method, path, options)
|
69
|
+
|
70
|
+
handle_possible_error(method.to_s.upcase, path, response, options)
|
71
|
+
|
72
|
+
Response.new(response.code, response.headers, response.body)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def handle_possible_error(method, path, response, options)
|
77
|
+
if response.code >= 500
|
78
|
+
raise ServerError.new(method, path, response.code, response.body, options)
|
79
|
+
elsif response.code >= 400
|
80
|
+
raise ClientError.new(method, path, response.code, response.body, options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def with_retries(&block)
|
85
|
+
tries ||= @config[:retries]
|
86
|
+
yield
|
87
|
+
rescue *HANDLED_EXCEPTIONS, ServerError => ex
|
88
|
+
if (tries -= 1) > 0
|
89
|
+
sleep 0.2
|
90
|
+
retry
|
91
|
+
end
|
92
|
+
raise ex
|
93
|
+
rescue ClientError => ex
|
94
|
+
raise ex
|
95
|
+
rescue => ex
|
96
|
+
raise UnhandledError.new(ex.message)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/hibp/report.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Hibp
|
2
|
+
class Report
|
3
|
+
|
4
|
+
attr_reader :breached_accounts, :clean_accounts, :failed_accounts
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@breached_accounts = {}
|
8
|
+
@clean_accounts = []
|
9
|
+
@failed_accounts = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_breached_account(email, pwned_websites)
|
13
|
+
@breached_accounts[email] = pwned_websites
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_clean_account(email)
|
17
|
+
@clean_accounts << email
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_failed_account(email, exception)
|
21
|
+
@failed_accounts[email] = exception
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/hibp/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hibp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael Henriksen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
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'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: methadone
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: paint
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: ruby-progressbar
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: thread
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
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
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: bundler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '1.3'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.3'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rake
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: A simple tool to check a bunch of email addresses against the Have I
|
127
|
+
Been Pwned? API.
|
128
|
+
email:
|
129
|
+
- michenriksen@neomailbox.ch
|
130
|
+
executables:
|
131
|
+
- hibp
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- .gitignore
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- bin/hibp
|
141
|
+
- hibp.gemspec
|
142
|
+
- lib/hibp.rb
|
143
|
+
- lib/hibp/api.rb
|
144
|
+
- lib/hibp/http_client.rb
|
145
|
+
- lib/hibp/report.rb
|
146
|
+
- lib/hibp/version.rb
|
147
|
+
homepage: https://github.com/michenriksen/hibp
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
post_install_message:
|
151
|
+
rdoc_options: []
|
152
|
+
require_paths:
|
153
|
+
- lib
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubyforge_project:
|
168
|
+
rubygems_version: 1.8.28
|
169
|
+
signing_key:
|
170
|
+
specification_version: 3
|
171
|
+
summary: A simple tool to check a bunch of email addresses against the Have I Been
|
172
|
+
Pwned? API.
|
173
|
+
test_files: []
|