Class: Clickwrap::Integrity::Chain
- Inherits:
-
Object
- Object
- Clickwrap::Integrity::Chain
- Defined in:
- lib/clickwrap/integrity/chain.rb
Overview
Walks the optional event chains and reports what still links up.
result = Clickwrap::Integrity::Chain.verify
result.success? # => true
result.counts # => {"checked" => 41_882, "verified" => 41_882, "breaks" => 0}
result.first_break # => nil
============================================================================
WHAT A CHAIN DETECTS, EXACTLY. Each event carries the digest of the one
before it, so an event that is later rewritten or removed stops linking up
with its successors, and this walk finds the first place that happens. That
is a real and useful property: ordinary corruption, a well-meant
update_column, a restored partial backup, and a row edited by hand all
show up here.
What it does NOT do is stop, or detect, a privileged actor who rewrites an event AND every digest that follows it. Whoever can write the events table can usually write this table too, and a chain whose head lives in the same database as the chain cannot say otherwise. That is precisely the gap the optional independent anchor adapter addresses, and even then the claim is only ever as strong as the anchor. The chain makes rewriting history detectable for as long as the head remains trustworthy — no more than that, and this class never says more than that.
Defined Under Namespace
Constant Summary collapse
- BATCH_SIZE =
1_000- REASONS =
Every way a walk can stop lining up, as a stable symbol so a monitor can branch on it without matching English.
%i[ digest_does_not_match previous_digest_does_not_link sequence_gap earlier_events_missing chain_head_missing chain_tail_missing chain_head_event_mismatch chain_head_digest_mismatch ].freeze
Instance Attribute Summary collapse
-
#from ⇒ Object
readonly
Returns the value of attribute from.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
-
#to ⇒ Object
readonly
Returns the value of attribute to.
Class Method Summary collapse
-
.verify(scope: nil, from: nil, to: nil) ⇒ Object
from:andto:accept either a chain sequence number or a time.
Instance Method Summary collapse
-
#initialize(scope: nil, from: nil, to: nil) ⇒ Chain
constructor
A new instance of Chain.
- #verify ⇒ Object
Constructor Details
#initialize(scope: nil, from: nil, to: nil) ⇒ Chain
Returns a new instance of Chain.
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/clickwrap/integrity/chain.rb', line 102 def initialize(scope: nil, from: nil, to: nil) @scope = scope&.to_s @from = from @to = to @breaks = [] @checked = 0 @verified = 0 @documented_dispositions = 0 @started_mid_chain = [] end |
Instance Attribute Details
#from ⇒ Object (readonly)
Returns the value of attribute from.
113 114 115 |
# File 'lib/clickwrap/integrity/chain.rb', line 113 def from @from end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
113 114 115 |
# File 'lib/clickwrap/integrity/chain.rb', line 113 def scope @scope end |
#to ⇒ Object (readonly)
Returns the value of attribute to.
113 114 115 |
# File 'lib/clickwrap/integrity/chain.rb', line 113 def to @to end |
Class Method Details
.verify(scope: nil, from: nil, to: nil) ⇒ Object
from: and to: accept either a chain sequence number or a time. A
sequence is the natural way to re-check one span of a chain; a time is
the natural way to run "everything since last night" from cron, and
refusing one of them would just make an operator convert by hand.
100 |
# File 'lib/clickwrap/integrity/chain.rb', line 100 def self.verify(scope: nil, from: nil, to: nil) = new(scope: scope, from: from, to: to).verify |
Instance Method Details
#verify ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/clickwrap/integrity/chain.rb', line 115 def verify scopes = chain_scopes scopes.each { |chain_scope| walk(chain_scope) } Result.new( chaining_enabled: !Clickwrap.config.chain_event_history_with.nil?, checked: @checked, verified: @verified, documented_dispositions: @documented_dispositions, scopes: scopes, breaks: @breaks, started_mid_chain: @started_mid_chain ) end |