Class: Clickwrap::Import::FinePrint

Inherits:
Object
  • Object
show all
Defined in:
lib/clickwrap/import/fine_print.rb

Overview

bin/rails clickwrap:import:fine_print[:plan] — read FinePrint's tables and turn its signatures into explicit imported_legacy events.

=========================================================================== FinePrint is established Rails prior art for versioned contracts and signature gates, and this importer exists because applications outgrow a question, not because they chose badly. FinePrint answers "did user U sign version N of contract X?", and it answers it well. What it does not record — because it was never trying to — is the presentation, the exact wording beside the control, the call to action, the request context, or the domain action the signature authorized.

Those fields therefore come across as unknown / not_collected. This importer synthesizes none of them. A migration that filled in today's Terms digest for a 2019 signature would turn a modest, honest record into a confident false one, and the person reading the receipt in a dispute would have no way to tell.

Read against FinePrint's signature model at the audited commit: https://github.com/openstax/fine_print/blob/3b75fbcbcfb048ecd2f4ee7c4f0b9bd3d10f7603/app/models/fine_print/signature.rb#L1-L33

NOTE ON COUPLING: this class deliberately does NOT depend on the fine_print gem, require any of its files, or reference any of its constants. It reads two tables through the host's own connection, if they are there, and columns are discovered rather than assumed. A migration tool that forces you to keep the gem you are migrating away from installed is a migration tool with a hostage.

Defined Under Namespace

Classes: ContractMapping, Report

Constant Summary collapse

CONTRACTS_TABLE =
"fine_print_contracts"
SIGNATURES_TABLE =
"fine_print_signatures"
UNKNOWN_FIELDS =

What FinePrint's schema does not contain, recorded on every imported event so the gap is stated rather than inferred from silence.

%w[
  exact_document_bytes
  presentation_manifest
  assertion
  submit_button_text
  protected_action
  request_evidence
  ip_address
  browser_user_agent
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(policy_key:, find_actor_with:, map_contract_with: nil, contract_names: nil, because: nil, limit: nil, dry_run: false) ⇒ FinePrint

map_contract_with receives a contract row (a plain Hash of column name to value) and returns the Clickwrap document key that contract corresponds to. find_actor_with receives (user_type, user_id) and returns the actor record, or a stable actor reference string, or nil to skip that signature.



79
80
81
82
83
84
85
86
87
88
# File 'lib/clickwrap/import/fine_print.rb', line 79

def initialize(policy_key:, find_actor_with:, map_contract_with: nil, contract_names: nil,
               because: nil, limit: nil, dry_run: false)
  @policy_key = policy_key.to_s
  @find_actor_with = find_actor_with
  @map_contract_with = map_contract_with
  @contract_names = contract_names&.map(&:to_s)
  @because = because
  @limit = limit
  @dry_run = dry_run
end

Instance Attribute Details

#becauseObject (readonly)

Returns the value of attribute because.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def because
  @because
end

#contract_namesObject (readonly)

Returns the value of attribute contract_names.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def contract_names
  @contract_names
end

#dry_runObject (readonly)

Returns the value of attribute dry_run.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def dry_run
  @dry_run
end

#find_actor_withObject (readonly)

Returns the value of attribute find_actor_with.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def find_actor_with
  @find_actor_with
end

#limitObject (readonly)

Returns the value of attribute limit.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def limit
  @limit
end

#map_contract_withObject (readonly)

Returns the value of attribute map_contract_with.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def map_contract_with
  @map_contract_with
end

#policy_keyObject (readonly)

Returns the value of attribute policy_key.



90
91
92
# File 'lib/clickwrap/import/fine_print.rb', line 90

def policy_key
  @policy_key
end

Class Method Details

.import!Object



71
# File 'lib/clickwrap/import/fine_print.rb', line 71

def import!(**) = new(**).call

.planObject

Reads everything, writes nothing.



69
# File 'lib/clickwrap/import/fine_print.rb', line 69

def plan(**) = new(dry_run: true, **).call

Instance Method Details

#callObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/clickwrap/import/fine_print.rb', line 93

def call
  return tables_absent unless tables_present?

  contracts = load_contracts
  mappings = map_contracts(contracts)
  results = import_signatures(contracts)

  Report.new(
    status: dry_run ? :planned : :imported,
    policy_key: policy_key,
    tables_present: true,
    contracts: mappings,
    signatures: results.length,
    results: results,
    message: summary(mappings, results)
  )
end