booth 0.0.1 → 0.0.2

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 (383) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/LICENSE.md +1 -2
  4. data/README.md +37 -6
  5. data/app/assets/images/booth/browsers/README.md +1 -2
  6. data/app/assets/images/booth/browsers/chrome.svg +1 -1
  7. data/app/assets/images/booth/browsers/edge.svg +1 -1
  8. data/app/assets/images/booth/browsers/firefox.svg +1 -1
  9. data/app/assets/images/booth/browsers/opera.svg +1 -1
  10. data/app/assets/images/booth/browsers/safari.svg +1 -1
  11. data/app/assets/images/booth/fido/passkey_mark_a.svg +10 -0
  12. data/app/assets/images/booth/fido/passkey_mark_a_black.svg +32 -0
  13. data/app/assets/images/booth/fido/passkey_mark_a_reverse.svg +33 -0
  14. data/app/assets/images/booth/fido/passkey_mark_a_white.svg +32 -0
  15. data/app/assets/images/booth/fido/passkey_mark_b_black.svg +1 -0
  16. data/app/assets/images/booth/platforms/android.svg +1 -6
  17. data/app/assets/images/booth/platforms/apple.svg +1 -6
  18. data/app/assets/images/booth/platforms/linux.svg +1 -6
  19. data/app/assets/images/booth/platforms/windows.svg +1 -6
  20. data/app/assets/javascripts/booth/authentication.js +29 -0
  21. data/app/assets/javascripts/booth/authentication.js.map +1 -0
  22. data/app/assets/javascripts/booth/error.js +38 -0
  23. data/app/assets/javascripts/booth/error.js.map +1 -0
  24. data/app/assets/javascripts/booth/form.js +78 -0
  25. data/app/assets/javascripts/booth/form.js.map +1 -0
  26. data/app/assets/javascripts/booth/gui.js +53 -0
  27. data/app/assets/javascripts/booth/gui.js.map +1 -0
  28. data/app/assets/javascripts/booth/registration.js +29 -0
  29. data/app/assets/javascripts/booth/registration.js.map +1 -0
  30. data/app/assets/javascripts/booth/setup.js +14 -0
  31. data/app/assets/javascripts/booth/verification.js +49 -0
  32. data/app/assets/javascripts/booth/verification.js.map +1 -0
  33. data/app/assets/javascripts/declarations/authentication.d.ts +6 -0
  34. data/app/assets/javascripts/declarations/error.d.ts +36 -0
  35. data/app/assets/javascripts/declarations/form.d.ts +8 -0
  36. data/app/assets/javascripts/declarations/gui.d.ts +4 -0
  37. data/app/assets/javascripts/declarations/registration.d.ts +6 -0
  38. data/app/assets/javascripts/declarations/setup.d.ts +3 -0
  39. data/app/assets/javascripts/declarations/verification.d.ts +6 -0
  40. data/app/assets/javascripts/src/authentication.ts +41 -0
  41. data/app/assets/javascripts/src/error.ts +35 -0
  42. data/app/assets/javascripts/src/form.ts +90 -0
  43. data/app/assets/javascripts/src/gui.ts +59 -0
  44. data/app/assets/javascripts/src/registration.ts +44 -0
  45. data/app/assets/javascripts/src/verification.ts +61 -0
  46. data/app/assets/stylesheets/booth/booth.css +3 -0
  47. data/config/importmap.rb +11 -0
  48. data/config/locales/de.yml +14 -38
  49. data/config/locales/en.yml +17 -36
  50. data/data/combined_aaguid.json +1 -0
  51. data/lib/booth/adminland/credentials/create.rb +10 -12
  52. data/lib/booth/adminland/credentials/index.rb +31 -0
  53. data/lib/booth/adminland/onboardings/create.rb +24 -15
  54. data/lib/booth/adminland/onboardings/destroy.rb +8 -4
  55. data/lib/booth/adminland/onboardings/find.rb +52 -45
  56. data/lib/booth/adminland/onboardings/find_unconsumed.rb +61 -0
  57. data/lib/booth/adminland/onboardings/index.rb +6 -3
  58. data/lib/booth/adminland/periodic_cleanup.rb +7 -2
  59. data/lib/booth/adminland.rb +17 -18
  60. data/lib/booth/coercers/domain.rb +11 -0
  61. data/lib/booth/coercers/request.rb +51 -0
  62. data/lib/booth/coercers/scope.rb +11 -0
  63. data/lib/booth/comparisons/domain.rb +38 -0
  64. data/lib/booth/comparisons/scope.rb +38 -0
  65. data/lib/booth/concerns/action.rb +25 -13
  66. data/lib/booth/concerns/transition.rb +5 -2
  67. data/lib/booth/configuration.rb +14 -73
  68. data/lib/booth/configure.rb +3 -10
  69. data/lib/booth/{audits/register → core/audit}/completed_onboarding.rb +8 -6
  70. data/lib/booth/core/audit/credential_created.rb +24 -0
  71. data/lib/booth/core/audit/logout.rb +24 -0
  72. data/lib/booth/core/authenticators/confirm.rb +30 -0
  73. data/lib/booth/core/authenticators/step.rb +24 -0
  74. data/lib/booth/core/cooldowns/distance_of_time.rb +50 -0
  75. data/lib/booth/core/cooldowns/strategies/exponential.rb +88 -0
  76. data/lib/booth/core/cooldowns/strategies/global.rb +66 -0
  77. data/lib/booth/core/cooldowns/strategies/result.rb +27 -0
  78. data/lib/booth/core/credentials/create.rb +32 -0
  79. data/lib/booth/core/credentials/find_by_username.rb +63 -0
  80. data/lib/booth/core/credentials/index.rb +15 -0
  81. data/lib/booth/core/credentials/webauth_challenge.rb +37 -0
  82. data/lib/booth/core/geolocation.rb +25 -0
  83. data/lib/booth/core/onboardings/find.rb +92 -0
  84. data/lib/booth/core/onboardings/step.rb +19 -0
  85. data/lib/booth/core/remotes/get.rb +45 -0
  86. data/lib/booth/core/remotes/respond.rb +82 -0
  87. data/lib/booth/core/remotes/set_for_login.rb +31 -0
  88. data/lib/booth/core/sessions/create_and_login.rb +63 -0
  89. data/lib/booth/core/sessions/historical_locations.rb +22 -0
  90. data/lib/booth/core/sessions/index.rb +66 -0
  91. data/lib/booth/core/sessions/revoke.rb +59 -0
  92. data/lib/booth/core/sessions/revoke_all_others.rb +49 -0
  93. data/lib/booth/core/sessions/to_passport.rb +35 -0
  94. data/lib/booth/core/webauth/authentication_verification.rb +76 -0
  95. data/lib/booth/core/webauth/options_for_create.rb +56 -0
  96. data/lib/booth/core/webauth/options_for_get.rb +30 -0
  97. data/lib/booth/core/webauth/provider.rb +36 -0
  98. data/lib/booth/core/webauth/registration_verification.rb +100 -0
  99. data/lib/booth/credential.rb +35 -0
  100. data/lib/booth/engine.rb +15 -4
  101. data/lib/booth/errors.rb +2 -0
  102. data/lib/booth/hooks/after_fetch.rb +14 -6
  103. data/lib/booth/hooks/before_logout.rb +5 -3
  104. data/lib/booth/hooks/serialize_from_session.rb +13 -5
  105. data/lib/booth/hooks/serialize_into_session.rb +6 -3
  106. data/lib/booth/logging.rb +13 -42
  107. data/lib/booth/models/application_record.rb +3 -0
  108. data/lib/booth/models/audit.rb +10 -11
  109. data/lib/booth/models/authenticator.rb +6 -9
  110. data/lib/booth/models/credential.rb +17 -20
  111. data/lib/booth/models/onboarding.rb +16 -39
  112. data/lib/booth/models/{contest.rb → remote.rb} +13 -14
  113. data/lib/booth/models/remotes/scopes/recently_created.rb +26 -0
  114. data/lib/booth/models/remotes/scopes/recently_responded.rb +35 -0
  115. data/lib/booth/models/session.rb +15 -10
  116. data/lib/booth/models/user_agent.rb +2 -0
  117. data/lib/booth/request.rb +43 -22
  118. data/lib/booth/requests/agent.rb +3 -1
  119. data/lib/booth/requests/authentication.rb +15 -5
  120. data/lib/booth/requests/ip.rb +4 -2
  121. data/lib/booth/requests/return_path.rb +4 -2
  122. data/lib/booth/requests/session.rb +6 -4
  123. data/lib/booth/requests/storage.rb +5 -31
  124. data/lib/booth/requests/storages/login.rb +35 -29
  125. data/lib/booth/requests/storages/registration.rb +2 -0
  126. data/lib/booth/requests/storages/webauth.rb +3 -0
  127. data/lib/booth/requests/sudo.rb +6 -50
  128. data/lib/booth/routes/userland.rb +13 -59
  129. data/lib/booth/syntaxes/domain.rb +46 -0
  130. data/lib/booth/syntaxes/email.rb +11 -8
  131. data/lib/booth/syntaxes/ip.rb +6 -4
  132. data/lib/booth/syntaxes/remote_code.rb +60 -0
  133. data/lib/booth/syntaxes/scope.rb +7 -3
  134. data/lib/booth/syntaxes/secret_key.rb +8 -6
  135. data/lib/booth/syntaxes/username.rb +23 -10
  136. data/lib/booth/syntaxes/uuid.rb +3 -1
  137. data/lib/booth/test.rb +27 -22
  138. data/lib/booth/testing/incorporation_test_case.rb +29 -0
  139. data/lib/booth/testing/shortcuts.rb +77 -0
  140. data/lib/booth/testing/support/assert_all_partials_were_covered.rb +69 -0
  141. data/lib/booth/testing/support/assert_logged_in.rb +68 -0
  142. data/lib/booth/{test → testing}/support/assert_logged_out.rb +7 -4
  143. data/lib/booth/testing/support/assert_partial.rb +56 -0
  144. data/lib/booth/{test → testing}/support/force_login.rb +10 -4
  145. data/lib/booth/{test → testing}/support/get_session_value.rb +8 -6
  146. data/lib/booth/testing/support/scenario.rb +23 -0
  147. data/lib/booth/testing/support/shortcuts/create_and_onboard.rb +56 -0
  148. data/lib/booth/testing/support/shortcuts/login_with_passkey.rb +55 -0
  149. data/lib/booth/testing/support/shortcuts/register_new_passkey.rb +51 -0
  150. data/lib/booth/testing/support/soft_reset_session.rb +24 -0
  151. data/lib/booth/testing/support/virtual_authenticators/create.rb +34 -0
  152. data/lib/booth/testing/support/virtual_authenticators/destroy.rb +20 -0
  153. data/lib/booth/testing/support/virtual_authenticators/enable.rb +24 -0
  154. data/lib/booth/testing/support/virtual_authenticators/load.rb +38 -0
  155. data/lib/booth/testing/support/virtual_authenticators/manager.rb +124 -0
  156. data/lib/booth/testing/support/visit.rb +62 -0
  157. data/lib/booth/testing/userland/login_remotely.rb +100 -0
  158. data/lib/booth/testing/userland/onboarding_first_time.rb +81 -0
  159. data/lib/booth/testing/userland/onboarding_to_reset_passkeys.rb +129 -0
  160. data/lib/booth/testing/userland/registration_with_passkey.rb +93 -0
  161. data/lib/booth/testing/userland/registration_without_passkey.rb +101 -0
  162. data/lib/booth/testing/userland/sessions_manage_behavior.rb +68 -0
  163. data/lib/booth/testing/userland/sessions_revoke_all_others.rb +17 -0
  164. data/lib/booth/testing/userland/sessions_revoke_one.rb +17 -0
  165. data/lib/booth/testing/userland.rb +36 -0
  166. data/lib/booth/to_struct.rb +9 -2
  167. data/lib/booth/userland/extract_flash_messages.rb +10 -3
  168. data/lib/booth/userland/logins/create.rb +8 -6
  169. data/lib/booth/userland/logins/destroy.rb +23 -6
  170. data/lib/booth/userland/logins/new.rb +23 -25
  171. data/lib/booth/userland/logins/transitions/create/choose_username.rb +62 -27
  172. data/lib/booth/userland/logins/transitions/create/skip_remotes.rb +18 -14
  173. data/lib/booth/userland/logins/transitions/create/webauth_authentication_initiation.rb +54 -48
  174. data/lib/booth/userland/logins/transitions/create/webauth_authentication_verification.rb +62 -58
  175. data/lib/booth/userland/logins/transitions/new/already_logged_in.rb +4 -3
  176. data/lib/booth/userland/logins/transitions/new/fallible.rb +4 -0
  177. data/lib/booth/userland/logins/transitions/new/{mode_username_and_password.rb → missing_authenticators.rb} +5 -4
  178. data/lib/booth/userland/logins/transitions/new/mode_username_and_webauth.rb +6 -4
  179. data/lib/booth/userland/logins/transitions/new/no_username_chosen.rb +3 -1
  180. data/lib/booth/userland/logins/transitions/new/remote_session_available.rb +20 -13
  181. data/lib/booth/userland/logins/transitions/new/timed_out.rb +3 -1
  182. data/lib/booth/userland/onboardings/show.rb +65 -39
  183. data/lib/booth/userland/onboardings/update.rb +46 -38
  184. data/lib/booth/userland/registrations/create.rb +51 -20
  185. data/lib/booth/userland/registrations/new.rb +6 -7
  186. data/lib/booth/userland/remotes/show.rb +56 -0
  187. data/lib/booth/userland/{personal_contests → remotes}/update.rb +5 -3
  188. data/lib/booth/userland/sessions/destroy_one_or_other.rb +3 -16
  189. data/lib/booth/userland/sessions/index.rb +4 -2
  190. data/lib/booth/userland/sessions/show.rb +5 -6
  191. data/lib/booth/userland/sessions/transitions/destroy/enter_webauth.rb +8 -6
  192. data/lib/booth/userland/sessions/transitions/destroy/webauth_authentication_initiation.rb +8 -6
  193. data/lib/booth/userland/sessions/transitions/destroy/webauth_authentication_verification.rb +7 -5
  194. data/lib/booth/userland/sessions/transitions/show/enter_webauth.rb +8 -6
  195. data/lib/booth/userland/webauths/create.rb +20 -17
  196. data/lib/booth/userland/webauths/destroy.rb +6 -16
  197. data/lib/booth/userland/webauths/guards/sudo.rb +10 -5
  198. data/lib/booth/userland/webauths/index.rb +4 -2
  199. data/lib/booth/userland/webauths/new.rb +7 -22
  200. data/lib/booth/userland/webauths/sudo.rb +3 -1
  201. data/lib/booth/userland/webauths/transitions/create/authentication_initiation.rb +8 -11
  202. data/lib/booth/userland/webauths/transitions/create/authentication_verification.rb +11 -13
  203. data/lib/booth/userland/webauths/transitions/create/choose_nickname.rb +8 -5
  204. data/lib/booth/userland/webauths/transitions/create/registration_initiation.rb +15 -14
  205. data/lib/booth/userland/webauths/transitions/create/registration_verification.rb +34 -28
  206. data/lib/booth/userland/webauths/transitions/create/reset.rb +2 -0
  207. data/lib/booth/userland/webauths/transitions/new/step.rb +3 -1
  208. data/lib/booth/userland/webauths/transitions/sudo/authentication_initiation.rb +5 -10
  209. data/lib/booth/userland/webauths/transitions/sudo/authentication_verification.rb +4 -2
  210. data/lib/booth/userland.rb +53 -109
  211. data/lib/booth/version.rb +3 -1
  212. data/lib/booth.rb +6 -236
  213. data/lib/generators/booth/migration/migration_generator.rb +2 -1
  214. data/lib/generators/booth/migration/templates/add_credential_to_users.erb +6 -4
  215. data/lib/generators/booth/migration/templates/create_booth_tables.erb +61 -72
  216. metadata +124 -571
  217. data/app/assets/config/booth_manifest.js +0 -15
  218. data/app/assets/images/booth/browsers/internet_explorer.svg +0 -1
  219. data/app/assets/javascripts/booth/all.js +0 -162
  220. data/app/assets/javascripts/booth/all.js.map +0 -1
  221. data/app/assets/javascripts/booth/booth.ts +0 -194
  222. data/app/assets/javascripts/booth/webauthn-json.ts +0 -99
  223. data/lib/booth/adminland/recoveries/consume.rb +0 -70
  224. data/lib/booth/audits/register/added_otp.rb +0 -22
  225. data/lib/booth/audits/register/changed_otp.rb +0 -22
  226. data/lib/booth/audits/register/correct_otp.rb +0 -42
  227. data/lib/booth/audits/register/correct_password.rb +0 -43
  228. data/lib/booth/audits/register/logout.rb +0 -22
  229. data/lib/booth/audits/register/requested_password_reset.rb +0 -22
  230. data/lib/booth/audits/register/wrong_otp.rb +0 -22
  231. data/lib/booth/audits/register/wrong_password.rb +0 -25
  232. data/lib/booth/authenticators/confirm.rb +0 -34
  233. data/lib/booth/authenticators/credential_mode_after_confirmation.rb +0 -25
  234. data/lib/booth/authenticators/step.rb +0 -19
  235. data/lib/booth/contests/get.rb +0 -36
  236. data/lib/booth/contests/respond.rb +0 -78
  237. data/lib/booth/contests/set_for_login.rb +0 -28
  238. data/lib/booth/cooldowns/distance_of_time.rb +0 -46
  239. data/lib/booth/cooldowns/otp.rb +0 -22
  240. data/lib/booth/cooldowns/password.rb +0 -44
  241. data/lib/booth/cooldowns/password_reset.rb +0 -24
  242. data/lib/booth/cooldowns/strategies/exponential.rb +0 -82
  243. data/lib/booth/cooldowns/strategies/global.rb +0 -62
  244. data/lib/booth/cooldowns/strategies/result.rb +0 -22
  245. data/lib/booth/credentials/create.rb +0 -28
  246. data/lib/booth/credentials/create_with_onboarding.rb +0 -26
  247. data/lib/booth/credentials/find_by_username.rb +0 -45
  248. data/lib/booth/credentials/mode.rb +0 -69
  249. data/lib/booth/credentials/modes/otp_addable.rb +0 -23
  250. data/lib/booth/credentials/modes/otp_changeable.rb +0 -23
  251. data/lib/booth/credentials/modes/otp_manageable.rb +0 -17
  252. data/lib/booth/credentials/modes/otp_removable.rb +0 -23
  253. data/lib/booth/credentials/modes/password_addable.rb +0 -29
  254. data/lib/booth/credentials/modes/password_changeable.rb +0 -31
  255. data/lib/booth/credentials/modes/password_manageable.rb +0 -17
  256. data/lib/booth/credentials/modes/password_removable.rb +0 -24
  257. data/lib/booth/credentials/modes/password_removal_requires_user_verifiable_webauth.rb +0 -16
  258. data/lib/booth/credentials/modes/webauth_addable.rb +0 -26
  259. data/lib/booth/credentials/modes/webauth_manageable.rb +0 -16
  260. data/lib/booth/credentials/modes/webauth_removable.rb +0 -25
  261. data/lib/booth/credentials/otp_authentication.rb +0 -59
  262. data/lib/booth/credentials/password_authentication.rb +0 -72
  263. data/lib/booth/credentials/webauth_challenge.rb +0 -28
  264. data/lib/booth/geolocation.rb +0 -20
  265. data/lib/booth/logger.rb +0 -41
  266. data/lib/booth/method_object.rb +0 -73
  267. data/lib/booth/mode.rb +0 -22
  268. data/lib/booth/models/concerns/modeable.rb +0 -50
  269. data/lib/booth/models/concerns/otpable.rb +0 -37
  270. data/lib/booth/models/concerns/passwordable.rb +0 -58
  271. data/lib/booth/models/contests/scopes/recently_created.rb +0 -23
  272. data/lib/booth/models/contests/scopes/recently_responded.rb +0 -32
  273. data/lib/booth/models/password_reset.rb +0 -41
  274. data/lib/booth/models/recovery.rb +0 -32
  275. data/lib/booth/models/registration.rb +0 -10
  276. data/lib/booth/modes/base.rb +0 -25
  277. data/lib/booth/modes/username_and_password.rb +0 -7
  278. data/lib/booth/modes/username_and_webauth.rb +0 -7
  279. data/lib/booth/modes/username_password_and_otp.rb +0 -7
  280. data/lib/booth/modes/username_password_and_webauth.rb +0 -7
  281. data/lib/booth/onboardings/find.rb +0 -35
  282. data/lib/booth/onboardings/propagate_to_credential.rb +0 -63
  283. data/lib/booth/onboardings/step.rb +0 -68
  284. data/lib/booth/password_resets/create.rb +0 -57
  285. data/lib/booth/password_resets/find.rb +0 -36
  286. data/lib/booth/password_resets/propagate_to_credential.rb +0 -36
  287. data/lib/booth/password_resets/step.rb +0 -18
  288. data/lib/booth/recoveries/create.rb +0 -45
  289. data/lib/booth/requests/storages/otp.rb +0 -54
  290. data/lib/booth/requests/storages/password.rb +0 -49
  291. data/lib/booth/requests/storages/password_reset.rb +0 -35
  292. data/lib/booth/requests/storages/recovery.rb +0 -35
  293. data/lib/booth/sessions/create_and_login.rb +0 -46
  294. data/lib/booth/sessions/historical_locations.rb +0 -18
  295. data/lib/booth/sessions/index.rb +0 -59
  296. data/lib/booth/sessions/revoke.rb +0 -51
  297. data/lib/booth/sessions/revoke_all_others.rb +0 -43
  298. data/lib/booth/sessions/to_passport.rb +0 -51
  299. data/lib/booth/syntaxes/contest_code.rb +0 -58
  300. data/lib/booth/syntaxes/otp.rb +0 -57
  301. data/lib/booth/syntaxes/scope_comparison.rb +0 -28
  302. data/lib/booth/test/helpers.rb +0 -63
  303. data/lib/booth/test/support/assert_all_partials_were_covered.rb +0 -63
  304. data/lib/booth/test/support/assert_logged_in.rb +0 -49
  305. data/lib/booth/test/support/assert_partial.rb +0 -29
  306. data/lib/booth/test/support/otp_code_from_session.rb +0 -30
  307. data/lib/booth/test/support/soft_reset_session.rb +0 -22
  308. data/lib/booth/test/userland/logins/missing_authenticators.rb +0 -72
  309. data/lib/booth/test/userland/logins/missing_onboarding.rb +0 -35
  310. data/lib/booth/test/userland/logins/username_and_password.rb +0 -40
  311. data/lib/booth/test/userland/logins/username_and_webauth.rb +0 -75
  312. data/lib/booth/test/userland/logins/username_password_and_otp.rb +0 -45
  313. data/lib/booth/test/userland/logins/username_password_and_webauth.rb +0 -86
  314. data/lib/booth/test/userland/onboardings/already_logged_in.rb +0 -64
  315. data/lib/booth/test/userland/onboardings/otp.rb +0 -63
  316. data/lib/booth/test/userland/onboardings/password.rb +0 -49
  317. data/lib/booth/test/userland/onboardings/timeout.rb +0 -47
  318. data/lib/booth/test/userland/otps/manage.rb +0 -86
  319. data/lib/booth/test/userland/password_resets/reset.rb +0 -102
  320. data/lib/booth/test/userland.rb +0 -38
  321. data/lib/booth/test/webauthn/disable.rb +0 -17
  322. data/lib/booth/test/webauthn/enable.rb +0 -19
  323. data/lib/booth/test/webauthn/virtual_authenticators/create.rb +0 -38
  324. data/lib/booth/test/webauthn/virtual_authenticators/destroy.rb +0 -20
  325. data/lib/booth/userland/logins/transitions/create/enter_otp.rb +0 -70
  326. data/lib/booth/userland/logins/transitions/create/verify_password.rb +0 -70
  327. data/lib/booth/userland/logins/transitions/new/mode_first_time.rb +0 -20
  328. data/lib/booth/userland/logins/transitions/new/mode_username_password_and_otp.rb +0 -24
  329. data/lib/booth/userland/logins/transitions/new/mode_username_password_and_webauth.rb +0 -24
  330. data/lib/booth/userland/onboardings/transitions/update/choose_mode.rb +0 -58
  331. data/lib/booth/userland/onboardings/transitions/update/choose_password.rb +0 -41
  332. data/lib/booth/userland/onboardings/transitions/update/choose_webauth_nickname.rb +0 -50
  333. data/lib/booth/userland/onboardings/transitions/update/confirm_otp.rb +0 -58
  334. data/lib/booth/userland/onboardings/transitions/update/confirm_password.rb +0 -49
  335. data/lib/booth/userland/onboardings/transitions/update/register_otp.rb +0 -31
  336. data/lib/booth/userland/onboardings/transitions/update/reset_otp.rb +0 -40
  337. data/lib/booth/userland/onboardings/transitions/update/reset_password.rb +0 -35
  338. data/lib/booth/userland/onboardings/transitions/update/reset_webauth.rb +0 -46
  339. data/lib/booth/userland/onboardings/transitions/update/webauth_authentication_initiation.rb +0 -40
  340. data/lib/booth/userland/onboardings/transitions/update/webauth_authentication_verification.rb +0 -59
  341. data/lib/booth/userland/onboardings/transitions/update/webauth_registration_initiation.rb +0 -46
  342. data/lib/booth/userland/onboardings/transitions/update/webauth_registration_verification.rb +0 -56
  343. data/lib/booth/userland/otps/destroy.rb +0 -42
  344. data/lib/booth/userland/otps/edit.rb +0 -72
  345. data/lib/booth/userland/otps/guards/manageable.rb +0 -21
  346. data/lib/booth/userland/otps/guards/sudo.rb +0 -23
  347. data/lib/booth/userland/otps/show.rb +0 -36
  348. data/lib/booth/userland/otps/sudo.rb +0 -51
  349. data/lib/booth/userland/otps/transitions/update/confirm.rb +0 -84
  350. data/lib/booth/userland/otps/transitions/update/register.rb +0 -40
  351. data/lib/booth/userland/otps/transitions/update/reset.rb +0 -31
  352. data/lib/booth/userland/otps/update.rb +0 -34
  353. data/lib/booth/userland/password_resets/create.rb +0 -73
  354. data/lib/booth/userland/password_resets/guards/logged_out.rb +0 -21
  355. data/lib/booth/userland/password_resets/new.rb +0 -57
  356. data/lib/booth/userland/password_resets/show.rb +0 -77
  357. data/lib/booth/userland/password_resets/transitions/update/choose_password.rb +0 -48
  358. data/lib/booth/userland/password_resets/transitions/update/confirm_password.rb +0 -54
  359. data/lib/booth/userland/password_resets/transitions/update/reset_password.rb +0 -29
  360. data/lib/booth/userland/password_resets/update.rb +0 -65
  361. data/lib/booth/userland/passwords/destroy.rb +0 -41
  362. data/lib/booth/userland/passwords/edit.rb +0 -54
  363. data/lib/booth/userland/passwords/guards/manageable.rb +0 -21
  364. data/lib/booth/userland/passwords/guards/removable.rb +0 -21
  365. data/lib/booth/userland/passwords/guards/sudo.rb +0 -21
  366. data/lib/booth/userland/passwords/remove.rb +0 -34
  367. data/lib/booth/userland/passwords/show.rb +0 -32
  368. data/lib/booth/userland/passwords/sudo.rb +0 -55
  369. data/lib/booth/userland/passwords/transitions/remove/step.rb +0 -27
  370. data/lib/booth/userland/passwords/transitions/update/choose_password.rb +0 -62
  371. data/lib/booth/userland/passwords/transitions/update/confirm_password.rb +0 -82
  372. data/lib/booth/userland/passwords/update.rb +0 -33
  373. data/lib/booth/userland/personal_contests/show.rb +0 -60
  374. data/lib/booth/userland/recoveries/create.rb +0 -48
  375. data/lib/booth/userland/recoveries/new.rb +0 -35
  376. data/lib/booth/userland/sessions/transitions/destroy/enter_password.rb +0 -50
  377. data/lib/booth/userland/sessions/transitions/destroy/verify_password.rb +0 -83
  378. data/lib/booth/userland/webauths/guards/manageable.rb +0 -21
  379. data/lib/booth/webauth/authentication_verification.rb +0 -68
  380. data/lib/booth/webauth/demand_user_verification.rb +0 -29
  381. data/lib/booth/webauth/options_for_create.rb +0 -46
  382. data/lib/booth/webauth/options_for_get.rb +0 -29
  383. data/lib/generators/booth/migration/templates/create_booth_mode_types.erb +0 -20
