crypt_ident 0.2.1

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.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rubocop.yml +29 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +7 -0
  6. data/.yardopts +16 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +263 -0
  10. data/Guardfile +26 -0
  11. data/HISTORY.md +22 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +548 -0
  14. data/Rakefile +93 -0
  15. data/bin/_guard-core +29 -0
  16. data/bin/bundle +105 -0
  17. data/bin/byebug +29 -0
  18. data/bin/code_climate_reek +29 -0
  19. data/bin/coderay +29 -0
  20. data/bin/commonmarker +29 -0
  21. data/bin/console +14 -0
  22. data/bin/erubis +29 -0
  23. data/bin/flay +29 -0
  24. data/bin/flog +29 -0
  25. data/bin/github-markup +29 -0
  26. data/bin/guard +29 -0
  27. data/bin/inch +29 -0
  28. data/bin/kwalify +29 -0
  29. data/bin/listen +29 -0
  30. data/bin/pry +29 -0
  31. data/bin/rackup +29 -0
  32. data/bin/rake +29 -0
  33. data/bin/redcarpet +29 -0
  34. data/bin/reek +29 -0
  35. data/bin/rubocop +29 -0
  36. data/bin/ruby-parse +29 -0
  37. data/bin/ruby-rewrite +29 -0
  38. data/bin/ruby_parse +29 -0
  39. data/bin/ruby_parse_extract_error +29 -0
  40. data/bin/sequel +29 -0
  41. data/bin/setup +34 -0
  42. data/bin/sparkr +29 -0
  43. data/bin/term_cdiff +29 -0
  44. data/bin/term_colortab +29 -0
  45. data/bin/term_decolor +29 -0
  46. data/bin/term_display +29 -0
  47. data/bin/term_mandel +29 -0
  48. data/bin/term_snow +29 -0
  49. data/bin/thor +29 -0
  50. data/bin/yard +29 -0
  51. data/bin/yardoc +29 -0
  52. data/bin/yri +29 -0
  53. data/config.reek +19 -0
  54. data/crypt_ident.gemspec +80 -0
  55. data/docs/CryptIdent.html +2276 -0
  56. data/docs/_index.html +116 -0
  57. data/docs/class_list.html +51 -0
  58. data/docs/css/common.css +1 -0
  59. data/docs/css/full_list.css +58 -0
  60. data/docs/css/style.css +496 -0
  61. data/docs/file.CODE_OF_CONDUCT.html +145 -0
  62. data/docs/file.HISTORY.html +91 -0
  63. data/docs/file.LICENSE.html +70 -0
  64. data/docs/file.README.html +692 -0
  65. data/docs/file_list.html +71 -0
  66. data/docs/frames.html +17 -0
  67. data/docs/index.html +692 -0
  68. data/docs/js/app.js +292 -0
  69. data/docs/js/full_list.js +216 -0
  70. data/docs/js/jquery.js +4 -0
  71. data/docs/method_list.html +115 -0
  72. data/docs/top-level-namespace.html +110 -0
  73. data/lib/crypt_ident.rb +13 -0
  74. data/lib/crypt_ident/change_password.rb +184 -0
  75. data/lib/crypt_ident/config.rb +47 -0
  76. data/lib/crypt_ident/generate_reset_token.rb +212 -0
  77. data/lib/crypt_ident/reset_password.rb +207 -0
  78. data/lib/crypt_ident/session_expired.rb +91 -0
  79. data/lib/crypt_ident/sign_in.rb +189 -0
  80. data/lib/crypt_ident/sign_out.rb +96 -0
  81. data/lib/crypt_ident/sign_up.rb +160 -0
  82. data/lib/crypt_ident/update_session_expiry.rb +125 -0
  83. data/lib/crypt_ident/version.rb +6 -0
  84. data/scripts/build-gem-list.rb +91 -0
  85. metadata +547 -0
