clickwrap 0.0.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +90 -0
- data/CHANGELOG.md +650 -0
- data/README.md +830 -1204
- data/SECURITY.md +33 -0
- data/app/assets/stylesheets/clickwrap.css +245 -0
- data/app/controllers/clickwrap/application_controller.rb +79 -0
- data/app/controllers/clickwrap/captures_controller.rb +145 -0
- data/app/controllers/clickwrap/document_versions_controller.rb +71 -0
- data/app/controllers/clickwrap/receipts_controller.rb +115 -0
- data/app/controllers/clickwrap/withdrawals_controller.rb +60 -0
- data/app/helpers/clickwrap/engine_helper.rb +97 -0
- data/app/views/clickwrap/captures/show.html.erb +34 -0
- data/app/views/clickwrap/receipts/index.html.erb +38 -0
- data/app/views/clickwrap/receipts/show.html.erb +91 -0
- data/app/views/clickwrap/shared/_error_summary.html.erb +39 -0
- data/app/views/clickwrap/shared/_fields.html.erb +100 -0
- data/app/views/clickwrap/shared/_statement.html.erb +105 -0
- data/app/views/clickwrap/withdrawals/new.html.erb +30 -0
- data/config/locales/en.yml +160 -0
- data/config/locales/es.yml +154 -0
- data/config/routes.rb +41 -0
- data/exe/clickwrap +374 -0
- data/guides/README.md +30 -0
- data/guides/accessibility.md +249 -0
- data/guides/consent-and-lifecycle.md +299 -0
- data/guides/integrating.md +610 -0
- data/guides/integrity.md +212 -0
- data/guides/migrating.md +335 -0
- data/guides/naming.md +320 -0
- data/guides/organizations.md +320 -0
- data/guides/receipts-and-verification.md +415 -0
- data/guides/request-evidence.md +512 -0
- data/guides/retention-and-legal-holds.md +438 -0
- data/lib/clickwrap/actor_proxy.rb +147 -0
- data/lib/clickwrap/anonymous_actor.rb +47 -0
- data/lib/clickwrap/authority.rb +174 -0
- data/lib/clickwrap/canonical_json.rb +216 -0
- data/lib/clickwrap/capture/event_builder.rb +220 -0
- data/lib/clickwrap/capture/presentation_verifier.rb +521 -0
- data/lib/clickwrap/capture.rb +650 -0
- data/lib/clickwrap/configuration.rb +1129 -0
- data/lib/clickwrap/controller_helpers.rb +758 -0
- data/lib/clickwrap/current_state.rb +282 -0
- data/lib/clickwrap/digest.rb +125 -0
- data/lib/clickwrap/doctor.rb +418 -0
- data/lib/clickwrap/document_definition.rb +255 -0
- data/lib/clickwrap/document_renderer.rb +83 -0
- data/lib/clickwrap/document_renderers/markdown.rb +175 -0
- data/lib/clickwrap/document_renderers/markdown_rails.rb +126 -0
- data/lib/clickwrap/dsl/policy_builder.rb +462 -0
- data/lib/clickwrap/dsl/retention_builder.rb +89 -0
- data/lib/clickwrap/durable_commit_callback.rb +37 -0
- data/lib/clickwrap/engine.rb +187 -0
- data/lib/clickwrap/errors.rb +181 -0
- data/lib/clickwrap/form_builder_extensions.rb +341 -0
- data/lib/clickwrap/front_matter.rb +67 -0
- data/lib/clickwrap/identifier.rb +112 -0
- data/lib/clickwrap/import/external_receipt.rb +241 -0
- data/lib/clickwrap/import/fine_print.rb +290 -0
- data/lib/clickwrap/import/legacy.rb +450 -0
- data/lib/clickwrap/integrations/organizations_authority.rb +81 -0
- data/lib/clickwrap/integrity/anchor.rb +130 -0
- data/lib/clickwrap/integrity/attestation_reconciler.rb +114 -0
- data/lib/clickwrap/integrity/attestor.rb +221 -0
- data/lib/clickwrap/integrity/chain.rb +313 -0
- data/lib/clickwrap/integrity/timestamp.rb +143 -0
- data/lib/clickwrap/ip_geolocation/location.rb +112 -0
- data/lib/clickwrap/ip_geolocation/null_resolver.rb +35 -0
- data/lib/clickwrap/ip_geolocation/resolver.rb +97 -0
- data/lib/clickwrap/ip_geolocation/static_resolver.rb +107 -0
- data/lib/clickwrap/ip_geolocation/trackdown_resolver.rb +330 -0
- data/lib/clickwrap/ip_geolocation.rb +16 -0
- data/lib/clickwrap/lifecycle.rb +534 -0
- data/lib/clickwrap/linter.rb +382 -0
- data/lib/clickwrap/localized_text.rb +101 -0
- data/lib/clickwrap/macros.rb +203 -0
- data/lib/clickwrap/models/application_record.rb +20 -0
- data/lib/clickwrap/models/chain_head.rb +79 -0
- data/lib/clickwrap/models/concerns/has_clickwraps.rb +55 -0
- data/lib/clickwrap/models/disposition_plan.rb +208 -0
- data/lib/clickwrap/models/document.rb +46 -0
- data/lib/clickwrap/models/document_version.rb +163 -0
- data/lib/clickwrap/models/event.rb +743 -0
- data/lib/clickwrap/models/event_document.rb +79 -0
- data/lib/clickwrap/models/event_statement.rb +92 -0
- data/lib/clickwrap/models/external_action.rb +150 -0
- data/lib/clickwrap/models/integrity_attestation.rb +90 -0
- data/lib/clickwrap/models/legal_hold.rb +81 -0
- data/lib/clickwrap/models/policy_revision.rb +115 -0
- data/lib/clickwrap/models/presentation.rb +59 -0
- data/lib/clickwrap/models/receipt_access.rb +53 -0
- data/lib/clickwrap/models/recording_sequence.rb +21 -0
- data/lib/clickwrap/models/request_evidence.rb +378 -0
- data/lib/clickwrap/models/statement_identity_lock.rb +38 -0
- data/lib/clickwrap/models/statement_state.rb +130 -0
- data/lib/clickwrap/pending_receipt.rb +177 -0
- data/lib/clickwrap/policy.rb +283 -0
- data/lib/clickwrap/presentation_manifest.rb +210 -0
- data/lib/clickwrap/presenter.rb +729 -0
- data/lib/clickwrap/privacy.rb +419 -0
- data/lib/clickwrap/protected_outcome.rb +120 -0
- data/lib/clickwrap/receipt.rb +606 -0
- data/lib/clickwrap/receipt_html.rb +235 -0
- data/lib/clickwrap/receipt_verifier.rb +978 -0
- data/lib/clickwrap/reference.rb +44 -0
- data/lib/clickwrap/registration.rb +236 -0
- data/lib/clickwrap/registry.rb +54 -0
- data/lib/clickwrap/remediation_token.rb +155 -0
- data/lib/clickwrap/request_evidence_extractor.rb +590 -0
- data/lib/clickwrap/request_evidence_policy.rb +261 -0
- data/lib/clickwrap/retention/applier.rb +231 -0
- data/lib/clickwrap/retention/disposition.rb +221 -0
- data/lib/clickwrap/retention/planner.rb +502 -0
- data/lib/clickwrap/retention_class.rb +97 -0
- data/lib/clickwrap/reviewed_text.rb +28 -0
- data/lib/clickwrap/schema_requirements.rb +196 -0
- data/lib/clickwrap/services/authorize_external_action.rb +149 -0
- data/lib/clickwrap/services/load_policies.rb +69 -0
- data/lib/clickwrap/services/publish_documents.rb +251 -0
- data/lib/clickwrap/services/validate_policy_references.rb +166 -0
- data/lib/clickwrap/statement.rb +248 -0
- data/lib/clickwrap/subject_fingerprint.rb +28 -0
- data/lib/clickwrap/submission.rb +169 -0
- data/lib/clickwrap/system_actor.rb +31 -0
- data/lib/clickwrap/test_helpers.rb +676 -0
- data/lib/clickwrap/testing.rb +211 -0
- data/lib/clickwrap/trusted_proxy_configuration.rb +92 -0
- data/lib/clickwrap/verification.rb +504 -0
- data/lib/clickwrap/version.rb +12 -1
- data/lib/clickwrap/view_helpers.rb +190 -0
- data/lib/clickwrap/vocabulary.rb +294 -0
- data/lib/clickwrap.rb +497 -7
- data/lib/generators/clickwrap/document_generator.rb +164 -0
- data/lib/generators/clickwrap/hardening_generator.rb +177 -0
- data/lib/generators/clickwrap/install_generator.rb +1287 -0
- data/lib/generators/clickwrap/link_generator.rb +56 -0
- data/lib/generators/clickwrap/policy_generator.rb +118 -0
- data/lib/generators/clickwrap/templates/clickwrap_hardening.rb.erb +256 -0
- data/lib/generators/clickwrap/templates/clickwrap_policies.rb.erb +192 -0
- data/lib/generators/clickwrap/templates/create_clickwrap_external_action_tables.rb.erb +128 -0
- data/lib/generators/clickwrap/templates/create_clickwrap_integrity_tables.rb.erb +157 -0
- data/lib/generators/clickwrap/templates/create_clickwrap_presentation_tables.rb.erb +160 -0
- data/lib/generators/clickwrap/templates/create_clickwrap_request_evidence_tables.rb.erb +180 -0
- data/lib/generators/clickwrap/templates/create_clickwrap_retention_tables.rb.erb +174 -0
- data/lib/generators/clickwrap/templates/create_clickwrap_tables.rb.erb +568 -0
- data/lib/generators/clickwrap/templates/initializer.rb.erb +439 -0
- data/lib/generators/clickwrap/templates/link_clickwrap_event_migration.rb.erb +12 -0
- data/lib/generators/clickwrap/templates/policy.rb.erb +31 -0
- data/lib/generators/clickwrap/templates/policy_test.rb.erb +56 -0
- data/lib/generators/clickwrap/templates/privacy.md.erb +58 -0
- data/lib/generators/clickwrap/templates/terms.md.erb +49 -0
- data/lib/generators/clickwrap/upgrade_generator.rb +50 -0
- data/lib/generators/clickwrap/views_generator.rb +101 -0
- data/lib/tasks/clickwrap.rake +569 -0
- metadata +311 -16
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/engine"
|
|
4
|
+
|
|
5
|
+
module Clickwrap
|
|
6
|
+
# The mountable engine: wires autoloading, migrations, locales, the
|
|
7
|
+
# ActiveRecord macro, the form-builder extension, the controller helpers, and
|
|
8
|
+
# boot-time policy loading into the host app.
|
|
9
|
+
class Engine < ::Rails::Engine
|
|
10
|
+
isolate_namespace Clickwrap
|
|
11
|
+
|
|
12
|
+
# -------------------------------------------------------------------------
|
|
13
|
+
# Zeitwerk: the gem keeps its ActiveRecord models under lib/clickwrap/models
|
|
14
|
+
# (same layout as the moderate and chats gems) so the whole domain ships in
|
|
15
|
+
# lib/ and the engine's app/ tree only holds the web layer. For that to
|
|
16
|
+
# autoload correctly we manage the loader by hand:
|
|
17
|
+
#
|
|
18
|
+
# - `push_dir(lib/clickwrap, namespace: Clickwrap)` makes
|
|
19
|
+
# lib/clickwrap/models/... autoloadable *under the Clickwrap namespace*.
|
|
20
|
+
# - `collapse(models)` + `collapse(models/concerns)` mean the files in
|
|
21
|
+
# those folders define Clickwrap::Event / Clickwrap::HasClickwraps —
|
|
22
|
+
# not Clickwrap::Models::Event.
|
|
23
|
+
# - The SPINE files are required explicitly by lib/clickwrap.rb at boot,
|
|
24
|
+
# so they must be *ignored* by the loader or Zeitwerk would complain
|
|
25
|
+
# about double definitions.
|
|
26
|
+
# -------------------------------------------------------------------------
|
|
27
|
+
LIB_ROOT = File.expand_path("..", __dir__)
|
|
28
|
+
CLICKWRAP_LIB = File.expand_path("clickwrap", LIB_ROOT)
|
|
29
|
+
|
|
30
|
+
ZEITWERK_IGNORED = %w[
|
|
31
|
+
version.rb
|
|
32
|
+
errors.rb
|
|
33
|
+
vocabulary.rb
|
|
34
|
+
canonical_json.rb
|
|
35
|
+
digest.rb
|
|
36
|
+
identifier.rb
|
|
37
|
+
ip_geolocation.rb
|
|
38
|
+
ip_geolocation/location.rb
|
|
39
|
+
ip_geolocation/resolver.rb
|
|
40
|
+
ip_geolocation/null_resolver.rb
|
|
41
|
+
ip_geolocation/static_resolver.rb
|
|
42
|
+
ip_geolocation/trackdown_resolver.rb
|
|
43
|
+
configuration.rb
|
|
44
|
+
engine.rb
|
|
45
|
+
macros.rb
|
|
46
|
+
authority.rb
|
|
47
|
+
registry.rb
|
|
48
|
+
localized_text.rb
|
|
49
|
+
document_definition.rb
|
|
50
|
+
statement.rb
|
|
51
|
+
request_evidence_policy.rb
|
|
52
|
+
policy.rb
|
|
53
|
+
retention_class.rb
|
|
54
|
+
dsl/policy_builder.rb
|
|
55
|
+
dsl/retention_builder.rb
|
|
56
|
+
document_renderers/markdown.rb
|
|
57
|
+
form_builder_extensions.rb
|
|
58
|
+
view_helpers.rb
|
|
59
|
+
controller_helpers.rb
|
|
60
|
+
registration.rb
|
|
61
|
+
].freeze
|
|
62
|
+
|
|
63
|
+
initializer "clickwrap.autoload", before: :set_autoload_paths do
|
|
64
|
+
loader = Rails.autoloaders.main
|
|
65
|
+
|
|
66
|
+
ZEITWERK_IGNORED.each do |file|
|
|
67
|
+
path = File.join(CLICKWRAP_LIB, file)
|
|
68
|
+
loader.ignore(path) if File.exist?(path)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
%w[models models/concerns].each do |dir|
|
|
72
|
+
path = File.join(CLICKWRAP_LIB, dir)
|
|
73
|
+
loader.collapse(path) if File.directory?(path)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
loader.push_dir(CLICKWRAP_LIB, namespace: Clickwrap)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
config.eager_load_paths << CLICKWRAP_LIB
|
|
80
|
+
|
|
81
|
+
# Make the gem's migrations runnable from the host without copying
|
|
82
|
+
# (`rails db:migrate` picks them up). The install generator still copies a
|
|
83
|
+
# host-owned migration, which is the recommended path: a released migration
|
|
84
|
+
# is never edited underneath an installed application, so the host owns the
|
|
85
|
+
# file that describes its own schema.
|
|
86
|
+
initializer "clickwrap.migrations" do |app|
|
|
87
|
+
unless app.root.to_s == root.to_s
|
|
88
|
+
config.paths["db/migrate"].expanded.each do |path|
|
|
89
|
+
app.config.paths["db/migrate"] << path
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Expose `has_clickwraps` on every AR model.
|
|
95
|
+
initializer "clickwrap.active_record" do
|
|
96
|
+
ActiveSupport.on_load(:active_record) do
|
|
97
|
+
extend Clickwrap::Macros
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Expose `form.clickwrap` and `form.clickwrap_fields` on the standard form
|
|
102
|
+
# builder, so the one-line happy path works in an ordinary `form_with`.
|
|
103
|
+
initializer "clickwrap.form_builder" do
|
|
104
|
+
ActiveSupport.on_load(:action_view) do
|
|
105
|
+
ActionView::Helpers::FormBuilder.prepend(Clickwrap::FormBuilderExtensions) unless
|
|
106
|
+
ActionView::Helpers::FormBuilder < Clickwrap::FormBuilderExtensions
|
|
107
|
+
# The custom-surface helpers (token field, statement controls, the
|
|
108
|
+
# manifest-worded submit) — available in every view, like the form
|
|
109
|
+
# builder methods above.
|
|
110
|
+
include Clickwrap::ViewHelpers
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Give host controllers `clickwrap_submission`, `capture_clickwrap_and!`,
|
|
115
|
+
# and the `requires_clickwrap` gate.
|
|
116
|
+
initializer "clickwrap.action_controller" do
|
|
117
|
+
ActiveSupport.on_load(:action_controller) do
|
|
118
|
+
include Clickwrap::ControllerHelpers
|
|
119
|
+
|
|
120
|
+
# `clickwraps_registration_with :signup` for Devise controllers. The
|
|
121
|
+
# macro is available everywhere; nothing happens unless a controller
|
|
122
|
+
# actually calls it, and Devise is never required.
|
|
123
|
+
include Clickwrap::Registration
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# The gem's locale files ship through Rails::Engine's own :add_locales
|
|
128
|
+
# (every engine's `config/locales` is picked up automatically) — and NOT
|
|
129
|
+
# through a manual `app.config.i18n.load_path +=` on top of it. The manual
|
|
130
|
+
# append is not merely redundant: railties paths are UNSHIFTED before
|
|
131
|
+
# everything in `load_path`, so an appended copy of these files lands
|
|
132
|
+
# AFTER the host's own locales and quietly overrides them. Load order is
|
|
133
|
+
# the whole contract here — gem first, host last — because a host rewords
|
|
134
|
+
# a statement by shipping the same key in its own locale file, and the
|
|
135
|
+
# host's counsel must always get the last word.
|
|
136
|
+
|
|
137
|
+
initializer "clickwrap.assets" do |app|
|
|
138
|
+
app.config.assets.paths << root.join("app/assets/stylesheets") if app.config.respond_to?(:assets)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Load the host's document, policy, and retention declarations. They live in
|
|
142
|
+
# ordinary Ruby files so they are reviewable in a diff and deployable like
|
|
143
|
+
# code; `to_prepare` re-reads them on every boot and every development
|
|
144
|
+
# reload, and compilation raises on a mistake rather than deferring it to
|
|
145
|
+
# the first person who tries to sign up.
|
|
146
|
+
# Every `requires_clickwrap` gate, checked once the host's routes exist.
|
|
147
|
+
#
|
|
148
|
+
# `after_routes_loaded` rather than `after_initialize`, and the difference
|
|
149
|
+
# matters: `after_initialize` runs while the application is still
|
|
150
|
+
# initializing, which is precisely when the routes reloader declines to
|
|
151
|
+
# load. Checking there would report "the engine is not mounted" to
|
|
152
|
+
# applications that mount it perfectly well, which is worse than not
|
|
153
|
+
# checking at all. This hook fires at the one moment the answer is knowable.
|
|
154
|
+
#
|
|
155
|
+
# A dead-end gate is still better found at boot than by the first person it
|
|
156
|
+
# stops, so the request path keeps its own backstop for controllers that are
|
|
157
|
+
# autoloaded later in development.
|
|
158
|
+
if config.respond_to?(:after_routes_loaded)
|
|
159
|
+
config.after_routes_loaded do
|
|
160
|
+
Clickwrap::ControllerHelpers.verify_registered_gates!
|
|
161
|
+
Clickwrap::Services::ValidatePolicyReferences.validate_remediation_paths!
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
config.to_prepare do
|
|
166
|
+
Clickwrap::Services::LoadPolicies.new.call
|
|
167
|
+
|
|
168
|
+
# Whether the raw request-evidence values are encrypted is a host decision
|
|
169
|
+
# read from the initializer, so it can only be applied once that has been
|
|
170
|
+
# read — and it has to be re-applied on every development reload, because
|
|
171
|
+
# the model class is a fresh object each time.
|
|
172
|
+
Clickwrap::RequestEvidence.apply_configured_encryption!
|
|
173
|
+
|
|
174
|
+
# `clickwrap:install` emits only the tables a default installation can
|
|
175
|
+
# actually put a row in; the rest come with their own flag. The one
|
|
176
|
+
# failure mode that creates is turning a capability on and forgetting its
|
|
177
|
+
# migration, and that must not be discovered by a capture failing in
|
|
178
|
+
# production. It is discovered here, with the exact command that fixes
|
|
179
|
+
# it. Answering needs a database, and "there is no database yet"
|
|
180
|
+
# (db:create, an asset build) is not a misconfiguration — the check
|
|
181
|
+
# simply does not fire.
|
|
182
|
+
Clickwrap::SchemaRequirements.reset!
|
|
183
|
+
missing = Clickwrap::SchemaRequirements.missing_for_configuration
|
|
184
|
+
raise Clickwrap::ConfigurationError, missing.map(&:explanation).join("\n\n") if missing.any?
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clickwrap
|
|
4
|
+
# Base class for every error Clickwrap raises. Hosts can rescue this one
|
|
5
|
+
# class and still distinguish causes through the subclasses below.
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
|
|
8
|
+
# --- Configuration and boot -------------------------------------------------
|
|
9
|
+
|
|
10
|
+
# Raised when the initializer contains a value Clickwrap cannot safely use.
|
|
11
|
+
class ConfigurationError < Error; end
|
|
12
|
+
|
|
13
|
+
# Raised while compiling a policy, document, or retention class definition.
|
|
14
|
+
class DefinitionError < Error; end
|
|
15
|
+
|
|
16
|
+
# Raised when a policy, document, statement, or retention class is referenced
|
|
17
|
+
# but was never defined.
|
|
18
|
+
class NotDefinedError < Error; end
|
|
19
|
+
|
|
20
|
+
class UnknownPolicyError < NotDefinedError; end
|
|
21
|
+
class UnknownStatementError < NotDefinedError; end
|
|
22
|
+
class UnknownRetentionClassError < NotDefinedError; end
|
|
23
|
+
|
|
24
|
+
# --- Documents --------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
# Raised when a document version is required but has not been published, or
|
|
27
|
+
# when stored bytes no longer match their recorded digest.
|
|
28
|
+
class DocumentNotPublishedError < Error; end
|
|
29
|
+
class DocumentDigestMismatchError < Error; end
|
|
30
|
+
|
|
31
|
+
# Raised when a version label is reused for different bytes.
|
|
32
|
+
class DocumentVersionConflictError < Error; end
|
|
33
|
+
|
|
34
|
+
# --- Presentation and submission -------------------------------------------
|
|
35
|
+
|
|
36
|
+
# The family of refusals a PERSON can cause from a form: a stale or missing
|
|
37
|
+
# presentation, a submission that doesn't parse, a required box left empty.
|
|
38
|
+
# These are not application errors — they deserve a re-rendered form with a
|
|
39
|
+
# localized sentence, never a 500. One rescue covers the whole family:
|
|
40
|
+
#
|
|
41
|
+
# rescue Clickwrap::CaptureRefused => refusal
|
|
42
|
+
# redirect_to somewhere_path, alert: refusal.user_facing_message
|
|
43
|
+
#
|
|
44
|
+
# Everything OUTSIDE this family (an evidence write failure above all) stays
|
|
45
|
+
# loud on purpose: infrastructure problems are yours to see, not the
|
|
46
|
+
# person's to absorb.
|
|
47
|
+
class CaptureRefused < Error
|
|
48
|
+
# The localized sentence the gem's own screens show for this refusal —
|
|
49
|
+
# safe to put in front of a person, never a developer-facing message.
|
|
50
|
+
def user_facing_message
|
|
51
|
+
I18n.t("clickwrap.errors.presentation_no_longer_valid")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Raised when the submitted presentation token is missing, malformed, signed
|
|
56
|
+
# with a different key, expired, or bound to a different actor, tenant,
|
|
57
|
+
# subject, policy, or revision than the one being captured.
|
|
58
|
+
class PresentationInvalid < CaptureRefused
|
|
59
|
+
attr_reader :result
|
|
60
|
+
|
|
61
|
+
def initialize(message = nil, result: nil)
|
|
62
|
+
@result = result
|
|
63
|
+
super(message || result&.message || "The presentation could not be verified")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class PresentationExpired < PresentationInvalid; end
|
|
68
|
+
|
|
69
|
+
# Raised when a submission cannot be parsed or contains keys the manifest
|
|
70
|
+
# never declared.
|
|
71
|
+
class SubmissionInvalid < CaptureRefused; end
|
|
72
|
+
|
|
73
|
+
# --- Capture ----------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
# Raised when a required answer is missing or an answer is not one of the
|
|
76
|
+
# choices the server offered.
|
|
77
|
+
class AnswerInvalid < CaptureRefused
|
|
78
|
+
attr_reader :statement_key, :reason
|
|
79
|
+
|
|
80
|
+
def initialize(message = nil, statement_key: nil, reason: nil)
|
|
81
|
+
@statement_key = statement_key
|
|
82
|
+
@reason = reason
|
|
83
|
+
super(message || "The submitted answer for #{statement_key.inspect} was not accepted")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def user_facing_message
|
|
87
|
+
I18n.t("clickwrap.errors.required_statement")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Raised when the evidence event itself could not be written. The protected
|
|
92
|
+
# database action in the same transaction rolls back with it.
|
|
93
|
+
class EventWriteFailed < Error; end
|
|
94
|
+
|
|
95
|
+
# Raised when an identical idempotency key arrives with a different payload.
|
|
96
|
+
class ReplayRejected < Error; end
|
|
97
|
+
|
|
98
|
+
# Raised when a registration block returns without persisting the exact
|
|
99
|
+
# prospective actor the presentation was issued for.
|
|
100
|
+
class RegistrationFailed < Error; end
|
|
101
|
+
|
|
102
|
+
# Raised when a represented-party creation block does not return a persisted
|
|
103
|
+
# record of the type whose browser flow was bound at presentation.
|
|
104
|
+
class RepresentedPartyCreationFailed < Error; end
|
|
105
|
+
|
|
106
|
+
# Raised when delegated action was not explicitly permitted by the policy and
|
|
107
|
+
# positively verified by the host's authority callback.
|
|
108
|
+
class AuthorityNotVerified < Error; end
|
|
109
|
+
|
|
110
|
+
# Raised when a signed in-place remediation context is missing, expired,
|
|
111
|
+
# belongs to a different actor/tenant/policy, or names a resource that can no
|
|
112
|
+
# longer be resolved and authorized.
|
|
113
|
+
class RemediationInvalid < Error; end
|
|
114
|
+
class RemediationNotAuthorized < RemediationInvalid; end
|
|
115
|
+
|
|
116
|
+
# Raised when a deadlock or serialization failure occurred and Clickwrap
|
|
117
|
+
# cannot prove the caller's block is safe to retry. The host decides.
|
|
118
|
+
class RetryableTransactionError < Error; end
|
|
119
|
+
|
|
120
|
+
# --- Verification and gating ------------------------------------------------
|
|
121
|
+
|
|
122
|
+
# Raised by the bang verification methods. Always carries the same structured
|
|
123
|
+
# result the non-bang `Clickwrap.verify` would have returned, so applications
|
|
124
|
+
# never parse an English message to make an authorization decision.
|
|
125
|
+
class VerificationFailed < Error
|
|
126
|
+
attr_reader :result
|
|
127
|
+
|
|
128
|
+
def initialize(result)
|
|
129
|
+
@result = result
|
|
130
|
+
super(result.message)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def error = result.error
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# --- Lifecycle --------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
class LifecycleError < Error; end
|
|
139
|
+
class AlreadyWithdrawnError < LifecycleError; end
|
|
140
|
+
class AlreadyConsumedError < LifecycleError; end
|
|
141
|
+
class OneTimeAuthorizationConflict < LifecycleError; end
|
|
142
|
+
class NotWithdrawableError < LifecycleError; end
|
|
143
|
+
|
|
144
|
+
# --- Request evidence, retention, and disposition ---------------------------
|
|
145
|
+
|
|
146
|
+
# Raised when a policy requires IP address, browser user-agent, or IP
|
|
147
|
+
# geolocation evidence and it could not be resolved.
|
|
148
|
+
class RequestEvidenceUnavailable < Error; end
|
|
149
|
+
|
|
150
|
+
# Raised when disposition is attempted on evidence under a legal hold.
|
|
151
|
+
class LegalHoldInEffect < Error; end
|
|
152
|
+
|
|
153
|
+
# Raised when ordinary Active Record mutation is attempted against evidence
|
|
154
|
+
# whose only permitted changes are named, audited lifecycle transitions.
|
|
155
|
+
class ImmutableEvidenceError < Error; end
|
|
156
|
+
|
|
157
|
+
# Raised when a disposition plan is stale, already applied, expired, or no
|
|
158
|
+
# longer matches what the operator reviewed.
|
|
159
|
+
class DispositionPlanInvalid < Error; end
|
|
160
|
+
|
|
161
|
+
# Raised when unredacted request evidence is requested without host
|
|
162
|
+
# authorization or without a human-readable reason.
|
|
163
|
+
class AccessNotAuthorized < Error; end
|
|
164
|
+
|
|
165
|
+
# --- Integrity and receipts -------------------------------------------------
|
|
166
|
+
|
|
167
|
+
# Raised when a receipt cannot be parsed, its schema version is unknown, or
|
|
168
|
+
# its canonical bytes do not match the digest it carries.
|
|
169
|
+
class ReceiptInvalid < Error; end
|
|
170
|
+
class UnknownReceiptSchema < ReceiptInvalid; end
|
|
171
|
+
class IntegrityCheckFailed < Error; end
|
|
172
|
+
|
|
173
|
+
# Raised when a pending receipt is used after its transaction rolled back, or
|
|
174
|
+
# when export/verification is called before commit.
|
|
175
|
+
class ReceiptNotCommitted < Error; end
|
|
176
|
+
|
|
177
|
+
# --- External actions -------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
class ExternalActionError < Error; end
|
|
180
|
+
class ExternalActionAlreadyResolved < ExternalActionError; end
|
|
181
|
+
end
|