@@ -1,28 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
2
4
  module Adminland
3
5
  module Credentials
4
6
  class Create
5
- include ::Booth::MethodObject
7
+ include Calls
6
8
  include ::Booth::Logging
7
9
 
10
+ option :domain
11
+ option :scope
8
12
  option :username
9
- option :allowed_modes
10
- option :scope, default: -> { :default }
11
13
 
12
14
  def call
13
- creation = ::Booth::Credentials::Create.call(
14
- username:,
15
- allowed_modes:,
16
- scope:
17
- )
15
+ creation = ::Booth::Core::Credentials::Create.call(domain:, scope:, username:)
18
16
 
19
17
  return creation if creation.failure?
20
18
 
21
19
  # Not exposing the ActiveRecord model outside of Booth.
22
- Tron.success :credential_created,
23
- id: creation.credential.id,
24
- scope: creation.credential.scope,
25
- allowed_modes: creation.credential.allowed_modes.map(&:to_sym)
20
+ Tron.success :credential_created, id: creation.credential.id,
21
+ domain: creation.credential.domain,
22
+ scope: creation.credential.scope,
23
+ username: creation.credential.username
26
24
  end
27
25
  end
28
26
  end
@@ -0,0 +1,31 @@
1
+ # # frozen_string_literal: true
2
+
3
+ # module Booth
4
+ # module Adminland
5
+ # module Credentials
6
+ # class Index
7
+ # include Calls
8
+ # include ::Booth::Logging
9
+
10
+ # option :domain
11
+ # option :scope
12
+
13
+ # def call
14
+ # # TODO: Pagination
15
+ # records = Booth::Models::Credential.sorted_scope
16
+ # .where(domain:, scope:)
17
+ # .limit(100)
18
+ # .map do |credential|
19
+ # # Not exposing ActiveRecord models outside of Booth.
20
+ # ::Booth::ToStruct.call(id: credential.id,
21
+ # username: credential.username)
22
+ # end
23
+
24
+ # Tron.success :indexed_credentials, records:,
25
+ # domain:,
26
+ # scope:
27
+ # end
28
+ # end
29
+ # end
30
+ # end
31
+ # end
@@ -1,22 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
2
4
  module Adminland