@@ -0,0 +1,2276 @@
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
+ Module: CryptIdent
8
+
9
+ &mdash; crypt_ident Module Documentation
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 = "CryptIdent";
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 (C)</a> &raquo;
40
+
41
+
42
+ <span class="title">CryptIdent</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Module: CryptIdent
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+ <dl>
73
+ <dt>Extended by:</dt>
74
+ <dd>Dry::Configurable</dd>
75
+ </dl>
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+ <dl>
85
+ <dt>Defined in:</dt>
86
+ <dd>lib/crypt_ident/config.rb<span class="defines">,<br />
87
+ lib/crypt_ident/sign_in.rb,<br /> lib/crypt_ident/sign_up.rb,<br /> lib/crypt_ident/version.rb,<br /> lib/crypt_ident/sign_out.rb,<br /> lib/crypt_ident/reset_password.rb,<br /> lib/crypt_ident/change_password.rb,<br /> lib/crypt_ident/session_expired.rb,<br /> lib/crypt_ident/generate_reset_token.rb,<br /> lib/crypt_ident/update_session_expiry.rb</span>
88
+ </dd>
89
+ </dl>
90
+
91
+ </div>
92
+
93
+ <h2>Overview</h2><div class="docstring">
94
+ <div class="discussion">
95
+ <p>Include and interact with <code>CryptIdent</code> to add authentication to a
96
+ Hanami controller action.</p>
97
+
98
+ <p>Note the emphasis on <em>controller action</em>; this module interacts with session
99
+ data, which is quite theoretically possible in an Interactor but practically
100
+ <em>quite</em> the PITA. YHBW.</p>
101
+
102
+
103
+ </div>
104
+ </div>
105
+ <div class="tags">
106
+
107
+ <p class="tag_title">Author:</p>
108
+ <ul class="author">
109
+
110
+ <li>
111
+
112
+
113
+
114
+
115
+
116
+ <div class='inline'><p>Jeff Dickey</p>
117
+ </div>
118
+
119
+ </li>
120
+
121
+ </ul>
122
+ <p class="tag_title">Version:</p>
123
+ <ul class="version">
124
+
125
+ <li>
126
+
127
+
128
+
129
+
130
+
131
+ <div class='inline'><p>0.2.0</p>
132
+ </div>
133
+
134
+ </li>
135
+
136
+ </ul>
137
+
138
+ </div>
139
+
140
+ <h2>
141
+ Constant Summary
142
+ <small><a href="#" class="constants_summary_toggle">collapse</a></small>
143
+ </h2>
144
+
145
+ <dl class="constants">
146
+
147
+ <dt id="VERSION-constant" class="">VERSION =
148
+ <div class="docstring">
149
+ <div class="discussion">
150
+ <p>Version number for Gem. Uses Semantic Versioning.</p>
151
+
152
+
153
+ </div>
154
+ </div>
155
+ <div class="tags">
156
+
157
+
158
+ </div>
159
+ </dt>
160
+ <dd><pre class="code"><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>0.2.1</span><span class='tstring_end'>&#39;</span></span></pre></dd>
161
+
162
+ </dl>
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+ <h2>
173
+ Instance Method Summary
174
+ <small><a href="#" class="summary_toggle">collapse</a></small>
175
+ </h2>
176
+
177
+ <ul class="summary">
178
+
179
+ <li class="public ">
180
+ <span class="summary_signature">
181
+
182
+ <a href="#change_password-instance_method" title="#change_password (instance method)">#<strong>change_password</strong>(user_in, current_password, new_password) {|result| ... } </a>
183
+
184
+
185
+
186
+ </span>
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+ <span class="summary_desc"><div class='inline'><p>Change an Authenticated User&#39;s password.</p>
197
+ </div></span>
198
+
199
+ </li>
200
+
201
+
202
+ <li class="public ">
203
+ <span class="summary_signature">
204
+
205
+ <a href="#generate_reset_token-instance_method" title="#generate_reset_token (instance method)">#<strong>generate_reset_token</strong>(user_name, current_user: nil) {|result| ... } </a>
206
+
207
+
208
+
209
+ </span>
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+ <span class="summary_desc"><div class='inline'><p>Generate a Password Reset Token.</p>
220
+ </div></span>
221
+
222
+ </li>
223
+
224
+
225
+ <li class="public ">
226
+ <span class="summary_signature">
227
+
228
+ <a href="#reset_password-instance_method" title="#reset_password (instance method)">#<strong>reset_password</strong>(token, new_password, current_user: nil) {|result| ... } </a>
229
+
230
+
231
+
232
+ </span>
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+ <span class="summary_desc"><div class='inline'><p>Reset the password for the User associated with a Password Reset Token.</p>
243
+ </div></span>
244
+
245
+ </li>
246
+
247
+
248
+ <li class="public ">
249
+ <span class="summary_signature">
250
+
251
+ <a href="#session_expired%3F-instance_method" title="#session_expired? (instance method)">#<strong>session_expired?</strong>(session_data = {}) &#x21d2; Boolean </a>
252
+
253
+
254
+
255
+ </span>
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+ <span class="summary_desc"><div class='inline'><p>Determine whether the Session has Expired due to User inactivity.</p>
266
+ </div></span>
267
+
268
+ </li>
269
+
270
+
271
+ <li class="public ">
272
+ <span class="summary_signature">
273
+
274
+ <a href="#sign_in-instance_method" title="#sign_in (instance method)">#<strong>sign_in</strong>(user_in, password, current_user: nil) {|result| ... } </a>
275
+
276
+
277
+
278
+ </span>
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+ <span class="summary_desc"><div class='inline'><p>Attempt to Authenticate a User, passing in an Entity for that User (which <strong>must</strong> contain a <code>password_hash</code> attribute), and a Clear-Text Password.</p>
289
+ </div></span>
290
+
291
+ </li>
292
+
293
+
294
+ <li class="public ">
295
+ <span class="summary_signature">
296
+
297
+ <a href="#sign_out-instance_method" title="#sign_out (instance method)">#<strong>sign_out</strong>(current_user:) {|result| ... } </a>
298
+
299
+
300
+
301
+ </span>
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+ <span class="summary_desc"><div class='inline'><p>Sign out a previously Authenticated User.</p>
312
+ </div></span>
313
+
314
+ </li>
315
+
316
+
317
+ <li class="public ">
318
+ <span class="summary_signature">
319
+
320
+ <a href="#sign_up-instance_method" title="#sign_up (instance method)">#<strong>sign_up</strong>(attribs, current_user:) {|result| ... } </a>
321
+
322
+
323
+
324
+ </span>
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+ <span class="summary_desc"><div class='inline'><p>Persist a new User to a Repository based on passed-in attributes, where the resulting Entity (on success) contains a <code>:password_hash</code> attribute containing the encrypted value of a <strong>random</strong> Clear-Text Password; any <code>password</code> value within <code>attribs</code> is ignored.</p>
335
+ </div></span>
336
+
337
+ </li>
338
+
339
+
340
+ <li class="public ">
341
+ <span class="summary_signature">
342
+
343
+ <a href="#update_session_expiry-instance_method" title="#update_session_expiry (instance method)">#<strong>update_session_expiry</strong>(session_data = {}) &#x21d2; Hash </a>
344
+
345
+
346
+
347
+ </span>
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+ <span class="summary_desc"><div class='inline'><p>Generate a Hash containing an updated Session Expiration timestamp, which can then be used for session management.</p>
358
+ </div></span>
359
+
360
+ </li>
361
+
362
+
363
+ </ul>
364
+
365
+
366
+
367
+
368
+
369
+ <div id="instance_method_details" class="method_details_list">
370
+ <h2>Instance Method Details</h2>
371
+
372
+
373
+ <div class="method_details first">
374
+ <h3 class="signature first" id="change_password-instance_method">
375
+
376
+ #<strong>change_password</strong>(user_in, current_password, new_password) {|result| ... }
377
+
378
+
379
+
380
+
381
+
382
+ </h3><div class="docstring">
383
+ <div class="discussion">
384
+ <p class="note returns_void">This method returns an undefined value.</p><p>Change an Authenticated User&#39;s password.</p>
385
+
386
+ <p>To change an Authenticated User&#39;s password, an Entity for that User, the
387
+ current Clear-Text Password, and the new Clear-Text Password are required.
388
+ The method accepts an optional <code>repo</code> parameter to specify a Repository
389
+ instance to which the updated User Entity should be persisted; if none is
390
+ specified (i.e., if the parameter has its default value of <code>nil</code>), then the
391
+ <code>UserRepository</code> specified in the Configuration is used.</p>
392
+
393
+ <p>The method <em>requires</em> a block, to which a <code>result</code> indicating success or
394
+ failure is yielded. That block <strong>must</strong> in turn call <strong>both</strong>
395
+ <code>result.success</code> and <code>result.failure</code> to handle success and failure results,
396
+ respectively. On success, the block yielded to by <code>result.success</code> is called
397
+ and passed a <code>user:</code> parameter, which is identical to the <code>user</code> parameter
398
+ passed in to <code>#change_password</code> <em>except</em> that the <code>:password_hash</code> attribute
399
+ has been updated to reflect the changed password. The updated value for the
400
+ encrypted password will also have been saved to the Repository.</p>
401
+
402
+ <p>On failure, the <code>result.failure</code> call will yield a <code>code:</code> parameter to its
403
+ block, which indicates the cause of failure as follows:</p>
404
+
405
+ <p>If the specified password <em>did not</em> match the passed-in <code>user</code> Entity, then
406
+ the <code>code:</code> for failure will be <code>:bad_password</code>.</p>
407
+
408
+ <p>If the specified <code>user</code> was <em>other than</em> a User Entity representing a
409
+ Registered User, then the <code>code:</code> for failure will be <code>:invalid_user</code>.</p>
410
+
411
+ <p>Note that no check for the Current User is done here; this method trusts the
412
+ Controller Action Class that (possibly indirectly) invokes it to guard that
413
+ contingency properly.</p>
414
+
415
+
416
+ </div>
417
+ </div>
418
+ <div class="tags">
419
+
420
+ <div class="examples">
421
+ <p class="tag_title">Examples:</p>
422
+
423
+
424
+ <p class="example_title"><div class='inline'><p>for a Controller Action Class (refactor in real use; demo only)</p>
425
+ </div></p>
426
+
427
+ <pre class="example code"><code><span class='kw'>def</span> <span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span>
428
+ <span class='id identifier rubyid_user_in'>user_in</span> <span class='op'>=</span> <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:current_user</span><span class='rbracket'>]</span>
429
+ <span class='id identifier rubyid_error_code'>error_code</span> <span class='op'>=</span> <span class='symbol'>:unassigned</span>
430
+ <span class='id identifier rubyid_config'>config</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="" title="CryptIdent (module)">CryptIdent</a></span></span><span class='period'>.</span><span class='id identifier rubyid_config'>config</span>
431
+ <span class='id identifier rubyid_change_password'>change_password</span><span class='lparen'>(</span><span class='id identifier rubyid_user_in'>user_in</span><span class='comma'>,</span> <span class='id identifier rubyid_params'>params</span><span class='lbracket'>[</span><span class='symbol'>:password</span><span class='rbracket'>]</span><span class='comma'>,</span>
432
+ <span class='id identifier rubyid_params'>params</span><span class='lbracket'>[</span><span class='symbol'>:new_password</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
433
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_success'>success</span> <span class='kw'>do</span> <span class='op'>|</span><span class='label'>user:</span><span class='op'>|</span>
434
+ <span class='ivar'>@user</span> <span class='op'>=</span> <span class='id identifier rubyid_user'>user</span>
435
+ <span class='id identifier rubyid_flash'>flash</span><span class='lbracket'>[</span><span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_success_key'>success_key</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>User </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> password changed.</span><span class='tstring_end'>&quot;</span></span>
436
+ <span class='id identifier rubyid_redirect_to'>redirect_to</span> <span class='id identifier rubyid_routes'>routes</span><span class='period'>.</span><span class='id identifier rubyid_root_path'>root_path</span>
437
+ <span class='kw'>end</span>
438
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_failure'>failure</span> <span class='kw'>do</span> <span class='op'>|</span><span class='label'>code:</span><span class='op'>|</span>
439
+ <span class='id identifier rubyid_flash'>flash</span><span class='lbracket'>[</span><span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_error_key'>error_key</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_error_message_for'>error_message_for</span><span class='lparen'>(</span><span class='id identifier rubyid_code'>code</span><span class='rparen'>)</span>
440
+ <span class='kw'>end</span>
441
+ <span class='kw'>end</span>
442
+ <span class='kw'>end</span>
443
+
444
+ <span class='id identifier rubyid_private'>private</span>
445
+
446
+ <span class='kw'>def</span> <span class='id identifier rubyid_error_message_for'>error_message_for</span><span class='lparen'>(</span><span class='id identifier rubyid_code'>code</span><span class='rparen'>)</span>
447
+ <span class='comment'># ...
448
+ </span><span class='kw'>end</span></code></pre>
449
+
450
+ </div>
451
+ <p class="tag_title">Parameters:</p>
452
+ <ul class="param">
453
+
454
+ <li>
455
+
456
+ <span class='name'>user_in</span>
457
+
458
+
459
+ <span class='type'>(<tt>User</tt>)</span>
460
+
461
+
462
+
463
+ &mdash;
464
+ <div class='inline'><p>The User Entity from which to get the valid Encrypted
465
+ Password and other non-Password attributes</p>
466
+ </div>
467
+
468
+ </li>
469
+
470
+ <li>
471
+
472
+ <span class='name'>current_password</span>
473
+
474
+
475
+ <span class='type'>(<tt>String</tt>)</span>
476
+
477
+
478
+
479
+ &mdash;
480
+ <div class='inline'><p>The current Clear-Text Password for the
481
+ specified User</p>
482
+ </div>
483
+
484
+ </li>
485
+
486
+ <li>
487
+
488
+ <span class='name'>new_password</span>
489
+
490
+
491
+ <span class='type'>(<tt>String</tt>)</span>
492
+
493
+
494
+
495
+ &mdash;
496
+ <div class='inline'><p>The new Clear-Text Password to encrypt and add
497
+ to the returned Entity, and persist to the Repository</p>
498
+ </div>
499
+
500
+ </li>
501
+
502
+ </ul>
503
+
504
+ <p class="tag_title">Yield Parameters:</p>
505
+ <ul class="yieldparam">
506
+
507
+ <li>
508
+
509
+ <span class='name'>result</span>
510
+
511
+
512
+ <span class='type'>(<tt>Dry::Matcher::Evaluator</tt>)</span>
513
+
514
+
515
+
516
+ &mdash;
517
+ <div class='inline'><p>Indicates whether the attempt
518
+ to create a new User succeeded or failed. Block <strong>must</strong>
519
+ call <strong>both</strong> <code>result.success</code> and <code>result.failure</code> methods,
520
+ where the block passed to <code>result.success</code> accepts a parameter
521
+ for <code>user:</code> (which is the newly-created User Entity). The
522
+ block passed to <code>result.failure</code> accepts a parameter for
523
+ <code>code:</code>, which is a Symbol reporting the reason for the
524
+ failure (as described above).</p>
525
+ </div>
526
+
527
+ </li>
528
+
529
+ </ul>
530
+ <p class="tag_title">Yield Returns:</p>
531
+ <ul class="yieldreturn">
532
+
533
+ <li>
534
+
535
+
536
+ <span class='type'>(<tt>void</tt>)</span>
537
+
538
+
539
+
540
+ &mdash;
541
+ <div class='inline'><p>Use the <code>result.success</code> and <code>result.failure</code>
542
+ method-call blocks to retrieve data from the method.</p>
543
+ </div>
544
+
545
+ </li>
546
+
547
+ </ul>
548
+ <p class="tag_title">Since:</p>
549
+ <ul class="since">
550
+
551
+ <li>
552
+
553
+
554
+
555
+
556
+
557
+ <div class='inline'><p>0.1.0</p>
558
+ </div>
559
+
560
+ </li>
561
+
562
+ </ul>
563
+ <p class="tag_title">Required Authentication Status:</p>
564
+ <ul class="authenticated">
565
+
566
+ <li>
567
+
568
+
569
+
570
+
571
+
572
+ <div class='inline'><p>Must be Authenticated.</p>
573
+ </div>
574
+
575
+ </li>
576
+
577
+ </ul>
578
+ <p class="tag_title">Session Data Interacted With:</p>
579
+ <ul class="session_data">
580
+
581
+ <li>
582
+
583
+
584
+
585
+
586
+
587
+ <div class='inline'><p>Implies that <code>:current_user</code> <strong>must</strong> be an Entity for a Registered User</p>
588
+ </div>
589
+
590
+ </li>
591
+
592
+ </ul>
593
+ <p class="tag_title">Ubiquitous Language Terms:</p>
594
+ <ul class="ubiq_lang">
595
+
596
+ <li>
597
+
598
+
599
+
600
+
601
+
602
+ <div class='inline'><ul>
603
+ <li>Authentication</li>
604
+ <li>Clear-Text Password</li>
605
+ <li>Encrypted Password</li>
606
+ <li>Entity</li>
607
+ <li>Guest User</li>
608
+ <li>Registered User</li>
609
+ <li>Repository</li>
610
+ </ul>
611
+ </div>
612
+
613
+ </li>
614
+
615
+ </ul>
616
+
617
+ </div><table class="source_code">
618
+ <tr>
619
+ <td>
620
+ <pre class="lines">
621
+
622
+
623
+ 103
624
+ 104
625
+ 105
626
+ 106
627
+ 107
628
+ 108</pre>
629
+ </td>
630
+ <td>
631
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/change_password.rb', line 103</span>
632
+
633
+ <span class='kw'>def</span> <span class='id identifier rubyid_change_password'>change_password</span><span class='lparen'>(</span><span class='id identifier rubyid_user_in'>user_in</span><span class='comma'>,</span> <span class='id identifier rubyid_current_password'>current_password</span><span class='comma'>,</span> <span class='id identifier rubyid_new_password'>new_password</span><span class='rparen'>)</span>
634
+ <span class='id identifier rubyid_call_params'>call_params</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='id identifier rubyid_current_password'>current_password</span><span class='comma'>,</span> <span class='id identifier rubyid_new_password'>new_password</span><span class='rbracket'>]</span>
635
+ <span class='const'>ChangePassword</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='label'>user:</span> <span class='id identifier rubyid_user_in'>user_in</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='op'>*</span><span class='id identifier rubyid_call_params'>call_params</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
636
+ <span class='kw'>yield</span> <span class='id identifier rubyid_result'>result</span>
637
+ <span class='kw'>end</span>
638
+ <span class='kw'>end</span></pre>
639
+ </td>
640
+ </tr>
641
+ </table>
642
+ </div>
643
+
644
+ <div class="method_details ">
645
+ <h3 class="signature " id="generate_reset_token-instance_method">
646
+
647
+ #<strong>generate_reset_token</strong>(user_name, current_user: nil) {|result| ... }
648
+
649
+
650
+
651
+
652
+
653
+ </h3><div class="docstring">
654
+ <div class="discussion">
655
+ <p class="note returns_void">This method returns an undefined value.</p><p>Generate a Password Reset Token</p>
656
+
657
+ <p>Password Reset Tokens are useful for verifying that the person requesting a
658
+ Password Reset for an existing User is sufficiently likely to be the person
659
+ who Registered that User or, if not, that no compromise or other harm is
660
+ done.</p>
661
+
662
+ <p>Typically, this is done by sending a link through email or other such medium
663
+ to the address previously associated with the User purportedly requesting
664
+ the Password Reset. <code>CryptIdent</code> <em>does not</em> automate generation or sending
665
+ of the email message. What it <em>does</em> provide is a method to generate a new
666
+ Password Reset Token to be embedded into an HTML anchor link within an email
667
+ that you construct, and then another method (<code>#reset_password</code>) to actually
668
+ change the password given a valid, correct token.</p>
669
+
670
+ <p>It also implements an expiry system, such that if the confirmation of the
671
+ Password Reset request is not completed within a configurable time, that the
672
+ token is no longer valid (and so cannot be later reused by unauthorised
673
+ persons).</p>
674
+
675
+ <p>This method <em>requires</em> a block, to which a <code>result</code> indicating success or
676
+ failure is yielded. That block <strong>must</strong> in turn call <strong>both</strong>
677
+ <code>result.success</code> and <code>result.failure</code> to handle success and failure results,
678
+ respectively. On success, the block yielded to by <code>result.success</code> is called
679
+ and passed a <code>user:</code> parameter, which is identical to the <code>user</code> parameter
680
+ passed in to <code>#generate_reset_token</code> <em>except</em> that the <code>:token</code> and
681
+ <code>:password_reset_expires_at</code> attributes have been updated to reflect the
682
+ token request. An updated record matching that <code>:user</code> Entity will also have
683
+ been saved to the Repository.</p>
684
+
685
+ <p>On failure, the <code>result.failure</code> call will yield three parameters: <code>:code</code>,
686
+ <code>:current_user</code>, and <code>:name</code>, and will be set as follows:</p>
687
+
688
+ <p>If the <code>:code</code> value is <code>:user_logged_in</code>, that indicates that the
689
+ <code>current_user</code> parameter to this method represented a Registered User. In
690
+ this event, the <code>:current_user</code> value passed in to the <code>result.failure</code> call
691
+ will be the same User Entity passed into the method, and the <code>:name</code> value
692
+ will be <code>:unassigned</code>.</p>
693
+
694
+ <p>If the <code>:code</code> value is <code>:user_not_found</code>, the named User was not found in
695
+ the Repository. The <code>:current_user</code> parameter will be the Guest User Entity,
696
+ and the <code>:name</code> parameter to the <code>result.failure</code> block will be the
697
+ <code>user_name</code> value passed into the method.</p>
698
+
699
+
700
+ </div>
701
+ </div>
702
+ <div class="tags">
703
+
704
+ <div class="examples">
705
+ <p class="tag_title">Examples:</p>
706
+
707
+
708
+ <p class="example_title"><div class='inline'><p>Demonstrating a (refactorable) Controller Action Class #call method</p>
709
+ </div></p>
710
+
711
+ <pre class="example code"><code>
712
+ def call(params)
713
+ config = CryptIdent.config
714
+ # Remember that reading an Entity stored in session data will in fact
715
+ # return a *Hash of its attribute values*. This is acceptable.
716
+ other_params = { current_user: session[:current_user] }
717
+ generate_reset_token(params[:name], other_params) do |result|
718
+ result.success do |user:|
719
+ @user = user
720
+ flash[config.success_key] = &#39;Request for #{user.name} sent&#39;
721
+ end
722
+ result.failure do |code:, current_user:, name:| do
723
+ respond_to_error(code, current_user, name)
724
+ end
725
+ end
726
+ end
727
+
728
+ private
729
+
730
+ def respond_to_error(code, current_user, name)
731
+ # ...
732
+ end</code></pre>
733
+
734
+ </div>
735
+ <p class="tag_title">Parameters:</p>
736
+ <ul class="param">
737
+
738
+ <li>
739
+
740
+ <span class='name'>user_name</span>
741
+
742
+
743
+ <span class='type'>(<tt>String</tt>)</span>
744
+
745
+
746
+
747
+ &mdash;
748
+ <div class='inline'><p>The name of the User for whom a Password Reset
749
+ Token is to be generated.</p>
750
+ </div>
751
+
752
+ </li>
753
+
754
+ <li>
755
+
756
+ <span class='name'>current_user</span>
757
+
758
+
759
+ <span class='type'>(<tt>User</tt>, <tt>Hash</tt>)</span>
760
+
761
+
762
+
763
+ &mdash;
764
+ <div class='inline'><p>Entity representing the currently
765
+ Authenticated User Entity. This <strong>must</strong> be a Registered
766
+ User, either as an Entity or as a Hash of attributes.</p>
767
+ </div>
768
+
769
+ </li>
770
+
771
+ </ul>
772
+
773
+ <p class="tag_title">Yield Parameters:</p>
774
+ <ul class="yieldparam">
775
+
776
+ <li>
777
+
778
+ <span class='name'>result</span>
779
+
780
+
781
+ <span class='type'>(<tt>Dry::Matcher::Evaluator</tt>)</span>
782
+
783
+
784
+
785
+ &mdash;
786
+ <div class='inline'><p>Indicates whether the attempt
787
+ to generate a new Reset Token succeeded or failed. The lock
788
+ <strong>must</strong> call <strong>both</strong> <code>result.success</code> and <code>result.failure</code>
789
+ methods, where the block passed to <code>result.success</code> accepts a
790
+ parameter for <code>user:</code>, which is a User Entity with the
791
+ specified <code>name</code> value as well as non-<code>nil</code> values for its
792
+ <code>:token</code> and <code>:password_reset_expires_at</code> attributes. The
793
+ block passed to <code>result.failure</code> accepts parameters for
794
+ <code>code:</code>, <code>current_user:</code>, and <code>name</code> as described above.</p>
795
+ </div>
796
+
797
+ </li>
798
+
799
+ </ul>
800
+ <p class="tag_title">Yield Returns:</p>
801
+ <ul class="yieldreturn">
802
+
803
+ <li>
804
+
805
+
806
+ <span class='type'>(<tt>void</tt>)</span>
807
+
808
+
809
+
810
+ &mdash;
811
+ <div class='inline'><p>Use the <code>result.success</code> and <code>result.failure</code>
812
+ method-call blocks to retrieve data from the method.</p>
813
+ </div>
814
+
815
+ </li>
816
+
817
+ </ul>
818
+ <p class="tag_title">Since:</p>
819
+ <ul class="since">
820
+
821
+ <li>
822
+
823
+
824
+
825
+
826
+
827
+ <div class='inline'><p>0.1.0</p>
828
+ </div>
829
+
830
+ </li>
831
+
832
+ </ul>
833
+ <p class="tag_title">Required Authentication Status:</p>
834
+ <ul class="authenticated">
835
+
836
+ <li>
837
+
838
+
839
+
840
+
841
+
842
+ <div class='inline'><p>Must not be Authenticated.</p>
843
+ </div>
844
+
845
+ </li>
846
+
847
+ </ul>
848
+ <p class="tag_title">Session Data Interacted With:</p>
849
+ <ul class="session_data">
850
+
851
+ <li>
852
+
853
+
854
+
855
+
856
+
857
+ <div class='inline'><p><code>:current_user</code> <strong>must not</strong> be a Registered User.</p>
858
+ </div>
859
+
860
+ </li>
861
+
862
+ </ul>
863
+ <p class="tag_title">Ubiquitous Language Terms:</p>
864
+ <ul class="ubiq_lang">
865
+
866
+ <li>
867
+
868
+
869
+
870
+
871
+
872
+ <div class='inline'><ul>
873
+ <li>Authentication</li>
874
+ <li>Guest User</li>
875
+ <li>Password Reset Token</li>
876
+ <li>Registered User</li>
877
+ </ul>
878
+ </div>
879
+
880
+ </li>
881
+
882
+ </ul>
883
+
884
+ </div><table class="source_code">
885
+ <tr>
886
+ <td>
887
+ <pre class="lines">
888
+
889
+
890
+ 113
891
+ 114
892
+ 115
893
+ 116
894
+ 117
895
+ 118</pre>
896
+ </td>
897
+ <td>
898
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/generate_reset_token.rb', line 113</span>
899
+
900
+ <span class='kw'>def</span> <span class='id identifier rubyid_generate_reset_token'>generate_reset_token</span><span class='lparen'>(</span><span class='id identifier rubyid_user_name'>user_name</span><span class='comma'>,</span> <span class='label'>current_user:</span> <span class='kw'>nil</span><span class='rparen'>)</span>
901
+ <span class='id identifier rubyid_other_params'>other_params</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='label'>current_user:</span> <span class='id identifier rubyid_current_user'>current_user</span> <span class='rbrace'>}</span>
902
+ <span class='const'>GenerateResetToken</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_user_name'>user_name</span><span class='comma'>,</span> <span class='id identifier rubyid_other_params'>other_params</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
903
+ <span class='kw'>yield</span> <span class='id identifier rubyid_result'>result</span>
904
+ <span class='kw'>end</span>
905
+ <span class='kw'>end</span></pre>
906
+ </td>
907
+ </tr>
908
+ </table>
909
+ </div>
910
+
911
+ <div class="method_details ">
912
+ <h3 class="signature " id="reset_password-instance_method">
913
+
914
+ #<strong>reset_password</strong>(token, new_password, current_user: nil) {|result| ... }
915
+
916
+
917
+
918
+
919
+
920
+ </h3><div class="docstring">
921
+ <div class="discussion">
922
+ <p class="note returns_void">This method returns an undefined value.</p><p>Reset the password for the User associated with a Password Reset Token.</p>
923
+
924
+ <p>After a Password Reset Token has been
925
+ <a href="#generate_reset_token-instance_method">generated</a> and sent to a User, that
926
+ User would then exercise the Client system and perform a Password Reset.</p>
927
+
928
+ <p>Calling <code>#reset_password</code> is different than calling <code>#change_password</code> in
929
+ one vital respect: with <code>#change_password</code>, the User involved <strong>must</strong> be
930
+ the Current User (as presumed by passing the appropriate User Entity in as
931
+ the <code>current_user:</code> parameter), whereas <code>#reset_password</code> <strong>must not</strong> be
932
+ called with <em>any</em> User other than the Guest User as the <code>current_user:</code>
933
+ parameter (and, again presumably, the Current User for the session). How can
934
+ we assure ourselves that the request is legitimate for a specific User? By
935
+ use of the Token generated by a previous call to <code>#generate_reset_token</code>,
936
+ which is used <em>in place of</em> a User Name for this request.</p>
937
+
938
+ <p>Given a valid set of parameters, and given that the updated User is
939
+ successfully persisted, the method calls the <strong>required</strong> block with a
940
+ <code>result</code> whose <code>result.success</code> matcher is yielded a <code>user:</code> parameter with
941
+ the updated User as its value.</p>
942
+
943
+ <p>NOTE: Each of the error returns documented below calls the <strong>required</strong>
944
+ block with a <code>result</code> whose <code>result.failure</code> matcher is yielded a <code>code:</code>
945
+ parameter as described, and a <code>token:</code> parameter that has the same value
946
+ as the passed-in <code>token</code> parameter.</p>
947
+
948
+ <p>If the passed-in <code>token</code> parameter matches the <code>token</code> field of a record in
949
+ the Repository <em>and</em> that Token is determined to have Expired, then the
950
+ <code>code:</code> parameter mentioned earlier will have the value <code>:expired_token</code>.</p>
951
+
952
+ <p>If the passed-in <code>token</code> parameter <em>does not</em> match the <code>token</code> field of any
953
+ record in the Repository, then the <code>code:</code> parameter will have the value
954
+ <code>:token_not_found</code>.</p>
955
+
956
+ <p>If the passed-in <code>current_user:</code> parameter is a Registered User, then the
957
+ <code>code:</code> parameter will have the value <code>:invalid_current_user</code>.</p>
958
+
959
+ <p>In no event are session values, including the Current User, changed. After a
960
+ successful Password Reset, the User must Authenticate as usual.</p>
961
+
962
+
963
+ </div>
964
+ </div>
965
+ <div class="tags">
966
+
967
+ <div class="examples">
968
+ <p class="tag_title">Examples:</p>
969
+
970
+
971
+ <pre class="example code"><code>def call(params)
972
+ reset_password(params[:token], params[:new_password],
973
+ current_user: session[:current_user]) do |result
974
+ result.success do |user:|
975
+ @user = user
976
+ message = &quot;Password for #{user.name} successfully reset.&quot;
977
+ flash[CryptIdent.config.success_key] = message
978
+ redirect_to routes.root_path
979
+ end
980
+ result.failure do |code:, token:|
981
+ failure_key = CryptIdent.config.failure_key
982
+ flash[failure_key] = failure_message_for(code, token)
983
+ end
984
+ end
985
+ end
986
+
987
+ private
988
+
989
+ def failure_message_for(code, token)
990
+ # ...
991
+ end</code></pre>
992
+
993
+ </div>
994
+ <p class="tag_title">Parameters:</p>
995
+ <ul class="param">
996
+
997
+ <li>
998
+
999
+ <span class='name'>token</span>
1000
+
1001
+
1002
+ <span class='type'>(<tt>String</tt>)</span>
1003
+
1004
+
1005
+
1006
+ &mdash;
1007
+ <div class='inline'><p>The Password Reset Token previously communicated to
1008
+ the User.</p>
1009
+ </div>
1010
+
1011
+ </li>
1012
+
1013
+ <li>
1014
+
1015
+ <span class='name'>new_password</span>
1016
+
1017
+
1018
+ <span class='type'>(<tt>String</tt>)</span>
1019
+
1020
+
1021
+
1022
+ &mdash;
1023
+ <div class='inline'><p>New Clear-Text Password to encrypt and add to
1024
+ return value</p>
1025
+ </div>
1026
+
1027
+ </li>
1028
+
1029
+ </ul>
1030
+
1031
+ <p class="tag_title">Yield Parameters:</p>
1032
+ <ul class="yieldparam">
1033
+
1034
+ <li>
1035
+
1036
+ <span class='name'>result</span>
1037
+
1038
+
1039
+ <span class='type'>(<tt>Dry::Matcher::Evaluator</tt>)</span>
1040
+
1041
+
1042
+
1043
+ &mdash;
1044
+ <div class='inline'><p>Indicates whether the attempt
1045
+ to generate a new Reset Token succeeded or failed. The lock
1046
+ <strong>must</strong> call <strong>both</strong> <code>result.success</code> and <code>result.failure</code>
1047
+ methods, where the block passed to <code>result.success</code> accepts a
1048
+ parameter for <code>user:</code>, which is a User Entity with the
1049
+ specified <code>name</code> value as well as non-<code>nil</code> values for its
1050
+ <code>:token</code> and <code>:password_reset_expires_at</code> attributes. The
1051
+ block passed to <code>result.failure</code> accepts parameters for
1052
+ <code>code:</code>, <code>current_user:</code>, and <code>name</code> as described above.</p>
1053
+ </div>
1054
+
1055
+ </li>
1056
+
1057
+ </ul>
1058
+ <p class="tag_title">Yield Returns:</p>
1059
+ <ul class="yieldreturn">
1060
+
1061
+ <li>
1062
+
1063
+
1064
+ <span class='type'>(<tt>void</tt>)</span>
1065
+
1066
+
1067
+
1068
+ &mdash;
1069
+ <div class='inline'><p>Use the <code>result.success</code> and <code>result.failure</code>
1070
+ method-call blocks to retrieve data from the method.</p>
1071
+ </div>
1072
+
1073
+ </li>
1074
+
1075
+ </ul>
1076
+ <p class="tag_title">Since:</p>
1077
+ <ul class="since">
1078
+
1079
+ <li>
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+ <div class='inline'><p>0.1.0</p>
1086
+ </div>
1087
+
1088
+ </li>
1089
+
1090
+ </ul>
1091
+ <p class="tag_title">Required Authentication Status:</p>
1092
+ <ul class="authenticated">
1093
+
1094
+ <li>
1095
+
1096
+
1097
+
1098
+
1099
+
1100
+ <div class='inline'><p>Must not be Authenticated.</p>
1101
+ </div>
1102
+
1103
+ </li>
1104
+
1105
+ </ul>
1106
+ <p class="tag_title">Session Data Interacted With:</p>
1107
+ <ul class="session_data">
1108
+
1109
+ <li>
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+ <div class='inline'><p><code>:current_user</code> <strong>must not</strong> be a Registered User.</p>
1116
+ </div>
1117
+
1118
+ </li>
1119
+
1120
+ </ul>
1121
+ <p class="tag_title">Ubiquitous Language Terms:</p>
1122
+ <ul class="ubiq_lang">
1123
+
1124
+ <li>
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+ <div class='inline'><ul>
1131
+ <li>Authentication</li>
1132
+ <li>Clear-Text Password</li>
1133
+ <li>Encrypted Password</li>
1134
+ <li>Password Reset Token</li>
1135
+ <li>Registered User</li>
1136
+ </ul>
1137
+ </div>
1138
+
1139
+ </li>
1140
+
1141
+ </ul>
1142
+
1143
+ </div><table class="source_code">
1144
+ <tr>
1145
+ <td>
1146
+ <pre class="lines">
1147
+
1148
+
1149
+ 111
1150
+ 112
1151
+ 113
1152
+ 114
1153
+ 115
1154
+ 116</pre>
1155
+ </td>
1156
+ <td>
1157
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/reset_password.rb', line 111</span>
1158
+
1159
+ <span class='kw'>def</span> <span class='id identifier rubyid_reset_password'>reset_password</span><span class='lparen'>(</span><span class='id identifier rubyid_token'>token</span><span class='comma'>,</span> <span class='id identifier rubyid_new_password'>new_password</span><span class='comma'>,</span> <span class='label'>current_user:</span> <span class='kw'>nil</span><span class='rparen'>)</span>
1160
+ <span class='id identifier rubyid_other_params'>other_params</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='label'>current_user:</span> <span class='id identifier rubyid_current_user'>current_user</span> <span class='rbrace'>}</span>
1161
+ <span class='const'>ResetPassword</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_token'>token</span><span class='comma'>,</span> <span class='id identifier rubyid_new_password'>new_password</span><span class='comma'>,</span> <span class='id identifier rubyid_other_params'>other_params</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
1162
+ <span class='kw'>yield</span> <span class='id identifier rubyid_result'>result</span>
1163
+ <span class='kw'>end</span>
1164
+ <span class='kw'>end</span></pre>
1165
+ </td>
1166
+ </tr>
1167
+ </table>
1168
+ </div>
1169
+
1170
+ <div class="method_details ">
1171
+ <h3 class="signature " id="session_expired?-instance_method">
1172
+
1173
+ #<strong>session_expired?</strong>(session_data = {}) &#x21d2; <tt>Boolean</tt>
1174
+
1175
+
1176
+
1177
+
1178
+
1179
+ </h3><div class="docstring">
1180
+ <div class="discussion">
1181
+ <p>Determine whether the Session has Expired due to User inactivity.</p>
1182
+
1183
+ <p>This is one of two methods in <code>CryptIdent</code> (the other being
1184
+ <a href="#update_session_expiry"><code>#update_session_expiry?</code></a>) which <em>does not</em> follow
1185
+ the <code>result</code>/success/failure <a href="#interfaces">monad workflow</a>. This is because
1186
+ there is no success/failure division in the workflow. Calling the method
1187
+ determines if the Current User session has Expired. If the passed-in
1188
+ <code>:current_user</code> is a Registered User, then this will return <code>true</code> if the
1189
+ current time is <em>later than</em> the passed-in <code>:expires_at</code> value; for the
1190
+ Guest User, it should always return <code>false</code>. (Guest User sessions never
1191
+ expire; after all, what would you change the session state to?).</p>
1192
+
1193
+ <p>The client code is responsible for applying these values to its own actual
1194
+ session data, as described by the sample session-management code shown in
1195
+ the README.</p>
1196
+
1197
+
1198
+ </div>
1199
+ </div>
1200
+ <div class="tags">
1201
+
1202
+ <div class="examples">
1203
+ <p class="tag_title">Examples:</p>
1204
+
1205
+
1206
+ <p class="example_title"><div class='inline'><p>As used in module included by Controller Action Class (see README)</p>
1207
+ </div></p>
1208
+
1209
+ <pre class="example code"><code><span class='kw'>def</span> <span class='id identifier rubyid_validate_session'>validate_session</span>
1210
+ <span class='id identifier rubyid_updates'>updates</span> <span class='op'>=</span> <span class='id identifier rubyid_update_session_expiry'>update_session_expiry</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='rparen'>)</span>
1211
+ <span class='kw'>if</span> <span class='op'>!</span><span class='id identifier rubyid_session_expired?'>session_expired?</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='rparen'>)</span>
1212
+ <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:expires_at</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_updates'>updates</span><span class='lbracket'>[</span><span class='symbol'>:expires_at</span><span class='rbracket'>]</span>
1213
+ <span class='kw'>return</span>
1214
+ <span class='kw'>end</span>
1215
+
1216
+ <span class='comment'># ... sign out and redirect appropriately ...
1217
+ </span><span class='kw'>end</span></code></pre>
1218
+
1219
+ </div>
1220
+ <p class="tag_title">Parameters:</p>
1221
+ <ul class="param">
1222
+
1223
+ <li>
1224
+
1225
+ <span class='name'>session_data</span>
1226
+
1227
+
1228
+ <span class='type'>(<tt>Hash</tt>)</span>
1229
+
1230
+
1231
+ <em class="default">(defaults to: <tt>{}</tt>)</em>
1232
+
1233
+
1234
+ &mdash;
1235
+ <div class='inline'><p>The Rack session data of interest to the method.
1236
+ If the <code>:current_user</code> entry is defined, it <strong>must</strong> be either
1237
+ a User Entity or <code>nil</code>, signifying the Guest User. If the
1238
+ <code>:expires_at</code> entry is defined, its value in the returned Hash
1239
+ <em>will</em> be different.</p>
1240
+ </div>
1241
+
1242
+ </li>
1243
+
1244
+ </ul>
1245
+
1246
+ <p class="tag_title">Returns:</p>
1247
+ <ul class="return">
1248
+
1249
+ <li>
1250
+
1251
+
1252
+ <span class='type'>(<tt>Boolean</tt>)</span>
1253
+
1254
+
1255
+
1256
+ </li>
1257
+
1258
+ </ul>
1259
+ <p class="tag_title">Since:</p>
1260
+ <ul class="since">
1261
+
1262
+ <li>
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+ <div class='inline'><p>0.1.0</p>
1269
+ </div>
1270
+
1271
+ </li>
1272
+
1273
+ </ul>
1274
+ <p class="tag_title">Required Authentication Status:</p>
1275
+ <ul class="authenticated">
1276
+
1277
+ <li>
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+ <div class='inline'><p>Must be Authenticated.</p>
1284
+ </div>
1285
+
1286
+ </li>
1287
+
1288
+ </ul>
1289
+ <p class="tag_title">Session Data Interacted With:</p>
1290
+ <ul class="session_data">
1291
+
1292
+ <li>
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+ <div class='inline'><p><code>:current_user</code> <strong>must</strong> be an Entity for a Registered User on entry
1299
+ <code>:expires_at</code> read during determination of expiry status</p>
1300
+ </div>
1301
+
1302
+ </li>
1303
+
1304
+ </ul>
1305
+ <p class="tag_title">Ubiquitous Language Terms:</p>
1306
+ <ul class="ubiq_lang">
1307
+
1308
+ <li>
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+ <div class='inline'><ul>
1315
+ <li>Authentication</li>
1316
+ <li>Current User</li>
1317
+ <li>Guest User</li>
1318
+ <li>Registered User</li>
1319
+ <li>Session Expiration</li>
1320
+ </ul>
1321
+ </div>
1322
+
1323
+ </li>
1324
+
1325
+ </ul>
1326
+
1327
+ </div><table class="source_code">
1328
+ <tr>
1329
+ <td>
1330
+ <pre class="lines">
1331
+
1332
+
1333
+ 58
1334
+ 59
1335
+ 60</pre>
1336
+ </td>
1337
+ <td>
1338
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/session_expired.rb', line 58</span>
1339
+
1340
+ <span class='kw'>def</span> <span class='id identifier rubyid_session_expired?'>session_expired?</span><span class='lparen'>(</span><span class='id identifier rubyid_session_data'>session_data</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
1341
+ <span class='const'>SessionExpired</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_session_data'>session_data</span><span class='rparen'>)</span>
1342
+ <span class='kw'>end</span></pre>
1343
+ </td>
1344
+ </tr>
1345
+ </table>
1346
+ </div>
1347
+
1348
+ <div class="method_details ">
1349
+ <h3 class="signature " id="sign_in-instance_method">
1350
+
1351
+ #<strong>sign_in</strong>(user_in, password, current_user: nil) {|result| ... }
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+ </h3><div class="docstring">
1358
+ <div class="discussion">
1359
+ <p class="note returns_void">This method returns an undefined value.</p><p>Attempt to Authenticate a User, passing in an Entity for that User (which
1360
+ <strong>must</strong> contain a <code>password_hash</code> attribute), and a Clear-Text Password.
1361
+ It also passes in the Current User.</p>
1362
+
1363
+ <p>If the Current User is not a Registered User, then Authentication of the
1364
+ specified User Entity against the specified Password is accomplished by
1365
+ comparing the User Entity&#39;s <code>password_hash</code> attribute to the passed-in
1366
+ Clear-Text Password.</p>
1367
+
1368
+ <p>The method <em>requires</em> a block, to which a <code>result</code> indicating success or
1369
+ failure is yielded. That block <strong>must</strong> in turn call <strong>both</strong>
1370
+ <code>result.success</code> and <code>result.failure</code> to handle success and failure results,
1371
+ respectively. On success, the block yielded to by <code>result.success</code> is called
1372
+ and passed a <code>user:</code> parameter, which is the Authenticated User (and is the
1373
+ same Entity as the <code>user</code> parameter passed in to <code>#sign_in</code>).</p>
1374
+
1375
+ <p>On failure, the <code>result.failure</code> call will yield a <code>code:</code> parameter to its
1376
+ block, which indicates the cause of failure as follows:</p>
1377
+
1378
+ <p>If the specified password <em>did not</em> match the passed-in <code>user</code> Entity, then
1379
+ the <code>code:</code> for failure will be <code>:invalid_password</code>.</p>
1380
+
1381
+ <p>If the specified <code>user</code> was not a Registered User, then the <code>code:</code> for
1382
+ failure will be <code>:user_is_guest</code>.</p>
1383
+
1384
+ <p>If the specified <code>current_user</code> is <em>neither</em> the Guest User <em>nor</em> the <code>user</code>
1385
+ passed in as a parameter to <code>#sign_in</code>, then the <code>code:</code> for failure will be
1386
+ <code>:illegal_current_user</code>.</p>
1387
+
1388
+ <p>On <em>success,</em> the Controller-level client code <strong>must</strong> set:</p>
1389
+
1390
+ <ul>
1391
+ <li><code>session[:expires_at]</code> to the expiration time for the session. This is
1392
+ ordinarily computed by adding the current time as returned by <code>Time.now</code>
1393
+ to the <code>:session_expiry</code> value in the current configuration.</li>
1394
+ <li><code>session[:current_user]</code> to tne returned <em>Entity</em> for the successfully
1395
+ Authenticated User. This is to eliminate possible repeated reads of the
1396
+ Repository.</li>
1397
+ </ul>
1398
+
1399
+ <p>On <em>failure,</em> the Controller-level client code <strong>should</strong> set:</p>
1400
+
1401
+ <ul>
1402
+ <li><code>session[:expires_at]</code> to some sufficiently-past time to <em>always</em> trigger
1403
+ <code>#session_expired?</code>; <code>Hanami::Utils::Kernel.Time(0)</code> does this quite well
1404
+ (returning midnight GMT on 1 January 1970, converted to local time).</li>
1405
+ <li><code>session[:current_user]</code> to either <code>nil</code> or the Guest User.</li>
1406
+ </ul>
1407
+
1408
+
1409
+ </div>
1410
+ </div>
1411
+ <div class="tags">
1412
+
1413
+ <div class="examples">
1414
+ <p class="tag_title">Examples:</p>
1415
+
1416
+
1417
+ <p class="example_title"><div class='inline'><p>As in a Controller Action Class (which you&#39;d refactor somewhat):</p>
1418
+ </div></p>
1419
+
1420
+ <pre class="example code"><code>def call(params)
1421
+ user = UserRepository.new.find_by_email(params[:email])
1422
+ guest_user = CryptIdent.config.guest_user
1423
+ return update_session_data(guest_user, 0) unless user
1424
+
1425
+ current_user = session[:current_user]
1426
+ config = CryptIdent.config
1427
+ sign_in(user, params[:password], current_user: current_user) do |result|
1428
+ result.success do |user:|
1429
+ @user = user
1430
+ update_session_data(user, Time.now)
1431
+ flash[config.success_key] = &quot;User #{user.name} signed in.&quot;
1432
+ redirect_to routes.root_path
1433
+ end
1434
+
1435
+ result.failure do |code:|
1436
+ update_session_data(guest_user, config, 0)
1437
+ flash[config.error_key] = error_message_for(code)
1438
+ end
1439
+ end
1440
+
1441
+ private
1442
+
1443
+ def error_message_for(code)
1444
+ # ...
1445
+ end
1446
+
1447
+ def update_session_data(user, time)
1448
+ session[:current_user] = user
1449
+ expiry = Time.now + CryptIdent.config.session_expiry
1450
+ session[:expires_at] == Hanami::Utils::Kernel.Time(expiry)
1451
+ end</code></pre>
1452
+
1453
+ </div>
1454
+ <p class="tag_title">Parameters:</p>
1455
+ <ul class="param">
1456
+
1457
+ <li>
1458
+
1459
+ <span class='name'>user_in</span>
1460
+
1461
+
1462
+ <span class='type'>(<tt>User</tt>)</span>
1463
+
1464
+
1465
+
1466
+ &mdash;
1467
+ <div class='inline'><p>Entity representing a User to be Authenticated.</p>
1468
+ </div>
1469
+
1470
+ </li>
1471
+
1472
+ <li>
1473
+
1474
+ <span class='name'>password</span>
1475
+
1476
+
1477
+ <span class='type'>(<tt>String</tt>)</span>
1478
+
1479
+
1480
+
1481
+ &mdash;
1482
+ <div class='inline'><p>Claimed Clear-Text Password for the specified User.</p>
1483
+ </div>
1484
+
1485
+ </li>
1486
+
1487
+ <li>
1488
+
1489
+ <span class='name'>current_user</span>
1490
+
1491
+
1492
+ <span class='type'>(<tt>User</tt>, <tt>nil</tt>)</span>
1493
+
1494
+
1495
+
1496
+ &mdash;
1497
+ <div class='inline'><p>Entity representing the currently
1498
+ Authenticated User Entity; either <code>nil</code> or the Guest User if
1499
+ none.</p>
1500
+ </div>
1501
+
1502
+ </li>
1503
+
1504
+ </ul>
1505
+
1506
+ <p class="tag_title">Yield Parameters:</p>
1507
+ <ul class="yieldparam">
1508
+
1509
+ <li>
1510
+
1511
+ <span class='name'>result</span>
1512
+
1513
+
1514
+ <span class='type'>(<tt>Dry::Matcher::Evaluator</tt>)</span>
1515
+
1516
+
1517
+
1518
+ &mdash;
1519
+ <div class='inline'><p>Indicates whether the attempt
1520
+ to Authenticate a User succeeded or failed. Block <strong>must</strong>
1521
+ call <strong>both</strong> <code>result.success</code> and <code>result.failure</code> methods,
1522
+ where the block passed to <code>result.success</code> accepts a parameter
1523
+ for <code>user:</code> (which is the newly-created User Entity). The
1524
+ block passed to <code>result.failure</code> accepts a parameter for
1525
+ <code>code:</code>, which is a Symbol reporting the reason for the
1526
+ failure (as described above).</p>
1527
+ </div>
1528
+
1529
+ </li>
1530
+
1531
+ </ul>
1532
+ <p class="tag_title">Yield Returns:</p>
1533
+ <ul class="yieldreturn">
1534
+
1535
+ <li>
1536
+
1537
+
1538
+ <span class='type'>(<tt>void</tt>)</span>
1539
+
1540
+
1541
+
1542
+ </li>
1543
+
1544
+ </ul>
1545
+ <p class="tag_title">Since:</p>
1546
+ <ul class="since">
1547
+
1548
+ <li>
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+ <div class='inline'><p>0.1.0</p>
1555
+ </div>
1556
+
1557
+ </li>
1558
+
1559
+ </ul>
1560
+ <p class="tag_title">Required Authentication Status:</p>
1561
+ <ul class="authenticated">
1562
+
1563
+ <li>
1564
+
1565
+
1566
+
1567
+
1568
+
1569
+ <div class='inline'><p>Must not be Authenticated as a different User.</p>
1570
+ </div>
1571
+
1572
+ </li>
1573
+
1574
+ </ul>
1575
+ <p class="tag_title">Session Data Interacted With:</p>
1576
+ <ul class="session_data">
1577
+
1578
+ <li>
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+ <div class='inline'><p><code>:current_user</code> <strong>must not</strong> be a Registered User</p>
1585
+ </div>
1586
+
1587
+ </li>
1588
+
1589
+ </ul>
1590
+ <p class="tag_title">Ubiquitous Language Terms:</p>
1591
+ <ul class="ubiq_lang">
1592
+
1593
+ <li>
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+ <div class='inline'><ul>
1600
+ <li>Authenticated User</li>
1601
+ <li>Authentication</li>
1602
+ <li>Clear-Text Password</li>
1603
+ <li>Entity</li>
1604
+ <li>Guest User</li>
1605
+ <li>Registered User</li>
1606
+ </ul>
1607
+ </div>
1608
+
1609
+ </li>
1610
+
1611
+ </ul>
1612
+
1613
+ </div><table class="source_code">
1614
+ <tr>
1615
+ <td>
1616
+ <pre class="lines">
1617
+
1618
+
1619
+ 123
1620
+ 124
1621
+ 125
1622
+ 126</pre>
1623
+ </td>
1624
+ <td>
1625
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/sign_in.rb', line 123</span>
1626
+
1627
+ <span class='kw'>def</span> <span class='id identifier rubyid_sign_in'>sign_in</span><span class='lparen'>(</span><span class='id identifier rubyid_user_in'>user_in</span><span class='comma'>,</span> <span class='id identifier rubyid_password'>password</span><span class='comma'>,</span> <span class='label'>current_user:</span> <span class='kw'>nil</span><span class='rparen'>)</span>
1628
+ <span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='label'>user:</span> <span class='id identifier rubyid_user_in'>user_in</span><span class='comma'>,</span> <span class='label'>password:</span> <span class='id identifier rubyid_password'>password</span><span class='comma'>,</span> <span class='label'>current_user:</span> <span class='id identifier rubyid_current_user'>current_user</span> <span class='rbrace'>}</span>
1629
+ <span class='const'>SignIn</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span> <span class='kw'>yield</span> <span class='id identifier rubyid_result'>result</span> <span class='rbrace'>}</span>
1630
+ <span class='kw'>end</span></pre>
1631
+ </td>
1632
+ </tr>
1633
+ </table>
1634
+ </div>
1635
+
1636
+ <div class="method_details ">
1637
+ <h3 class="signature " id="sign_out-instance_method">
1638
+
1639
+ #<strong>sign_out</strong>(current_user:) {|result| ... }
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+ </h3><div class="docstring">
1646
+ <div class="discussion">
1647
+ <p class="note returns_void">This method returns an undefined value.</p><p>Sign out a previously Authenticated User.</p>
1648
+
1649
+ <p>The method <em>requires</em> a block, to which a <code>result</code> indicating success or
1650
+ failure is yielded. (Presently, any call to <code>#sign_out</code> results in success.)
1651
+ That block <strong>must</strong> in turn call <strong>both</strong> <code>result.success</code> and
1652
+ <code>result.failure</code> (even though no failure is implemented) to handle success
1653
+ and failure results, respectively. On success, the block yielded to by
1654
+ <code>result.success</code> is called without parameters.</p>
1655
+
1656
+
1657
+ </div>
1658
+ </div>
1659
+ <div class="tags">
1660
+
1661
+ <div class="examples">
1662
+ <p class="tag_title">Examples:</p>
1663
+
1664
+
1665
+ <p class="example_title"><div class='inline'><p>Controller Action Class method example resetting values</p>
1666
+ </div></p>
1667
+
1668
+ <pre class="example code"><code><span class='kw'>def</span> <span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid__params'>_params</span><span class='rparen'>)</span>
1669
+ <span class='id identifier rubyid_sign_out'>sign_out</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:current_user</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
1670
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_success'>success</span> <span class='kw'>do</span>
1671
+ <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:current_user</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="" title="CryptIdent (module)">CryptIdent</a></span></span><span class='period'>.</span><span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_guest_user'>guest_user</span>
1672
+ <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:expires_at</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='const'>Hanami</span><span class='op'>::</span><span class='const'>Utils</span><span class='op'>::</span><span class='const'>Kernel</span><span class='period'>.</span><span class='const'>Time</span><span class='lparen'>(</span><span class='int'>0</span><span class='rparen'>)</span>
1673
+ <span class='kw'>end</span>
1674
+
1675
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_failure'>failure</span> <span class='lbrace'>{</span> <span class='kw'>next</span> <span class='rbrace'>}</span>
1676
+ <span class='kw'>end</span>
1677
+ <span class='kw'>end</span></code></pre>
1678
+
1679
+
1680
+ <p class="example_title"><div class='inline'><p>Controller Action Class method example deleting values</p>
1681
+ </div></p>
1682
+
1683
+ <pre class="example code"><code><span class='kw'>def</span> <span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid__params'>_params</span><span class='rparen'>)</span>
1684
+ <span class='id identifier rubyid_sign_out'>sign_out</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:current_user</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
1685
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_success'>success</span> <span class='kw'>do</span>
1686
+ <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:current_user</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='kw'>nil</span>
1687
+ <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:expires_at</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='kw'>nil</span>
1688
+ <span class='kw'>end</span>
1689
+
1690
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_failure'>failure</span> <span class='lbrace'>{</span> <span class='kw'>next</span> <span class='rbrace'>}</span>
1691
+ <span class='kw'>end</span>
1692
+ <span class='kw'>end</span></code></pre>
1693
+
1694
+ </div>
1695
+ <p class="tag_title">Parameters:</p>
1696
+ <ul class="param">
1697
+
1698
+ <li>
1699
+
1700
+ <span class='name'>current_user</span>
1701
+
1702
+
1703
+ <span class='type'>(<tt>User</tt>, <tt>`nil`</tt>)</span>
1704
+
1705
+
1706
+
1707
+ &mdash;
1708
+ <div class='inline'><p>Entity representing the currently
1709
+ Authenticated User Entity. This <strong>should</strong> be a Registered
1710
+ User.</p>
1711
+ </div>
1712
+
1713
+ </li>
1714
+
1715
+ </ul>
1716
+
1717
+ <p class="tag_title">Yield Parameters:</p>
1718
+ <ul class="yieldparam">
1719
+
1720
+ <li>
1721
+
1722
+ <span class='name'>result</span>
1723
+
1724
+
1725
+ <span class='type'>(<tt>Dry::Matcher::Evaluator</tt>)</span>
1726
+
1727
+
1728
+
1729
+ &mdash;
1730
+ <div class='inline'><p>Normally, used to report
1731
+ whether a method succeeded or failed. The block <strong>must</strong>
1732
+ call <strong>both</strong> <code>result.success</code> and <code>result.failure</code> methods.
1733
+ In practice, parameters to both may presently be safely
1734
+ ignored.</p>
1735
+ </div>
1736
+
1737
+ </li>
1738
+
1739
+ </ul>
1740
+ <p class="tag_title">Yield Returns:</p>
1741
+ <ul class="yieldreturn">
1742
+
1743
+ <li>
1744
+
1745
+
1746
+ <span class='type'>(<tt>void</tt>)</span>
1747
+
1748
+
1749
+
1750
+ </li>
1751
+
1752
+ </ul>
1753
+ <p class="tag_title">Since:</p>
1754
+ <ul class="since">
1755
+
1756
+ <li>
1757
+
1758
+
1759
+
1760
+
1761
+
1762
+ <div class='inline'><p>0.1.0</p>
1763
+ </div>
1764
+
1765
+ </li>
1766
+
1767
+ </ul>
1768
+ <p class="tag_title">Required Authentication Status:</p>
1769
+ <ul class="authenticated">
1770
+
1771
+ <li>
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+ <div class='inline'><p>Should be Authenticated.</p>
1778
+ </div>
1779
+
1780
+ </li>
1781
+
1782
+ </ul>
1783
+ <p class="tag_title">Session Data Interacted With:</p>
1784
+ <ul class="session_data">
1785
+
1786
+ <li>
1787
+
1788
+
1789
+
1790
+
1791
+
1792
+ <div class='inline'><p>See method description above.</p>
1793
+ </div>
1794
+
1795
+ </li>
1796
+
1797
+ </ul>
1798
+ <p class="tag_title">Ubiquitous Language Terms:</p>
1799
+ <ul class="ubiq_lang">
1800
+
1801
+ <li>
1802
+
1803
+
1804
+
1805
+
1806
+
1807
+ <div class='inline'><ul>
1808
+ <li>Authenticated User</li>
1809
+ <li>Authentication</li>
1810
+ <li>Controller Action Class</li>
1811
+ <li>Entity</li>
1812
+ <li>Guest User</li>
1813
+ <li>Interactor</li>
1814
+ <li>Repository</li>
1815
+ </ul>
1816
+ </div>
1817
+
1818
+ </li>
1819
+
1820
+ </ul>
1821
+
1822
+ </div><table class="source_code">
1823
+ <tr>
1824
+ <td>
1825
+ <pre class="lines">
1826
+
1827
+
1828
+ 74
1829
+ 75
1830
+ 76</pre>
1831
+ </td>
1832
+ <td>
1833
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/sign_out.rb', line 74</span>
1834
+
1835
+ <span class='kw'>def</span> <span class='id identifier rubyid_sign_out'>sign_out</span><span class='lparen'>(</span><span class='label'>current_user:</span><span class='rparen'>)</span>
1836
+ <span class='const'>SignOut</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='label'>current_user:</span> <span class='id identifier rubyid_current_user'>current_user</span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span> <span class='kw'>yield</span> <span class='id identifier rubyid_result'>result</span> <span class='rbrace'>}</span>
1837
+ <span class='kw'>end</span></pre>
1838
+ </td>
1839
+ </tr>
1840
+ </table>
1841
+ </div>
1842
+
1843
+ <div class="method_details ">
1844
+ <h3 class="signature " id="sign_up-instance_method">
1845
+
1846
+ #<strong>sign_up</strong>(attribs, current_user:) {|result| ... }
1847
+
1848
+
1849
+
1850
+
1851
+
1852
+ </h3><div class="docstring">
1853
+ <div class="discussion">
1854
+ <p class="note returns_void">This method returns an undefined value.</p><p>Persist a new User to a Repository based on passed-in attributes, where the
1855
+ resulting Entity (on success) contains a <code>:password_hash</code> attribute
1856
+ containing the encrypted value of a <strong>random</strong> Clear-Text Password; any
1857
+ <code>password</code> value within <code>attribs</code> is ignored.</p>
1858
+
1859
+ <p>The method <em>requires</em> a block, to which a <code>result</code> indicating success or
1860
+ failure is yielded. That block <strong>must</strong> in turn call <strong>both</strong>
1861
+ <code>result.success</code> and <code>result.failure</code> to handle success and failure results,
1862
+ respectively. On success, the block yielded to by <code>result.success</code> is called
1863
+ and passed a <code>user:</code> parameter, which is the newly-created User Entity.</p>
1864
+
1865
+ <p>If the call fails, the <code>result.success</code> block is yielded to, and passed a
1866
+ <code>code:</code> parameter, which will contain one of the following symbols:</p>
1867
+
1868
+ <ul>
1869
+ <li><code>:current_user_exists</code> indicates that the method was called with a
1870
+ Registered User as the <code>current_user</code> parameter.</li>
1871
+ <li><code>:user_already_created</code> indicates that the specified <code>name</code> attribute
1872
+ matches a record that already exists in the underlying Repository.</li>
1873
+ <li><code>:user_creation_failed</code> indicates that the Repository was unable to create
1874
+ the new User for some other reason, such as an internal error.</li>
1875
+ </ul>
1876
+
1877
+ <p><strong>NOTE</strong> that the incoming <code>params</code> are expected to have been whitelisted at
1878
+ the Controller Action Class level.</p>
1879
+
1880
+
1881
+ </div>
1882
+ </div>
1883
+ <div class="tags">
1884
+
1885
+ <div class="examples">
1886
+ <p class="tag_title">Examples:</p>
1887
+
1888
+
1889
+ <p class="example_title"><div class='inline'><p>in a Controller Action Class</p>
1890
+ </div></p>
1891
+
1892
+ <pre class="example code"><code><span class='kw'>def</span> <span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid__params'>_params</span><span class='rparen'>)</span>
1893
+ <span class='id identifier rubyid_sign_up'>sign_up</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='comma'>,</span> <span class='label'>current_user:</span> <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:current_user</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
1894
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_success'>success</span> <span class='kw'>do</span> <span class='op'>|</span><span class='label'>user:</span><span class='op'>|</span>
1895
+ <span class='ivar'>@user</span> <span class='op'>=</span> <span class='id identifier rubyid_user'>user</span>
1896
+ <span class='id identifier rubyid_message'>message</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> successfully created. You may sign in now.</span><span class='tstring_end'>&quot;</span></span>
1897
+ <span class='id identifier rubyid_flash'>flash</span><span class='lbracket'>[</span><span class='const'><span class='object_link'><a href="" title="CryptIdent (module)">CryptIdent</a></span></span><span class='period'>.</span><span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_success_key'>success_key</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_message'>message</span>
1898
+ <span class='id identifier rubyid_redirect_to'>redirect_to</span> <span class='id identifier rubyid_routes'>routes</span><span class='period'>.</span><span class='id identifier rubyid_root_path'>root_path</span>
1899
+ <span class='kw'>end</span>
1900
+
1901
+ <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_failure'>failure</span> <span class='kw'>do</span> <span class='op'>|</span><span class='label'>code:</span><span class='op'>|</span>
1902
+ <span class='comment'># `#error_message_for` is a method on the same class, not shown
1903
+ </span> <span class='id identifier rubyid_failure_key'>failure_key</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="" title="CryptIdent (module)">CryptIdent</a></span></span><span class='period'>.</span><span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_failure_key'>failure_key</span>
1904
+ <span class='id identifier rubyid_flash'>flash</span><span class='lbracket'>[</span><span class='id identifier rubyid_failure_key'>failure_key</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_error_message_for'>error_message_for</span><span class='lparen'>(</span><span class='id identifier rubyid_code'>code</span><span class='comma'>,</span> <span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span>
1905
+ <span class='kw'>end</span>
1906
+ <span class='kw'>end</span>
1907
+ <span class='kw'>end</span></code></pre>
1908
+
1909
+ </div>
1910
+ <p class="tag_title">Parameters:</p>
1911
+ <ul class="param">
1912
+
1913
+ <li>
1914
+
1915
+ <span class='name'>attribs</span>
1916
+
1917
+
1918
+ <span class='type'>(<tt>Hash</tt>)</span>
1919
+
1920
+
1921
+
1922
+ &mdash;
1923
+ <div class='inline'><p>Hash-like object of attributes for new User Entity and
1924
+ record. <strong>Must</strong> include <code>name</code> and any other attributes
1925
+ required by the underlying database schema. Any <code>password</code>
1926
+ attribute will be ignored.</p>
1927
+ </div>
1928
+
1929
+ </li>
1930
+
1931
+ <li>
1932
+
1933
+ <span class='name'>current_user</span>
1934
+
1935
+
1936
+ <span class='type'>(<tt>User</tt>, <tt>nil</tt>)</span>
1937
+
1938
+
1939
+
1940
+ &mdash;
1941
+ <div class='inline'><p>Entity representing the current
1942
+ Authenticated User, or the Guest User. A value of <code>nil</code> is
1943
+ treated as though the Guest User had been specified.</p>
1944
+ </div>
1945
+
1946
+ </li>
1947
+
1948
+ </ul>
1949
+
1950
+ <p class="tag_title">Yield Parameters:</p>
1951
+ <ul class="yieldparam">
1952
+
1953
+ <li>
1954
+
1955
+ <span class='name'>result</span>
1956
+
1957
+
1958
+ <span class='type'>(<tt>Dry::Matcher::Evaluator</tt>)</span>
1959
+
1960
+
1961
+
1962
+ &mdash;
1963
+ <div class='inline'><p>Indicates whether the attempt
1964
+ to create a new User succeeded or failed. Block <strong>must</strong>
1965
+ call <strong>both</strong> <code>result.success</code> and <code>result.failure</code> methods,
1966
+ where the block passed to <code>result.success</code> accepts a parameter
1967
+ for <code>user:</code> (which is the newly-created User Entity). The
1968
+ block passed to <code>result.failure</code> accepts a parameter for
1969
+ <code>code:</code>, which is a Symbol reporting the reason for the
1970
+ failure (as described above).</p>
1971
+ </div>
1972
+
1973
+ </li>
1974
+
1975
+ </ul>
1976
+ <p class="tag_title">Since:</p>
1977
+ <ul class="since">
1978
+
1979
+ <li>
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+ <div class='inline'><p>0.1.0</p>
1986
+ </div>
1987
+
1988
+ </li>
1989
+
1990
+ </ul>
1991
+ <p class="tag_title">Required Authentication Status:</p>
1992
+ <ul class="authenticated">
1993
+
1994
+ <li>
1995
+
1996
+
1997
+
1998
+
1999
+
2000
+ <div class='inline'><p>Must not be Authenticated.</p>
2001
+ </div>
2002
+
2003
+ </li>
2004
+
2005
+ </ul>
2006
+ <p class="tag_title">Session Data Interacted With:</p>
2007
+ <ul class="session_data">
2008
+
2009
+ <li>
2010
+
2011
+
2012
+
2013
+
2014
+
2015
+ <div class='inline'><p><code>:current_user</code> <strong>must not</strong> be a Registered User.</p>
2016
+ </div>
2017
+
2018
+ </li>
2019
+
2020
+ </ul>
2021
+ <p class="tag_title">Ubiquitous Language Terms:</p>
2022
+ <ul class="ubiq_lang">
2023
+
2024
+ <li>
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+ <div class='inline'><ul>
2031
+ <li>Authentication</li>
2032
+ <li>Clear-Text Password</li>
2033
+ <li>Entity</li>
2034
+ <li>Guest User</li>
2035
+ <li>Registered User</li>
2036
+ </ul>
2037
+ </div>
2038
+
2039
+ </li>
2040
+
2041
+ </ul>
2042
+
2043
+ </div><table class="source_code">
2044
+ <tr>
2045
+ <td>
2046
+ <pre class="lines">
2047
+
2048
+
2049
+ 87
2050
+ 88
2051
+ 89
2052
+ 90
2053
+ 91</pre>
2054
+ </td>
2055
+ <td>
2056
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/sign_up.rb', line 87</span>
2057
+
2058
+ <span class='kw'>def</span> <span class='id identifier rubyid_sign_up'>sign_up</span><span class='lparen'>(</span><span class='id identifier rubyid_attribs'>attribs</span><span class='comma'>,</span> <span class='label'>current_user:</span><span class='rparen'>)</span>
2059
+ <span class='const'>SignUp</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_attribs'>attribs</span><span class='comma'>,</span> <span class='label'>current_user:</span> <span class='id identifier rubyid_current_user'>current_user</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_result'>result</span><span class='op'>|</span>
2060
+ <span class='kw'>yield</span> <span class='id identifier rubyid_result'>result</span>
2061
+ <span class='kw'>end</span>
2062
+ <span class='kw'>end</span></pre>
2063
+ </td>
2064
+ </tr>
2065
+ </table>
2066
+ </div>
2067
+
2068
+ <div class="method_details ">
2069
+ <h3 class="signature " id="update_session_expiry-instance_method">
2070
+
2071
+ #<strong>update_session_expiry</strong>(session_data = {}) &#x21d2; <tt>Hash</tt>
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+ </h3><div class="docstring">
2078
+ <div class="discussion">
2079
+ <p>Generate a Hash containing an updated Session Expiration timestamp, which
2080
+ can then be used for session management.</p>
2081
+
2082
+ <p>This is one of two methods in <code>CryptIdent</code> (the other being
2083
+ <a href="#session-expired"><code>#session_expired?</code></a>) which <em>does not</em> follow the
2084
+ <code>result</code>/success/failure <a href="#interfaces">monad workflow</a>. This is because
2085
+ there is no success/failure division in the workflow. Calling the method
2086
+ only makes sense if there is a Registered User as the Current User, but <em>all
2087
+ this method does</em> is build a Hash with <code>:current_user</code> and <code>:expires_at</code>
2088
+ entries. The returned <code>:current_user</code> is the passed-in <code>:current_user</code> if a
2089
+ Registered User, or the Guest User if not. The returned <code>:updated_at</code> value,
2090
+ for a Registered User, is the configured Session Expiry added to the current
2091
+ time, and for the Guest User, a time far enough in the future that any call
2092
+ to <code>#session_expired?</code> will be highly unlikely to ever return <code>true</code>.</p>
2093
+
2094
+ <p>The client code is responsible for applying these values to its own actual
2095
+ session data, as described by the sample session-management code shown in
2096
+ the README.</p>
2097
+
2098
+
2099
+ </div>
2100
+ </div>
2101
+ <div class="tags">
2102
+
2103
+ <div class="examples">
2104
+ <p class="tag_title">Examples:</p>
2105
+
2106
+
2107
+ <p class="example_title"><div class='inline'><p>As used in module included by Controller Action Class (see README)</p>
2108
+ </div></p>
2109
+
2110
+ <pre class="example code"><code><span class='kw'>def</span> <span class='id identifier rubyid_validate_session'>validate_session</span>
2111
+ <span class='kw'>if</span> <span class='op'>!</span><span class='id identifier rubyid_session_expired?'>session_expired?</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='rparen'>)</span>
2112
+ <span class='id identifier rubyid_updates'>updates</span> <span class='op'>=</span> <span class='id identifier rubyid_update_session_expiry'>update_session_expiry</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='rparen'>)</span>
2113
+ <span class='id identifier rubyid_session'>session</span><span class='lbracket'>[</span><span class='symbol'>:expires_at</span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_updates'>updates</span><span class='lbracket'>[</span><span class='symbol'>:expires_at</span><span class='rbracket'>]</span>
2114
+ <span class='kw'>return</span>
2115
+ <span class='kw'>end</span>
2116
+
2117
+ <span class='comment'># ... sign out and redirect appropriately ...
2118
+ </span><span class='kw'>end</span></code></pre>
2119
+
2120
+ </div>
2121
+ <p class="tag_title">Parameters:</p>
2122
+ <ul class="param">
2123
+
2124
+ <li>
2125
+
2126
+ <span class='name'>session_data</span>
2127
+
2128
+
2129
+ <span class='type'>(<tt>Hash</tt>)</span>
2130
+
2131
+
2132
+ <em class="default">(defaults to: <tt>{}</tt>)</em>
2133
+
2134
+
2135
+ &mdash;
2136
+ <div class='inline'><p>The Rack session data of interest to the method.
2137
+ If the <code>:current_user</code> entry is defined, it <strong>must</strong> be either
2138
+ a User Entity or <code>nil</code>, signifying the Guest User. If the
2139
+ <code>:expires_at</code> entry is defined, its value in the returned Hash
2140
+ <em>will</em> be different.</p>
2141
+ </div>
2142
+
2143
+ </li>
2144
+
2145
+ </ul>
2146
+
2147
+ <p class="tag_title">Returns:</p>
2148
+ <ul class="return">
2149
+
2150
+ <li>
2151
+
2152
+
2153
+ <span class='type'>(<tt>Hash</tt>)</span>
2154
+
2155
+
2156
+
2157
+ &mdash;
2158
+ <div class='inline'><p>A <code>Hash</code> with entries to be used to update session data.
2159
+ <code>expires_at</code> will have a value of the current time plus the
2160
+ configuration-specified <code>session_expiry</code> offset <em>if</em> the
2161
+ supplied <code>:current_user</code> value is a Registered User;
2162
+ otherwise it will have a value far enough in advance of the
2163
+ current time (e.g., by 100 years) that the
2164
+ <code>#session_expired?</code> method is highly unlikely to ever return
2165
+ <code>true</code>. The <code>:current_user</code> value will be the passed-in
2166
+ <code>session_data[:current_user]</code> value if that represents a
2167
+ Registered User, or the Guest User otherwise.</p>
2168
+ </div>
2169
+
2170
+ </li>
2171
+
2172
+ </ul>
2173
+ <p class="tag_title">Since:</p>
2174
+ <ul class="since">
2175
+
2176
+ <li>
2177
+
2178
+
2179
+
2180
+
2181
+
2182
+ <div class='inline'><p>0.1.0</p>
2183
+ </div>
2184
+
2185
+ </li>
2186
+
2187
+ </ul>
2188
+ <p class="tag_title">Required Authentication Status:</p>
2189
+ <ul class="authenticated">
2190
+
2191
+ <li>
2192
+
2193
+
2194
+
2195
+
2196
+
2197
+ <div class='inline'><p>Must be Authenticated.</p>
2198
+ </div>
2199
+
2200
+ </li>
2201
+
2202
+ </ul>
2203
+ <p class="tag_title">Session Data Interacted With:</p>
2204
+ <ul class="session_data">
2205
+
2206
+ <li>
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+ <div class='inline'><p><code>:current_user</code> <strong>must</strong> be a User Entity. <code>nil</code> is accepted to indicate
2213
+ the Guest User
2214
+ <code>:expires_at</code> set to the session-expiration time on exit, which will be
2215
+ arbitrarily far in the future for the Guest User.</p>
2216
+ </div>
2217
+
2218
+ </li>
2219
+
2220
+ </ul>
2221
+ <p class="tag_title">Ubiquitous Language Terms:</p>
2222
+ <ul class="ubiq_lang">
2223
+
2224
+ <li>
2225
+
2226
+
2227
+
2228
+
2229
+
2230
+ <div class='inline'><ul>
2231
+ <li>Authentication</li>
2232
+ <li>Guest User</li>
2233
+ <li>Registered User</li>
2234
+ <li>Session Expiration</li>
2235
+ <li>User</li>
2236
+ </ul>
2237
+ </div>
2238
+
2239
+ </li>
2240
+
2241
+ </ul>
2242
+
2243
+ </div><table class="source_code">
2244
+ <tr>
2245
+ <td>
2246
+ <pre class="lines">
2247
+
2248
+
2249
+ 74
2250
+ 75
2251
+ 76</pre>
2252
+ </td>
2253
+ <td>
2254
+ <pre class="code"><span class="info file"># File 'lib/crypt_ident/update_session_expiry.rb', line 74</span>
2255
+
2256
+ <span class='kw'>def</span> <span class='id identifier rubyid_update_session_expiry'>update_session_expiry</span><span class='lparen'>(</span><span class='id identifier rubyid_session_data'>session_data</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
2257
+ <span class='const'>UpdateSessionExpiry</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_session_data'>session_data</span><span class='rparen'>)</span>
2258
+ <span class='kw'>end</span></pre>
2259
+ </td>
2260
+ </tr>
2261
+ </table>
2262
+ </div>
2263
+
2264
+ </div>
2265
+
2266
+ </div>
2267
+
2268
+ <div id="footer">
2269
+ Generated on Sat Feb 16 04:17:25 2019 by
2270
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
2271
+ 0.9.18 (ruby-2.6.0).
2272
+ </div>
2273
+
2274
+ </div>
2275
+ </body>
2276
+ </html>