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.
@@ -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
- &mdash; 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> &raquo;
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&#39;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&#39;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&#39;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'>&#39;</span><span class='tstring_content'>pwned</span><span class='tstring_end'>&#39;</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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</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'>#=&gt; 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'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</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'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</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'>=&gt;</span> <span class='id identifier rubyid_e'>e</span>
139
- <span class='comment'># Ummm... don&#39;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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
148
- <span class='comment'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
150
- <span class='comment'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='lbrace'>{</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>&#39;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Super fun new user agent</span><span class='tstring_end'>&#39;</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'>&lt;</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'>&quot;</span><span class='tstring_content'>has been pwned %{count} times</span><span class='tstring_end'>&quot;</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'>&lt;</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'>&lt;</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 &quot;could not be verified against the past data breaches&quot;.)
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'>&quot;</span><span class='tstring_content'>might be pwned</span><span class='tstring_end'>&quot;</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'>-&gt;</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>&quot;User-Agent&quot;</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'>&quot;</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Super fun user agent</span><span class='tstring_end'>&quot;</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>
@@ -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>
@@ -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>
@@ -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
- &mdash; 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> &raquo;
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&#39;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&#39;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&#39;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'>&#39;</span><span class='tstring_content'>pwned</span><span class='tstring_end'>&#39;</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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</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'>#=&gt; 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'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</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'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</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'>=&gt;</span> <span class='id identifier rubyid_e'>e</span>
139
- <span class='comment'># Ummm... don&#39;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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
148
- <span class='comment'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
150
- <span class='comment'>#=&gt; 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'>&quot;</span><span class='tstring_content'>password</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='lbrace'>{</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>&#39;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Super fun new user agent</span><span class='tstring_end'>&#39;</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'>&lt;</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'>&quot;</span><span class='tstring_content'>has been pwned %{count} times</span><span class='tstring_end'>&quot;</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'>&lt;</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'>&lt;</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 &quot;could not be verified against the past data breaches&quot;.)
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'>&quot;</span><span class='tstring_content'>might be pwned</span><span class='tstring_end'>&quot;</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'>-&gt;</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>&quot;User-Agent&quot;</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'>&quot;</span><span class='tstring_content'>User-Agent</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Super fun user agent</span><span class='tstring_end'>&quot;</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>