3
5
  module Onboardings
4
6
  class Create
5
- include ::Booth::MethodObject
7
+ include Calls
6
8
  include ::Booth::Logging
7
9
 
8
10
  option :credential_id
9
11
 
10
12
  def call
11
- find_action.on_success { validate_action }
12
- .on_success { save_action }
13
+ do_find_record.on_success { do_validate }
14
+ .on_success { do_save }
13
15
  end
14
16
 
15
17
  private
16
18
 
17
- def find_action
19
+ def do_find_record
18
20
  if credential
19
- debug { "Found the credential with id #{credential_id.inspect}, deleting any current onboardings" }
21
+ log { "Found Credential with ID #{credential_id.inspect}, deleting other onboardings" }
20
22
  ::Booth::Models::Onboarding.where(credential_id: credential.id).destroy_all
21
23
  Tron.success :credential_exists
22
24
  else
@@ -25,27 +27,34 @@ module Booth
25
27
  end
26
28
  end
27
29
 
28
- def validate_action
30
+ def do_validate
29
31
  if onboarding.valid?
30
- debug { 'The new onboarding record is valid' }
32
+ log { 'The new onboarding record is valid' }
31
33
  Tron.success :record_is_valid
32
34
  else
33
- debug { "The new onboarding record is invalid: #{onboarding.errors.full_messages.to_sentence}" }
34
- Tron.failure :invalid_record, message: onboarding.errors.full_messages.to_sentence
35
+ log { "The new Onboarding is invalid: #{onboarding.errors.to_a.to_sentence}" }
36
+ Tron.failure :invalid_record, message: onboarding.errors.to_a.to_sentence
35
37
  end
