pwned 1.2.0 → 2.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 +4 -4
- data/.travis.yml +13 -9
- data/.yardopts +1 -0
- data/CHANGELOG.md +70 -15
- data/README.md +139 -10
- data/bin/pwned +52 -0
- data/lib/pwned.rb +22 -6
- data/lib/pwned/hashed_password.rb +35 -0
- data/lib/pwned/not_pwned_validator.rb +17 -3
- data/lib/pwned/password.rb +11 -96
- data/lib/pwned/password_base.rb +133 -0
- data/lib/pwned/version.rb +1 -1
- data/pwned.gemspec +11 -2
- metadata +25 -30
- data/docs/NotPwnedValidator.html +0 -425
- data/docs/Pwned.html +0 -513
- data/docs/Pwned/Error.html +0 -149
- data/docs/Pwned/Password.html +0 -925
- data/docs/Pwned/TimeoutError.html +0 -152
- data/docs/PwnedValidator.html +0 -192
- data/docs/_index.html +0 -162
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -499
- data/docs/file.README.html +0 -292
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -292
- data/docs/js/app.js +0 -248
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -115
- data/docs/top-level-namespace.html +0 -112
data/docs/file.README.html
DELETED
@@ -1,292 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta charset="UTF-8">
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
-
<title>
|
7
|
-
File: README
|
8
|
-
|
9
|
-
— Documentation by YARD 0.9.12
|
10
|
-
|
11
|
-
</title>
|
12
|
-
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
14
|
-
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
|
-
|
17
|
-
<script type="text/javascript" charset="utf-8">
|
18
|
-
pathId = "README";
|
19
|
-
relpath = '';
|
20
|
-
</script>
|
21
|
-
|
22
|
-
|
23
|
-
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
-
|
25
|
-
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
-
|
27
|
-
|
28
|
-
</head>
|
29
|
-
<body>
|
30
|
-
<div class="nav_wrap">
|
31
|
-
<iframe id="nav" src="file_list.html?1"></iframe>
|
32
|
-
<div id="resizer"></div>
|
33
|
-
</div>
|
34
|
-
|
35
|
-
<div id="main" tabindex="-1">
|
36
|
-
<div id="header">
|
37
|
-
<div id="menu">
|
38
|
-
|
39
|
-
<a href="_index.html">Index</a> »
|
40
|
-
<span class="title">File: README</span>
|
41
|
-
|
42
|
-
</div>
|
43
|
-
|
44
|
-
<div id="search">
|
45
|
-
|
46
|
-
<a class="full_list_link" id="class_list_link"
|
47
|
-
href="class_list.html">
|
48
|
-
|
49
|
-
<svg width="24" height="24">
|
50
|
-
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
51
|
-
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
52
|
-
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
-
</svg>
|
54
|
-
</a>
|
55
|
-
|
56
|
-
</div>
|
57
|
-
<div class="clear"></div>
|
58
|
-
</div>
|
59
|
-
|
60
|
-
<div id="content"><div id='filecontents'>
|
61
|
-
<h1 id="label-Pwned">Pwned</h1>
|
62
|
-
|
63
|
-
<p>An easy, Ruby way to use the Pwned Passwords API.</p>
|
64
|
-
|
65
|
-
<p><a href="https://rubygems.org/gems/pwned"><img
|
66
|
-
src="https://badge.fury.io/rb/pwned.svg"></a> <a
|
67
|
-
href="https://travis-ci.org/philnash/pwned"><img
|
68
|
-
src="https://travis-ci.org/philnash/pwned.svg?branch=master"></a> <a
|
69
|
-
href="https://codeclimate.com/github/philnash/pwned/maintainability"><img
|
70
|
-
src="https://codeclimate.com/github/philnash/pwned/badges/gpa.svg"></a></p>
|
71
|
-
|
72
|
-
<p><a href="https://philnash.github.io/pwned/">API docs</a> | <a
|
73
|
-
href="https://github.com/philnash/pwned">GitHub repo</a></p>
|
74
|
-
|
75
|
-
<h2 id="label-About">About</h2>
|
76
|
-
|
77
|
-
<p>Troy Hunt's <a
|
78
|
-
href="https://haveibeenpwned.com/API/v2#PwnedPasswords">Pwned Passwords API
|
79
|
-
V2</a> allows you to check if a password has been found in any of the huge
|
80
|
-
data breaches.</p>
|
81
|
-
|
82
|
-
<p><code>Pwned</code> is a Ruby library to use the Pwned Passwords API's
|
83
|
-
<a
|
84
|
-
href="https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/#cloudflareprivacyandkanonymity">k-Anonymity
|
85
|
-
model</a> to test a password against the API without sending the entire
|
86
|
-
password to the service.</p>
|
87
|
-
|
88
|
-
<p>The data from this API is provided by <a
|
89
|
-
href="https://haveibeenpwned.com/">Have I been pwned?</a>. Before using the
|
90
|
-
API, please check <a
|
91
|
-
href="https://haveibeenpwned.com/API/v2#AcceptableUse">the acceptable uses
|
92
|
-
and license of the API</a>.</p>
|
93
|
-
|
94
|
-
<h2 id="label-Installation">Installation</h2>
|
95
|
-
|
96
|
-
<p>Add this line to your application's Gemfile:</p>
|
97
|
-
|
98
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gem'>gem</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>pwned</span><span class='tstring_end'>'</span></span>
|
99
|
-
</code></pre>
|
100
|
-
|
101
|
-
<p>And then execute:</p>
|
102
|
-
|
103
|
-
<pre class="code ruby"><code class="ruby">$ bundle
|
104
|
-
</code></pre>
|
105
|
-
|
106
|
-
<p>Or install it yourself as:</p>
|
107
|
-
|
108
|
-
<pre class="code ruby"><code class="ruby">$ gem install pwned
|
109
|
-
</code></pre>
|
110
|
-
|
111
|
-
<h2 id="label-Usage">Usage</h2>
|
112
|
-
|
113
|
-
<p>To test a password against the API, instantiate a
|
114
|
-
<code>Pwned::Password</code> object and then ask if it is
|
115
|
-
<code>pwned?</code>.</p>
|
116
|
-
|
117
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
118
|
-
<span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned?'>pwned?</span>
|
119
|
-
<span class='comment'>#=> true
|
120
|
-
</span><span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned_count'>pwned_count</span>
|
121
|
-
<span class='comment'>#=> 3303003
|
122
|
-
</span></code></pre>
|
123
|
-
|
124
|
-
<p>You can also check how many times the password appears in the dataset.</p>
|
125
|
-
|
126
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
127
|
-
<span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned_count'>pwned_count</span>
|
128
|
-
<span class='comment'>#=> 3303003
|
129
|
-
</span></code></pre>
|
130
|
-
|
131
|
-
<p>Since you are likely using this as part of a signup flow, it is recommended
|
132
|
-
that you rescue errors so if the service does go down, your user journey is
|
133
|
-
not disturbed.</p>
|
134
|
-
|
135
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>begin</span>
|
136
|
-
<span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
137
|
-
<span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned?'>pwned?</span>
|
138
|
-
<span class='kw'>rescue</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Error.html" title="Pwned::Error (class)">Error</a></span></span> <span class='op'>=></span> <span class='id identifier rubyid_e'>e</span>
|
139
|
-
<span class='comment'># Ummm... don't worry about it, I guess?
|
140
|
-
</span><span class='kw'>end</span>
|
141
|
-
</code></pre>
|
142
|
-
|
143
|
-
<p>Most of the times you only care if the password has been pwned before or
|
144
|
-
not. You can use simplified accessors to check whether the password has
|
145
|
-
been pwned, or how many times it was pwned:</p>
|
146
|
-
|
147
|
-
<pre class="code ruby"><code class="ruby"><span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='period'>.</span><span class='id identifier rubyid_pwned?'><span class='object_link'><a href="Pwned.html#pwned%3F-class_method" title="Pwned.pwned? (method)">pwned?</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
148
|
-
<span class='comment'>#=> true
|
149
|
-
</span><span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='period'>.</span><span class='id identifier rubyid_pwned_count'><span class='object_link'><a href="Pwned.html#pwned_count-class_method" title="Pwned.pwned_count (method)">pwned_count</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
150
|
-
<span class='comment'>#=> 3303003
|
151
|
-
</span></code></pre>
|
152
|
-
|
153
|
-
<h4 id="label-Advanced">Advanced</h4>
|
154
|
-
|
155
|
-
<p>You can set options and headers to be used with <code>open-uri</code> when
|
156
|
-
making the request to the API. HTTP headers must be string keys and the <a
|
157
|
-
href="https://ruby-doc.org/stdlib-2.5.0/libdoc/open-uri/rdoc/OpenURI/OpenRead.html#method-i-open">other
|
158
|
-
options are available in the OpenURI::OpenRead module</a>.</p>
|
159
|
-
|
160
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='lbrace'>{</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>'</span></span> <span class='op'>=></span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Super fun new user agent</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
|
161
|
-
</code></pre>
|
162
|
-
|
163
|
-
<h3 id="label-ActiveRecord+Validator">ActiveRecord Validator</h3>
|
164
|
-
|
165
|
-
<p>There is a custom validator available for your ActiveRecord models:</p>
|
166
|
-
|
167
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
168
|
-
<span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='kw'>true</span>
|
169
|
-
<span class='comment'># or
|
170
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>message:</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>has been pwned %{count} times</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
171
|
-
<span class='kw'>end</span>
|
172
|
-
</code></pre>
|
173
|
-
|
174
|
-
<h4 id="label-I18n">I18n</h4>
|
175
|
-
|
176
|
-
<p>You can change the error message using I18n (use <code>%{count}</code> to
|
177
|
-
interpolate the number of times the password was seen in the data
|
178
|
-
breaches):</p>
|
179
|
-
|
180
|
-
<pre class="code ruby"><code class="ruby">en:
|
181
|
-
errors:
|
182
|
-
messages:
|
183
|
-
not_pwned: has been pwned %{count} times
|
184
|
-
pwned_error: might be pwned
|
185
|
-
</code></pre>
|
186
|
-
|
187
|
-
<h4 id="label-Threshold">Threshold</h4>
|
188
|
-
|
189
|
-
<p>If you are ok with the password appearing a certain number of times before
|
190
|
-
you decide it is invalid, you can set a threshold. The validator will check
|
191
|
-
whether the <code>pwned_count</code> is greater than the threshold.</p>
|
192
|
-
|
193
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
194
|
-
<span class='comment'># The record is marked as valid if the password has been used once in the breached data
|
195
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>threshold:</span> <span class='int'>1</span> <span class='rbrace'>}</span>
|
196
|
-
<span class='kw'>end</span>
|
197
|
-
</code></pre>
|
198
|
-
|
199
|
-
<h4 id="label-Network+Errors+Handling">Network Errors Handling</h4>
|
200
|
-
|
201
|
-
<p>By default the record will be treated as valid when we cannot reach the <a
|
202
|
-
href="https://haveibeenpwned.com/">haveibeenpwned.com</a> servers. This can
|
203
|
-
be changed with the <code>:on_error</code> validator parameter:</p>
|
204
|
-
|
205
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
206
|
-
<span class='comment'># The record is marked as valid on network errors.
|
207
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='kw'>true</span>
|
208
|
-
<span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:valid</span> <span class='rbrace'>}</span>
|
209
|
-
|
210
|
-
<span class='comment'># The record is marked as invalid on network errors
|
211
|
-
</span> <span class='comment'># (error message "could not be verified against the past data breaches".)
|
212
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:invalid</span> <span class='rbrace'>}</span>
|
213
|
-
|
214
|
-
<span class='comment'># The record is marked as invalid on network errors with custom error.
|
215
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:invalid</span><span class='comma'>,</span> <span class='label'>error_message:</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>might be pwned</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
216
|
-
|
217
|
-
<span class='comment'># We will raise an error on network errors.
|
218
|
-
</span> <span class='comment'># This means that `record.valid?` will raise `Pwned::Error`.
|
219
|
-
</span> <span class='comment'># Not recommended to use in production.
|
220
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:raise_error</span> <span class='rbrace'>}</span>
|
221
|
-
|
222
|
-
<span class='comment'># Call custom proc on error. For example, capture errors in Sentry,
|
223
|
-
</span> <span class='comment'># but do not mark the record as invalid.
|
224
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span>
|
225
|
-
<span class='label'>on_error:</span> <span class='tlambda'>-></span><span class='lparen'>(</span><span class='id identifier rubyid_record'>record</span><span class='comma'>,</span> <span class='id identifier rubyid_error'>error</span><span class='rparen'>)</span> <span class='tlambeg'>{</span> <span class='const'>Raven</span><span class='period'>.</span><span class='id identifier rubyid_capture_exception'>capture_exception</span><span class='lparen'>(</span><span class='id identifier rubyid_error'>error</span><span class='rparen'>)</span> <span class='rbrace'>}</span>
|
226
|
-
<span class='rbrace'>}</span>
|
227
|
-
<span class='kw'>end</span>
|
228
|
-
</code></pre>
|
229
|
-
|
230
|
-
<h4 id="label-Custom+Request+Options">Custom Request Options</h4>
|
231
|
-
|
232
|
-
<p>You can configure network requests made from the validator using
|
233
|
-
<code>:request_options</code> (see <a
|
234
|
-
href="http://ruby-doc.org/stdlib-2.5.0/libdoc/open-uri/rdoc/OpenURI/OpenRead.html#method-i-open">OpenURI::OpenRead#open</a>
|
235
|
-
for the list of available options, string keys represent custom network
|
236
|
-
request headers, e.g. <code>"User-Agent"</code>):</p>
|
237
|
-
|
238
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span>
|
239
|
-
<span class='label'>request_options:</span> <span class='lbrace'>{</span> <span class='label'>read_timeout:</span> <span class='int'>5</span><span class='comma'>,</span> <span class='label'>open_timeout:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>"</span></span> <span class='op'>=></span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>Super fun user agent</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
240
|
-
<span class='rbrace'>}</span>
|
241
|
-
</code></pre>
|
242
|
-
|
243
|
-
<h2 id="label-TODO">TODO</h2>
|
244
|
-
<ul><li>
|
245
|
-
<p>[ ] Devise plugin</p>
|
246
|
-
</li></ul>
|
247
|
-
|
248
|
-
<h2 id="label-Development">Development</h2>
|
249
|
-
|
250
|
-
<p>After checking out the repo, run <code>bin/setup</code> to install
|
251
|
-
dependencies. Then, run <code>rake spec</code> to run the tests. You can
|
252
|
-
also run <code>bin/console</code> for an interactive prompt that will allow
|
253
|
-
you to experiment.</p>
|
254
|
-
|
255
|
-
<p>To install this gem onto your local machine, run <code>bundle exec rake
|
256
|
-
install</code>. To release a new version, update the version number in
|
257
|
-
<code>version.rb</code>, and then run <code>bundle exec rake
|
258
|
-
release</code>, which will create a git tag for the version, push git
|
259
|
-
commits and tags, and push the <code>.gem</code> file to <a
|
260
|
-
href="https://rubygems.org">rubygems.org</a>.</p>
|
261
|
-
|
262
|
-
<h2 id="label-Contributing">Contributing</h2>
|
263
|
-
|
264
|
-
<p>Bug reports and pull requests are welcome on GitHub at <a
|
265
|
-
href="https://github.com/philnash/pwned">github.com/philnash/pwned</a>.
|
266
|
-
This project is intended to be a safe, welcoming space for collaboration,
|
267
|
-
and contributors are expected to adhere to the <a
|
268
|
-
href="http://contributor-covenant.org">Contributor Covenant</a> code of
|
269
|
-
conduct.</p>
|
270
|
-
|
271
|
-
<h2 id="label-License">License</h2>
|
272
|
-
|
273
|
-
<p>The gem is available as open source under the terms of the <a
|
274
|
-
href="https://opensource.org/licenses/MIT">MIT License</a>.</p>
|
275
|
-
|
276
|
-
<h2 id="label-Code+of+Conduct">Code of Conduct</h2>
|
277
|
-
|
278
|
-
<p>Everyone interacting in the Pwned project’s codebases, issue trackers, chat
|
279
|
-
rooms and mailing lists is expected to follow the <a
|
280
|
-
href="https://github.com/philnash/pwned/blob/master/CODE_OF_CONDUCT.md">code
|
281
|
-
of conduct</a>.</p>
|
282
|
-
</div></div>
|
283
|
-
|
284
|
-
<div id="footer">
|
285
|
-
Generated on Wed Mar 14 11:06:58 2018 by
|
286
|
-
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
287
|
-
0.9.12 (ruby-2.5.0).
|
288
|
-
</div>
|
289
|
-
|
290
|
-
</div>
|
291
|
-
</body>
|
292
|
-
</html>
|
data/docs/file_list.html
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
5
|
-
<meta charset="utf-8" />
|
6
|
-
|
7
|
-
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" charset="utf-8" />
|
8
|
-
|
9
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
14
|
-
|
15
|
-
<script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
|
16
|
-
|
17
|
-
|
18
|
-
<title>File List</title>
|
19
|
-
<base id="base_target" target="_parent" />
|
20
|
-
</head>
|
21
|
-
<body>
|
22
|
-
<div id="content">
|
23
|
-
<div class="fixed_header">
|
24
|
-
<h1 id="full_list_header">File List</h1>
|
25
|
-
<div id="full_list_nav">
|
26
|
-
|
27
|
-
<span><a target="_self" href="class_list.html">
|
28
|
-
Classes
|
29
|
-
</a></span>
|
30
|
-
|
31
|
-
<span><a target="_self" href="method_list.html">
|
32
|
-
Methods
|
33
|
-
</a></span>
|
34
|
-
|
35
|
-
<span><a target="_self" href="file_list.html">
|
36
|
-
Files
|
37
|
-
</a></span>
|
38
|
-
|
39
|
-
</div>
|
40
|
-
|
41
|
-
<div id="search">Search: <input type="text" /></div>
|
42
|
-
</div>
|
43
|
-
|
44
|
-
<ul id="full_list" class="file">
|
45
|
-
|
46
|
-
|
47
|
-
<li id="object_README" class="odd">
|
48
|
-
<div class="item"><span class="object_link"><a href="index.html" title="README">README</a></span></div>
|
49
|
-
</li>
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
</ul>
|
54
|
-
</div>
|
55
|
-
</body>
|
56
|
-
</html>
|
data/docs/frames.html
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta charset="utf-8">
|
5
|
-
<title>Documentation by YARD 0.9.12</title>
|
6
|
-
</head>
|
7
|
-
<script type="text/javascript" charset="utf-8">
|
8
|
-
var match = unescape(window.location.hash).match(/^#!(.+)/);
|
9
|
-
var name = match ? match[1] : 'index.html';
|
10
|
-
name = name.replace(/^(\w+):\/\//, '').replace(/^\/\//, '');
|
11
|
-
window.top.location = name;
|
12
|
-
</script>
|
13
|
-
<noscript>
|
14
|
-
<h1>Oops!</h1>
|
15
|
-
<h2>YARD requires JavaScript!</h2>
|
16
|
-
</noscript>
|
17
|
-
</html>
|
data/docs/index.html
DELETED
@@ -1,292 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta charset="UTF-8">
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
-
<title>
|
7
|
-
File: README
|
8
|
-
|
9
|
-
— Documentation by YARD 0.9.12
|
10
|
-
|
11
|
-
</title>
|
12
|
-
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
14
|
-
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
|
-
|
17
|
-
<script type="text/javascript" charset="utf-8">
|
18
|
-
pathId = "README";
|
19
|
-
relpath = '';
|
20
|
-
</script>
|
21
|
-
|
22
|
-
|
23
|
-
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
-
|
25
|
-
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
-
|
27
|
-
|
28
|
-
</head>
|
29
|
-
<body>
|
30
|
-
<div class="nav_wrap">
|
31
|
-
<iframe id="nav" src="class_list.html?1"></iframe>
|
32
|
-
<div id="resizer"></div>
|
33
|
-
</div>
|
34
|
-
|
35
|
-
<div id="main" tabindex="-1">
|
36
|
-
<div id="header">
|
37
|
-
<div id="menu">
|
38
|
-
|
39
|
-
<a href="_index.html">Index</a> »
|
40
|
-
<span class="title">File: README</span>
|
41
|
-
|
42
|
-
</div>
|
43
|
-
|
44
|
-
<div id="search">
|
45
|
-
|
46
|
-
<a class="full_list_link" id="class_list_link"
|
47
|
-
href="class_list.html">
|
48
|
-
|
49
|
-
<svg width="24" height="24">
|
50
|
-
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
51
|
-
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
52
|
-
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
-
</svg>
|
54
|
-
</a>
|
55
|
-
|
56
|
-
</div>
|
57
|
-
<div class="clear"></div>
|
58
|
-
</div>
|
59
|
-
|
60
|
-
<div id="content"><div id='filecontents'>
|
61
|
-
<h1 id="label-Pwned">Pwned</h1>
|
62
|
-
|
63
|
-
<p>An easy, Ruby way to use the Pwned Passwords API.</p>
|
64
|
-
|
65
|
-
<p><a href="https://rubygems.org/gems/pwned"><img
|
66
|
-
src="https://badge.fury.io/rb/pwned.svg"></a> <a
|
67
|
-
href="https://travis-ci.org/philnash/pwned"><img
|
68
|
-
src="https://travis-ci.org/philnash/pwned.svg?branch=master"></a> <a
|
69
|
-
href="https://codeclimate.com/github/philnash/pwned/maintainability"><img
|
70
|
-
src="https://codeclimate.com/github/philnash/pwned/badges/gpa.svg"></a></p>
|
71
|
-
|
72
|
-
<p><a href="https://philnash.github.io/pwned/">API docs</a> | <a
|
73
|
-
href="https://github.com/philnash/pwned">GitHub repo</a></p>
|
74
|
-
|
75
|
-
<h2 id="label-About">About</h2>
|
76
|
-
|
77
|
-
<p>Troy Hunt's <a
|
78
|
-
href="https://haveibeenpwned.com/API/v2#PwnedPasswords">Pwned Passwords API
|
79
|
-
V2</a> allows you to check if a password has been found in any of the huge
|
80
|
-
data breaches.</p>
|
81
|
-
|
82
|
-
<p><code>Pwned</code> is a Ruby library to use the Pwned Passwords API's
|
83
|
-
<a
|
84
|
-
href="https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/#cloudflareprivacyandkanonymity">k-Anonymity
|
85
|
-
model</a> to test a password against the API without sending the entire
|
86
|
-
password to the service.</p>
|
87
|
-
|
88
|
-
<p>The data from this API is provided by <a
|
89
|
-
href="https://haveibeenpwned.com/">Have I been pwned?</a>. Before using the
|
90
|
-
API, please check <a
|
91
|
-
href="https://haveibeenpwned.com/API/v2#AcceptableUse">the acceptable uses
|
92
|
-
and license of the API</a>.</p>
|
93
|
-
|
94
|
-
<h2 id="label-Installation">Installation</h2>
|
95
|
-
|
96
|
-
<p>Add this line to your application's Gemfile:</p>
|
97
|
-
|
98
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gem'>gem</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>pwned</span><span class='tstring_end'>'</span></span>
|
99
|
-
</code></pre>
|
100
|
-
|
101
|
-
<p>And then execute:</p>
|
102
|
-
|
103
|
-
<pre class="code ruby"><code class="ruby">$ bundle
|
104
|
-
</code></pre>
|
105
|
-
|
106
|
-
<p>Or install it yourself as:</p>
|
107
|
-
|
108
|
-
<pre class="code ruby"><code class="ruby">$ gem install pwned
|
109
|
-
</code></pre>
|
110
|
-
|
111
|
-
<h2 id="label-Usage">Usage</h2>
|
112
|
-
|
113
|
-
<p>To test a password against the API, instantiate a
|
114
|
-
<code>Pwned::Password</code> object and then ask if it is
|
115
|
-
<code>pwned?</code>.</p>
|
116
|
-
|
117
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
118
|
-
<span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned?'>pwned?</span>
|
119
|
-
<span class='comment'>#=> true
|
120
|
-
</span><span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned_count'>pwned_count</span>
|
121
|
-
<span class='comment'>#=> 3303003
|
122
|
-
</span></code></pre>
|
123
|
-
|
124
|
-
<p>You can also check how many times the password appears in the dataset.</p>
|
125
|
-
|
126
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
127
|
-
<span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned_count'>pwned_count</span>
|
128
|
-
<span class='comment'>#=> 3303003
|
129
|
-
</span></code></pre>
|
130
|
-
|
131
|
-
<p>Since you are likely using this as part of a signup flow, it is recommended
|
132
|
-
that you rescue errors so if the service does go down, your user journey is
|
133
|
-
not disturbed.</p>
|
134
|
-
|
135
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>begin</span>
|
136
|
-
<span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
137
|
-
<span class='id identifier rubyid_password'>password</span><span class='period'>.</span><span class='id identifier rubyid_pwned?'>pwned?</span>
|
138
|
-
<span class='kw'>rescue</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Error.html" title="Pwned::Error (class)">Error</a></span></span> <span class='op'>=></span> <span class='id identifier rubyid_e'>e</span>
|
139
|
-
<span class='comment'># Ummm... don't worry about it, I guess?
|
140
|
-
</span><span class='kw'>end</span>
|
141
|
-
</code></pre>
|
142
|
-
|
143
|
-
<p>Most of the times you only care if the password has been pwned before or
|
144
|
-
not. You can use simplified accessors to check whether the password has
|
145
|
-
been pwned, or how many times it was pwned:</p>
|
146
|
-
|
147
|
-
<pre class="code ruby"><code class="ruby"><span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='period'>.</span><span class='id identifier rubyid_pwned?'><span class='object_link'><a href="Pwned.html#pwned%3F-class_method" title="Pwned.pwned? (method)">pwned?</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
148
|
-
<span class='comment'>#=> true
|
149
|
-
</span><span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='period'>.</span><span class='id identifier rubyid_pwned_count'><span class='object_link'><a href="Pwned.html#pwned_count-class_method" title="Pwned.pwned_count (method)">pwned_count</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
150
|
-
<span class='comment'>#=> 3303003
|
151
|
-
</span></code></pre>
|
152
|
-
|
153
|
-
<h4 id="label-Advanced">Advanced</h4>
|
154
|
-
|
155
|
-
<p>You can set options and headers to be used with <code>open-uri</code> when
|
156
|
-
making the request to the API. HTTP headers must be string keys and the <a
|
157
|
-
href="https://ruby-doc.org/stdlib-2.5.0/libdoc/open-uri/rdoc/OpenURI/OpenRead.html#method-i-open">other
|
158
|
-
options are available in the OpenURI::OpenRead module</a>.</p>
|
159
|
-
|
160
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_password'>password</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Pwned.html" title="Pwned (module)">Pwned</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Pwned/Password.html" title="Pwned::Password (class)">Password</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Pwned/Password.html#initialize-instance_method" title="Pwned::Password#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>password</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='lbrace'>{</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>'</span></span> <span class='op'>=></span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Super fun new user agent</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
|
161
|
-
</code></pre>
|
162
|
-
|
163
|
-
<h3 id="label-ActiveRecord+Validator">ActiveRecord Validator</h3>
|
164
|
-
|
165
|
-
<p>There is a custom validator available for your ActiveRecord models:</p>
|
166
|
-
|
167
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
168
|
-
<span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='kw'>true</span>
|
169
|
-
<span class='comment'># or
|
170
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>message:</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>has been pwned %{count} times</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
171
|
-
<span class='kw'>end</span>
|
172
|
-
</code></pre>
|
173
|
-
|
174
|
-
<h4 id="label-I18n">I18n</h4>
|
175
|
-
|
176
|
-
<p>You can change the error message using I18n (use <code>%{count}</code> to
|
177
|
-
interpolate the number of times the password was seen in the data
|
178
|
-
breaches):</p>
|
179
|
-
|
180
|
-
<pre class="code ruby"><code class="ruby">en:
|
181
|
-
errors:
|
182
|
-
messages:
|
183
|
-
not_pwned: has been pwned %{count} times
|
184
|
-
pwned_error: might be pwned
|
185
|
-
</code></pre>
|
186
|
-
|
187
|
-
<h4 id="label-Threshold">Threshold</h4>
|
188
|
-
|
189
|
-
<p>If you are ok with the password appearing a certain number of times before
|
190
|
-
you decide it is invalid, you can set a threshold. The validator will check
|
191
|
-
whether the <code>pwned_count</code> is greater than the threshold.</p>
|
192
|
-
|
193
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
194
|
-
<span class='comment'># The record is marked as valid if the password has been used once in the breached data
|
195
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>threshold:</span> <span class='int'>1</span> <span class='rbrace'>}</span>
|
196
|
-
<span class='kw'>end</span>
|
197
|
-
</code></pre>
|
198
|
-
|
199
|
-
<h4 id="label-Network+Errors+Handling">Network Errors Handling</h4>
|
200
|
-
|
201
|
-
<p>By default the record will be treated as valid when we cannot reach the <a
|
202
|
-
href="https://haveibeenpwned.com/">haveibeenpwned.com</a> servers. This can
|
203
|
-
be changed with the <code>:on_error</code> validator parameter:</p>
|
204
|
-
|
205
|
-
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
206
|
-
<span class='comment'># The record is marked as valid on network errors.
|
207
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='kw'>true</span>
|
208
|
-
<span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:valid</span> <span class='rbrace'>}</span>
|
209
|
-
|
210
|
-
<span class='comment'># The record is marked as invalid on network errors
|
211
|
-
</span> <span class='comment'># (error message "could not be verified against the past data breaches".)
|
212
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:invalid</span> <span class='rbrace'>}</span>
|
213
|
-
|
214
|
-
<span class='comment'># The record is marked as invalid on network errors with custom error.
|
215
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:invalid</span><span class='comma'>,</span> <span class='label'>error_message:</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>might be pwned</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
216
|
-
|
217
|
-
<span class='comment'># We will raise an error on network errors.
|
218
|
-
</span> <span class='comment'># This means that `record.valid?` will raise `Pwned::Error`.
|
219
|
-
</span> <span class='comment'># Not recommended to use in production.
|
220
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span> <span class='label'>on_error:</span> <span class='symbol'>:raise_error</span> <span class='rbrace'>}</span>
|
221
|
-
|
222
|
-
<span class='comment'># Call custom proc on error. For example, capture errors in Sentry,
|
223
|
-
</span> <span class='comment'># but do not mark the record as invalid.
|
224
|
-
</span> <span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span>
|
225
|
-
<span class='label'>on_error:</span> <span class='tlambda'>-></span><span class='lparen'>(</span><span class='id identifier rubyid_record'>record</span><span class='comma'>,</span> <span class='id identifier rubyid_error'>error</span><span class='rparen'>)</span> <span class='tlambeg'>{</span> <span class='const'>Raven</span><span class='period'>.</span><span class='id identifier rubyid_capture_exception'>capture_exception</span><span class='lparen'>(</span><span class='id identifier rubyid_error'>error</span><span class='rparen'>)</span> <span class='rbrace'>}</span>
|
226
|
-
<span class='rbrace'>}</span>
|
227
|
-
<span class='kw'>end</span>
|
228
|
-
</code></pre>
|
229
|
-
|
230
|
-
<h4 id="label-Custom+Request+Options">Custom Request Options</h4>
|
231
|
-
|
232
|
-
<p>You can configure network requests made from the validator using
|
233
|
-
<code>:request_options</code> (see <a
|
234
|
-
href="http://ruby-doc.org/stdlib-2.5.0/libdoc/open-uri/rdoc/OpenURI/OpenRead.html#method-i-open">OpenURI::OpenRead#open</a>
|
235
|
-
for the list of available options, string keys represent custom network
|
236
|
-
request headers, e.g. <code>"User-Agent"</code>):</p>
|
237
|
-
|
238
|
-
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_validates'>validates</span> <span class='symbol'>:password</span><span class='comma'>,</span> <span class='label'>not_pwned:</span> <span class='lbrace'>{</span>
|
239
|
-
<span class='label'>request_options:</span> <span class='lbrace'>{</span> <span class='label'>read_timeout:</span> <span class='int'>5</span><span class='comma'>,</span> <span class='label'>open_timeout:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>"</span></span> <span class='op'>=></span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>Super fun user agent</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
240
|
-
<span class='rbrace'>}</span>
|
241
|
-
</code></pre>
|
242
|
-
|
243
|
-
<h2 id="label-TODO">TODO</h2>
|
244
|
-
<ul><li>
|
245
|
-
<p>[ ] Devise plugin</p>
|
246
|
-
</li></ul>
|
247
|
-
|
248
|
-
<h2 id="label-Development">Development</h2>
|
249
|
-
|
250
|
-
<p>After checking out the repo, run <code>bin/setup</code> to install
|
251
|
-
dependencies. Then, run <code>rake spec</code> to run the tests. You can
|
252
|
-
also run <code>bin/console</code> for an interactive prompt that will allow
|
253
|
-
you to experiment.</p>
|
254
|
-
|
255
|
-
<p>To install this gem onto your local machine, run <code>bundle exec rake
|
256
|
-
install</code>. To release a new version, update the version number in
|
257
|
-
<code>version.rb</code>, and then run <code>bundle exec rake
|
258
|
-
release</code>, which will create a git tag for the version, push git
|
259
|
-
commits and tags, and push the <code>.gem</code> file to <a
|
260
|
-
href="https://rubygems.org">rubygems.org</a>.</p>
|
261
|
-
|
262
|
-
<h2 id="label-Contributing">Contributing</h2>
|
263
|
-
|
264
|
-
<p>Bug reports and pull requests are welcome on GitHub at <a
|
265
|
-
href="https://github.com/philnash/pwned">github.com/philnash/pwned</a>.
|
266
|
-
This project is intended to be a safe, welcoming space for collaboration,
|
267
|
-
and contributors are expected to adhere to the <a
|
268
|
-
href="http://contributor-covenant.org">Contributor Covenant</a> code of
|
269
|
-
conduct.</p>
|
270
|
-
|
271
|
-
<h2 id="label-License">License</h2>
|
272
|
-
|
273
|
-
<p>The gem is available as open source under the terms of the <a
|
274
|
-
href="https://opensource.org/licenses/MIT">MIT License</a>.</p>
|
275
|
-
|
276
|
-
<h2 id="label-Code+of+Conduct">Code of Conduct</h2>
|
277
|
-
|
278
|
-
<p>Everyone interacting in the Pwned project’s codebases, issue trackers, chat
|
279
|
-
rooms and mailing lists is expected to follow the <a
|
280
|
-
href="https://github.com/philnash/pwned/blob/master/CODE_OF_CONDUCT.md">code
|
281
|
-
of conduct</a>.</p>
|
282
|
-
</div></div>
|
283
|
-
|
284
|
-
<div id="footer">
|
285
|
-
Generated on Wed Mar 14 11:06:58 2018 by
|
286
|
-
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
287
|
-
0.9.12 (ruby-2.5.0).
|
288
|
-
</div>
|
289
|
-
|
290
|
-
</div>
|
291
|
-
</body>
|
292
|
-
</html>
|