clickwrap 0.0.0 → 0.1.0
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 +612 -0
- data/README.md +830 -1204
- data/SECURITY.md +33 -0
- data/app/assets/stylesheets/clickwrap.css +241 -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 +138 -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 +184 -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 +716 -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,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators/base"
|
|
4
|
+
require "rails/generators/active_record"
|
|
5
|
+
|
|
6
|
+
module Clickwrap
|
|
7
|
+
module Generators
|
|
8
|
+
# `rails generate clickwrap:upgrade` — the schema changes a newer release
|
|
9
|
+
# needs, as NEW migrations.
|
|
10
|
+
#
|
|
11
|
+
# This generator exists because of a promise: a released migration is never
|
|
12
|
+
# edited underneath an installed application. Editing one would change the
|
|
13
|
+
# schema that existing evidence was written under while leaving that evidence
|
|
14
|
+
# in place, and a receipt whose table no longer means what it meant is worth
|
|
15
|
+
# less than no receipt at all. So upgrades add migrations, and the files you
|
|
16
|
+
# already ran stay exactly as they were.
|
|
17
|
+
#
|
|
18
|
+
# At 0.1.0 there is nothing to upgrade from. This generator says so and
|
|
19
|
+
# creates nothing, rather than writing an empty migration to look busy.
|
|
20
|
+
class UpgradeGenerator < Rails::Generators::Base
|
|
21
|
+
include ActiveRecord::Generators::Migration
|
|
22
|
+
|
|
23
|
+
source_root File.expand_path("templates", __dir__)
|
|
24
|
+
desc "Create the migrations needed to move an installed app to this release"
|
|
25
|
+
|
|
26
|
+
def self.next_migration_number(dir)
|
|
27
|
+
ActiveRecord::Generators::Base.next_migration_number(dir)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def create_upgrade_migrations
|
|
31
|
+
say "\n☑️ clickwrap #{Clickwrap::VERSION} has no upgrade migrations.", :green
|
|
32
|
+
say "\n0.1.0 is the first release, so there is no earlier schema to move from and"
|
|
33
|
+
say "nothing was created."
|
|
34
|
+
say "\nIf you are installing clickwrap for the first time, you want:"
|
|
35
|
+
say " bin/rails generate clickwrap:install"
|
|
36
|
+
say "\nWhen a later release needs a schema change, this generator will add NEW"
|
|
37
|
+
say "migrations for it and report exactly what they do. Your existing migration"
|
|
38
|
+
say "files stay untouched, and evidence written under them goes on verifying —"
|
|
39
|
+
say "every released receipt format keeps a golden fixture, and a new format means"
|
|
40
|
+
say "a new explicit schema and verifier rather than a quiet reinterpretation.\n"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def migration_version
|
|
46
|
+
"[#{ActiveRecord::VERSION::STRING.to_f}]"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators/base"
|
|
4
|
+
|
|
5
|
+
module Clickwrap
|
|
6
|
+
module Generators
|
|
7
|
+
# `rails generate clickwrap:views` — eject the engine's overridable templates
|
|
8
|
+
# into the HOST app so they can be restyled. This is the Devise move
|
|
9
|
+
# (`rails g devise:views`), and it works for the same boring Rails reason:
|
|
10
|
+
# the host app's `app/views` sits AHEAD of any engine's view paths in the
|
|
11
|
+
# lookup chain, so a file copied to e.g.
|
|
12
|
+
# `app/views/clickwrap/captures/show.html.erb` SHADOWS the gem's bundled
|
|
13
|
+
# default automatically — no config, no registration. Delete your copy and
|
|
14
|
+
# the gem's default comes back. Upgrade the gem and your ejected copies are
|
|
15
|
+
# untouched (re-run only if you WANT the new defaults).
|
|
16
|
+
#
|
|
17
|
+
# `source_root` points at the engine's own `app/views`, so `directory` copies
|
|
18
|
+
# the exact templates the engine renders.
|
|
19
|
+
#
|
|
20
|
+
# One thing does not eject with the markup: the evidence contract. The
|
|
21
|
+
# controls are initially unselected, the document links come before the
|
|
22
|
+
# submit action, and the call to action recorded in the manifest is the one
|
|
23
|
+
# the person can actually press. Restyle freely, but a copy that preselects a
|
|
24
|
+
# control or moves the links below the button changes what the receipt is
|
|
25
|
+
# describing — and the development linter will say so.
|
|
26
|
+
#
|
|
27
|
+
# The same goes for the composed line. `presentation.combined` is one control
|
|
28
|
+
# answering several statements, and the manifest signs which ones; render it
|
|
29
|
+
# and then iterate `presentation.itemized_statements`, never `statements`, or
|
|
30
|
+
# the page offers a second control for a statement the one control already
|
|
31
|
+
# covers. The linter reports that too.
|
|
32
|
+
class ViewsGenerator < Rails::Generators::Base
|
|
33
|
+
source_root File.expand_path("../../../app/views", __dir__)
|
|
34
|
+
|
|
35
|
+
desc "Copy clickwrap's overridable views into your app so you can restyle them"
|
|
36
|
+
|
|
37
|
+
class_option :views, type: :array,
|
|
38
|
+
desc: "Which view groups to copy (defaults to all of them)"
|
|
39
|
+
|
|
40
|
+
def copy_views
|
|
41
|
+
return say_nothing_to_copy if available_groups.empty?
|
|
42
|
+
|
|
43
|
+
requested_groups.each do |group|
|
|
44
|
+
unless available_groups.include?(group)
|
|
45
|
+
say " No `#{group}` views ship with this release. Available: " \
|
|
46
|
+
"#{available_groups.join(", ")}.", :yellow
|
|
47
|
+
next
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
directory "clickwrap/#{group}", "app/views/clickwrap/#{group}"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def show_styling_tip
|
|
55
|
+
return if available_groups.empty?
|
|
56
|
+
|
|
57
|
+
say "\n🎨 Views copied — they are yours now, and the gem's originals stay put for"
|
|
58
|
+
say " reference. Tailwind, Bootstrap, ViewComponent, Phlex, and plain ERB all"
|
|
59
|
+
say " work; classes you add here are picked up by your build automatically,"
|
|
60
|
+
say " because the files now live in app/views."
|
|
61
|
+
say "\n Worth keeping while you restyle: explicit labels, visible keyboard focus,"
|
|
62
|
+
say " conventional high-contrast links, `aria-invalid`/`aria-describedby` error"
|
|
63
|
+
say " relationships, meaning that does not depend on color alone, and validation"
|
|
64
|
+
say " that still works with no JavaScript."
|
|
65
|
+
say "\n And keep the shape: render `presentation.combined` as ONE control, then"
|
|
66
|
+
say " iterate `presentation.itemized_statements` — never `statements`, or you offer"
|
|
67
|
+
say " a second box for a statement the first one already answers.\n"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def requested_groups
|
|
73
|
+
requested = Array(options[:views]).map(&:to_s).reject(&:empty?)
|
|
74
|
+
requested.any? ? requested : available_groups
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Read from the engine rather than hardcoded, so this generator keeps
|
|
78
|
+
# working as the engine's surfaces change and never offers a group that
|
|
79
|
+
# does not exist.
|
|
80
|
+
def available_groups
|
|
81
|
+
@available_groups ||= begin
|
|
82
|
+
root = File.join(self.class.source_root.to_s, "clickwrap")
|
|
83
|
+
|
|
84
|
+
if File.directory?(root)
|
|
85
|
+
Dir.children(root).select { |entry| File.directory?(File.join(root, entry)) }.sort
|
|
86
|
+
else
|
|
87
|
+
[]
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def say_nothing_to_copy
|
|
93
|
+
say "\n This release of clickwrap ships no ejectable views, so nothing was copied.", :yellow
|
|
94
|
+
say " `form.clickwrap` renders the controls and the submit action either way. For a"
|
|
95
|
+
say " fully custom surface, ask the presenter for primitives instead of recreating"
|
|
96
|
+
say " hidden inputs:"
|
|
97
|
+
say " presentation = Clickwrap.present(:signup, actor: current_user, ...)"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|