36
38
  end
37
39
 
38
- def save_action
40
+ def do_save
39
41
  if onboarding.save
40
- debug { 'Successfully persisted a new onboarding record' }
41
- Tron.success :onboarding_created, id: onboarding.id, credential_id: credential.id,
42
- secret_key: onboarding.secret_key
42
+ respond_success
43
43
  else
44
- debug { 'Could not persist a new onboarding record' }
45
- Tron.failure :persistence_failed, message: onboarding.errors.full_messages.to_sentence
44
+ log { 'Could not persist a new onboarding record' }
45
+ Tron.failure :persistence_failed, message: onboarding.errors.to_a.to_sentence
46
46
  end
47
47
  end
48
48
 
49
+ def respond_success
50
+ log { 'Successfully persisted a new onboarding record' }
51
+ emit 'onboarding.created', id: onboarding.id, credential_id: credential.id
52
+
53
+ Tron.success :onboarding_created, id: onboarding.id,
54
+ credential_id: credential.id,
55
+ secret_key: onboarding.secret_key
56
+ end
57
+
49
58
  def credential
50
59
  return @credential if defined?(@credential)
51
60
 
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
2
4
  module Adminland
3
5
  module Onboardings
4
6
  class Destroy
5
7
  include ::Booth::Logging
6
- include ::Booth::MethodObject
8
+ include Calls
7
9
 
