Module: Clickwrap::Registration
- Defined in:
- lib/clickwrap/registration.rb
Overview
The authentication adapters: how an account and the evidence that authorized creating it commit together.
Both are thin conveniences over Clickwrap.register!, and both are
deliberately EXPLICIT — a line you write in your controller, not a hidden
after_create callback and not a monkey patch. That matters because this is
the exact place two real applications got it wrong in the same way: the
account was already persisted, the evidence write failed, and the exception
was rescued. The result was a live account with no record of what its owner
had agreed to, and nothing anywhere said so.
Signup is also modeled honestly. At first render there is no persisted
actor, so the presentation binds to a short-lived registration flow rather
than to a fictional authenticated user, and the receipt records
account_registration attribution instead of implying a session that did
not exist.
Defined Under Namespace
Modules: ClassMethods, DeviseAdapter
Constant Summary collapse
- REFUSALS =
Everything that counts as a REFUSAL of one registration attempt — a person on a stale render, an unticked control, a validation the account failed — as opposed to an infrastructure failure (EventWriteFailed and friends), which is never dressed up as validation and always escapes.
[ Clickwrap::SubmissionInvalid, Clickwrap::PresentationInvalid, Clickwrap::AnswerInvalid, Clickwrap::RegistrationFailed, ActiveRecord::RecordInvalid ].freeze
Class Method Summary collapse
-
.absorb_refusal(error, resource:, clickwrap_errors:) ⇒ Object
Translates one refusal into the same human sentences everywhere: inline beside the control it belongs to (through the controller's clickwrap_errors) and once on the resource's :base so the page's error rollup announces it.
- .included(base) ⇒ Object
-
.perform(policy_key, prospective_actor:, http_request: nil, submission: nil, tenant: nil, locale: nil, registration_flow_id: nil, &block) ⇒ Object
The primitive both adapters compose.
Class Method Details
.absorb_refusal(error, resource:, clickwrap_errors:) ⇒ Object
Translates one refusal into the same human sentences everywhere: inline
beside the control it belongs to (through the controller's
clickwrap_errors) and once on the resource's :base so the page's error
rollup announces it. The Devise adapter and the hand-rolled-door helper
(register_with_clickwrap without the bang) both come through here, so
every door in an application refuses in identical language by
construction — a door cannot forget a rescue it never writes.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/clickwrap/registration.rb', line 44 def self.absorb_refusal(error, resource:, clickwrap_errors:) case error when Clickwrap::AnswerInvalid if error.statement_key.present? clickwrap_errors[error.statement_key.to_s] = I18n.t("clickwrap.errors.required_statement") end resource.errors.add(:base, I18n.t("clickwrap.errors.required_statement")) if resource.errors.empty? when Clickwrap::SubmissionInvalid, Clickwrap::PresentationInvalid # A missing, stale, expired, or swapped presentation is a person on an # old render (or a cached form with no presentation at all) — not an # application error, and never a raw 500 in front of a person. resource.errors.add(:base, I18n.t("clickwrap.errors.presentation_no_longer_valid")) if resource.errors.empty? when Clickwrap::RegistrationFailed, ActiveRecord::RecordInvalid resource.errors.add(:base, error.) if resource.errors.empty? else raise error end error end |
.included(base) ⇒ Object
33 34 35 |
# File 'lib/clickwrap/registration.rb', line 33 def self.included(base) base.extend(ClassMethods) end |
.perform(policy_key, prospective_actor:, http_request: nil, submission: nil, tenant: nil, locale: nil, registration_flow_id: nil, &block) ⇒ Object
The primitive both adapters compose. A host with its own registration service can call this directly and get the same guarantees.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/clickwrap/registration.rb', line 96 def self.perform(policy_key, prospective_actor:, http_request: nil, submission: nil, tenant: nil, locale: nil, registration_flow_id: nil, &block) raise ArgumentError, "register_with_clickwrap needs a block that persists the account" unless block Clickwrap.register!( policy_key, prospective_actor: prospective_actor, http_request: http_request, submission: submission, tenant: tenant, locale: locale, registration_flow_id: registration_flow_id, &block ) end |