crypt_ident 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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>