8
10
  option :id, as: :raw_id
9
11
 
@@ -16,14 +18,14 @@ module Booth
16
18
  def do_verify_id
17
19
  return Tron.success :valid_id_syntax if id
18
20
 
19
- debug { "Invalid Onboarding ID #{raw_id.inspect}" }
21
+ log { "Invalid Onboarding ID #{raw_id.inspect}" }
20
22
  Tron.failure :invalid_id_syntax, id:, credential_id: nil
21
23
  end
22
24
 
23
25
  def do_find_record
24
26
  return Tron.success :record_found if record
25
27
 
26
- debug { "Could not find Onboarding with ID #{id.inspect}" }
28
+ log { "Could not find Onboarding with ID #{id.inspect}" }
27
29
  Tron.failure :onboarding_not_found, id: nil, credential_id: nil
28
30
  end
29
31
 
@@ -42,7 +44,9 @@ module Booth
42
44
  end
43
45
 
44
46
  def record
45
- @record ||= ::Booth::Models::Onboarding.find_by(id:)
47
+ return @record if defined?(@record)
48
+
49
+ @record = ::Booth::Models::Onboarding.find_by(id:)
46
50
  end
47
51
  end
48
52
  end
@@ -1,91 +1,98 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
2
4
  module Adminland
3
5
  module Onboardings
6
+ # Find a Onboarding either by #id or #credential_id.
4
7
  class Find
8
+ include Calls
5
9
  include ::Booth::Logging
6
- include ::Booth::MethodObject
7
10
 
8
- option :id, default: -> {}
9
- option :credential_id, default: -> {}, as: :raw_credential_id
10
- option :raise_if_missing, default: -> { false }
11
- option :only_unused, default: -> { false }
11
+ option :domain
12
+ option :scope
13
+ option :id, as: :raw_id, optional: true
14
+ option :credential_id, as: :raw_credential_id, optional: true
12
15
 
13
16
  def call
14
- do_check_id
17
+ do_check_domain
18
+ .on_success { do_check_id_argument }
19
+ .on_success { do_check_scope }
20
+ .on_success { do_check_id }
15
21
  .on_success { do_find_onboarding }
16
- .on_success { do_check_used }
17
22
  .on_success { do_serialize_onboarding }
18
23
  end
19
24
 
20
25
  private
21
26
 
22
- def do_check_id
23
- return Tron.success(:id_is_valid) if onboarding_id || credential_id
27
+ attr_accessor :onboarding
24
28
 
25
- Tron.failure :no_id_provided, record: nil
29
+ # TODO: Actually compare
30
+ def do_check_domain
31
+ ::Booth::Syntaxes::Domain.call(domain)
26
32
  end
27
33
 
28
- def do_find_onboarding
29
- @onboarding = if onboarding_id
30
- ::Booth::Models::Onboarding.find_by(id: onboarding_id)
31
- else
32
- ::Booth::Models::Onboarding.find_by(credential_id:)
33
- end
34
-
35
- return Tron.success :onboarding_exists if @onboarding
34
+ def do_check_scope
35
+ ::Booth::Syntaxes::Scope.call(scope)
36
+ end
36
37
 
37
- if onboarding_id
38
- debug { "Couldn't find Onboarding with ID #{onboarding_id.inspect}" }
38
+ def do_check_id_argument
39
+ if @raw_id == Dry::Initializer::UNDEFINED &&
40
+ @raw_credential_id == Dry::Initializer::UNDEFINED
41
+ Tron.failure(:missing_id_or_credential_id)
39
42
  else
40
- debug { "Couldn't find Onboarding with credential ID #{credential_id.inspect}" }
43
+ Tron.success(:id_or_credential_id_was_provided)
41
44
  end
45
+ end
42
46
 
43
- result = Tron.failure :onboarding_not_found, provided_onboarding_id: id.inspect,
44
- provided_credential_id: raw_credential_id.inspect,
45
- record: nil
46
- raise result if raise_if_missing
47
+ def do_check_id
48
+ return Tron.success(:id_is_valid) if onboarding_id || credential_id
47
49
 
48
- result
50
+ Tron.failure :invalid_id_provided
49
51
  end
50
52
 
51
- def do_check_used
52
- return Tron.success :onboarding_is_new if @onboarding.step == :choose_mode
53
- return Tron.success :we_allow_used_onboardings unless only_unused
53
+ def do_find_onboarding
54
+ self.onboarding = find_onboarding
55
+
56
+ return Tron.success :onboarding_exists if onboarding
54
57
 
55
- error = Tron.failure(:onboarding_already_used, provided_onboarding_id: id.inspect,
56
- provided_credential_id: raw_credential_id.inspect,
57
- record: nil)
58
- raise error if raise_if_missing
58
+ if onboarding_id
59
+ log { "Couldn't find Onboarding with ID #{onboarding_id.inspect}" }
60
+ else
61
+ log { "Couldn't find Onboarding with credential ID #{credential_id.inspect}" }
62
+ end
59
63
 
60
- error
64
+ Tron.failure :onboarding_not_found, provided_onboarding_id: raw_id,
65
+ provided_credential_id: raw_credential_id
61
66
  end
62
67
 
63
68
  def do_serialize_onboarding
64
69
  attributes = @onboarding.attributes
65
70
  .symbolize_keys
66
- .slice(:id, :credential_id, :secret_key, :accessed_at, :mode)
67
- .merge(additional_attributes)
71
+ .slice(:id, :credential_id, :secret_key, :accessed_at, :consumed_at)
72
+ .merge(username: onboarding.username, consumed?: onboarding.consumed?, domain:)
68
73
 
69
- debug { "Onboarding found ID #{@onboarding.id.inspect} and Credential ID #{@onboarding.credential_id.inspect}" }
70
- Tron.success(:onboarding_found, record: ::Booth::ToStruct.call(attributes))
74
+ log do
75
+ "Onboarding found ID #{@onboarding.id.inspect} and Credential ID #{@onboarding.credential_id.inspect}"
76
+ end
77
+ Tron.success(:onboarding_found, **attributes)
71
78
  end
72
79
 
73
80
  # Helpers
74
81
 
75
82
  def onboarding_id
76
- ::Booth::Syntaxes::Uuid.call(id, raise_if_invalid: false).uuid
83
+ ::Booth::Syntaxes::Uuid.call(raw_id, raise_if_invalid: false).uuid
77
84
  end
78
85
 
79
86
  def credential_id
80
87
  ::Booth::Syntaxes::Uuid.call(raw_credential_id, raise_if_invalid: false).uuid
81
88
  end
82
89
 
83
- def additional_attributes
84
- {
85
- step: @onboarding.step,
86
- username: @onboarding.username,
87
- is_completed: @onboarding.completed?,
88
- }
90
+ def find_onboarding
91
+ if onboarding_id
92
+ ::Booth::Models::Onboarding.find_by(id: onboarding_id)
93
+ else
94
+ ::Booth::Models::Onboarding.find_by(credential_id:)
95
+ end
89
96
  end
90
97
  end
91
98
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Booth
4
+ module Adminland
5
+ module Onboardings
6
+ # Find a Onboarding that can still be consumed.
7
+ class FindUnconsumed
8
+ include Calls
9
+ include ::Booth::Logging
10
+
11
+ option :id, as: :raw_id
12
+
13
+ def call
14
+ do_check_id
15
+ .on_success { do_find_onboarding }
16
+ .on_success { do_check_consumed }
17
+ .on_success { do_serialize_onboarding }
18
+ end
19
+
20
+ private
21
+
22
+ attr_accessor :onboarding
23
+
24
+ def do_check_id
25
+ return Tron.success(:id_is_valid) if id
26
+
27
+ Tron.failure :no_id_provided, record: nil
28
+ end
29
+
30
+ def do_find_onboarding
31
+ self.onboarding = Booth::Models::Onboarding.find_by(id:)
32
+ return Tron.success(:onboarding_exists) if onboarding
33
+
34
+ Tron.failure(:onboarding_not_found, id:, record: nil)
35
+ end
36
+
37
+ def do_check_consumed
38
+ return Tron.success :onboarding_can_be_consumed unless onboarding.consumed?
39
+
40
+ Tron.failure(:onboarding_already_consumed, id:, record: nil)
41
+ end
42
+
43
+ def do_serialize_onboarding
44
+ attributes = onboarding.attributes
45
+ .symbolize_keys
46
+ .slice(:id, :credential_id, :secret_key, :consumed?)
47
+ .merge(username: onboarding.username)
48
+
49
+ log { "Onboarding with ID #{@onboarding.id.inspect} found" }
50
+ Tron.success(:onboarding_found, record: ::Booth::ToStruct.call(attributes))
51
+ end
52
+
53
+ # Helpers
54
+
55
+ def id
56
+ ::Booth::Syntaxes::Uuid.call(raw_id, raise_if_invalid: false).uuid
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
2
4
  module Adminland
3
5
  module Onboardings
4
6
  class Index
5
- include ::Booth::MethodObject
7
+ include Calls
6
8
 
7
- option :scope, ->(scope) { ::Booth::Syntaxes::Scope.call(scope).normalized_scope }
9
+ option :domain, ::Booth::Coercers::Domain
10
+ option :scope, ::Booth::Coercers::Scope
8
11
 
9
12
  def call
10
13
  Tron.success(:all_onboardings, records:)
@@ -15,7 +18,7 @@ module Booth
15
18
  def records
16
19
  ::Booth::Models::Onboarding.includes_scope
17
20
  .sorted_scope
18
- .where(credential: { scope: })
21
+ .where(credential: { domain:, scope: })
19
22
  end
20
23
  end
21
24
  end
@@ -1,10 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
2
4
  module Adminland
3
5
  class PeriodicCleanup
4
- include ::Booth::MethodObject
6
+ include Calls
5
7
 
6
8
  def call
7
- # TODO
9
+ # TODO: Implement cleanup.
10
+ # - Remove revoked sessions older than a year.
11
+ # - Remove Credentials without Authenticator older than a year.
12
+ # - Remove old Authenticators that were added but never completed/tested.
8
13
  end
9
14
  end
10
15
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Booth
4
+ # Public API that you can call in your Rails app.
2
5
  module Adminland
3
6
  # ------------------
4
7
  # Credential Helpers
@@ -8,38 +11,34 @@ module Booth
8
11
  ::Booth::Adminland::Credentials::Create.call(...)
9
12
  end
10
13
 
11
-
12
- # ------------------
14
+ # --------------
13
15
  # Onboarding Helpers
14
- # ------------------
16
+ # --------------
15
17
 
16
- def self.create_onboarding(...)
17
- ::Booth::Adminland::Onboardings::Create.call(...)
18
+ def self.index_onboardings(...)
19
+ ::Booth::Adminland::Onboardings::Index.call(...)
18
20
  end
19
21
 
20
- def self.destroy_onboarding(...)
21
- ::Booth::Adminland::Onboardings::Destroy.call(...)
22
+ def self.create_onboarding(...)
23
+ ::Booth::Adminland::Onboardings::Create.call(...)
22
24
  end
23
25
 
24
26
  def self.find_onboarding(...)
25
27
  ::Booth::Adminland::Onboardings::Find.call(...)
26
28
  end
27
29
 
28
- def self.find_onboarding_for_mail_delivery(id:)
29
- ::Booth::Adminland::Onboardings::Find.call(id:, only_unused: true, raise_if_missing: true)
30
+ # For Mailers.
31
+ def self.find_unconsumed_onboarding(...)
32
+ ::Booth::Adminland::Onboardings::FindUnconsumed.call(...)
30
33
  end
31
34
 
32
- def self.index_onboardings(...)
33
- ::Booth::Adminland::Onboardings::Index.call(...)
35
+ def self.destroy_onboarding(...)
36
+ ::Booth::Adminland::Onboardings::Destroy.call(...)
34
37
  end
35
38
 
36
-
37
-
38
- # Other
39
-
40
- def self.consume_recovery(...)
41
- ::Booth::Adminland::Recoveries::Consume.call(...)
42
- end
39
+ # ----------------
40
+ # Internal Helpers
41
+ # ----------------
43
42
 
44
43
  def self.periodic_cleanup(...)
45
44
  ::Booth::Adminland::PeriodicCleanup.call(...)
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Booth
4
+ module Coercers
5
+ class Domain
6
+ def self.call(input)
7
+ ::Booth::Syntaxes::Domain.call(input).valid_domain
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Booth
4
+ module Coercers
5
+ class Request
6
+ include ::Booth::Logging
7
+
8
+ # If `DRY::Initializer` is used, then `Booth::Request` can be used as a
9
+ # [Coercer](https://dry-rb.org/gems/dry-initializer/3.0/type-constraints/#back-references).
10
+ #
11
+ # **Example:**
12
+ #
13
+ # ```ruby
14
+ # class Thing
15
+ # extend DRY::Initializer
16
+ #
17
+ # option :request, ::Booth::Coercers::Request # This uses Booth::Request.call as coercer
18
+ # end
19
+ #
20
+ # # This runs Booth::Request.call(rack_request, self).
21
+ # thing = Thing.new(request: rack_request)
22
+ # # (So in .call we have both, rack_request and the new Thing instance available).
23
+ # ```
24
+ #
25
+ # **Parameters:**
26
+ #
27
+ # - `request`: See initializer.
28
+ # - `initializer` - Some instance that called the coercer.
29
+ #
30
+ # **Returns:**
31
+ #
32
+ # - A new Booth::Request instance.
33
+ #
34
+ def self.call(request, initializer)
35
+ # `initializer` is some instance that is trying to coerce one of its params into a `Booth::Request`.
36
+ # By convention, that's where we assume the scope to be specified. So we take it from there.
37
+ #
38
+ if request.is_a?(::Booth::Request)
39
+ return request if request.scope == initializer.scope
40
+
41
+ # return ::Booth::Request.new(scope: initializer.scope, request: request.send(:request))
42
+
43
+ raise "Request has #{request.scope} but #{initializer} has #{initializer.scope}"
44
+ # request = request.send(:request)
45
+ end
46
+
47
+ ::Booth::Request.new(request:, scope: initializer.scope)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Booth
4
+ module Coercers
5
+ class Scope
6
+ def self.call(input)
7
+ ::Booth::Syntaxes::Scope.call(input).normalized_scope
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Booth
4
+ module Comparisons
5
+ # Compares two FQDN (fully quantified domain name).
6
+ class Domain
7
+ include ::Booth::Logging
8
+ include Calls
9
+
10
+ option :expected, as: :raw_expected # Might be secret, usually comes from DB
11
+ option :actual, as: :raw_actual # Can be revealed to end-user, usually comes from request
12
+
13
+ def call
14
+ return Tron.success(:identical_domains) if expected == actual
15
+
16
+ log { "The expected domain #{expected.inspect} does not match actual #{actual.inspect}" }
17
+ Tron.failure :mismatching_domain, expected: raw_expected,
18
+ actual: raw_actual,
19
+ public_message:
20
+ end
21
+
22
+ private
23
+
24
+ def expected
25
+ ::Booth::Syntaxes::Domain.call(raw_expected).valid_domain
26
+ end
27
+
28
+ def actual
29
+ ::Booth::Syntaxes::Domain.call(raw_actual).valid_domain
30
+ end
31
+
32
+ # TODO: I18n
33
+ def public_message
34
+ "The domain #{raw_actual} seems to be wrong."
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Booth
4
+ module Comparisons
5
+ # Compares two scope names.
6
+ class Scope
7
+ include ::Booth::Logging
8
+ include Calls
9
+
10
+ option :expected, as: :raw_expected # Might be secret, usually comes from DB
11
+ option :actual, as: :raw_actual # Can probably be revealed to end-user, comes from Controller
12
+
13
+ def call
14
+ return Tron.success(:identical_scopes) if expected == actual
15
+
16
+ log { "The expected scope #{expected.inspect} does not match actual #{actual.inspect}" }
17
+ Tron.failure :mismatching_scope, expected: raw_expected,
18
+ actual: raw_actual,
19
+ public_message:
20
+ end
21
+
22
+ private
23
+
24
+ def expected
25
+ ::Booth::Syntaxes::Scope.call(raw_expected).normalized_scope
26
+ end
27
+
28
+ def actual
29
+ ::Booth::Syntaxes::Scope.call(raw_actual).normalized_scope
30
+ end
31
+
32
+ # TODO: I18n
33
+ def public_message
34
+ "The scope #{raw_actual} seems to be wrong."
35
+ end
36
+ end
37
+ end
38
+ end