Class: Reeve::Testing::Checks::CrossPrincipalLeak

Inherits:
Base
  • Object
show all
Defined in:
lib/reeve/testing/checks/cross_principal_leak.rb

Overview

FR-016, FR-003. The check the whole kit exists for: does this tool hand one principal another principal's records?

It answers by construction rather than by introspection. The contract's host-setup rule is two fixture principals with disjoint records, so invoking the tool once per principal and intersecting the identifiers that come back is decisive: a non-empty intersection is a leak, and no policy needs to be read to know it. A denial contributes an empty set — nothing returned is nothing leaked.

Reeve::Checks::CrossPrincipalLeak.new(
tool: InvoiceSearchTool, principals: [alice, bob], arguments: { query: "AC" }
).call

Two expectations, because two questions are worth asking:

:disjoint (default) — no identifier reaches two principals. The compliance
                    question, and the one FR-016 is written about.
:nothing            — none of these principals may receive any record at all.
                    What `deny_access_for(stranger)` asserts.

Constant Summary collapse

EXPECTATIONS =
%i[disjoint nothing].freeze

Instance Method Summary collapse

Methods inherited from Base

check_name, #check_name

Constructor Details

#initialize(tool:, principals:, arguments: {}, expect: :disjoint, invoke: nil, ledger: nil) ⇒ CrossPrincipalLeak

Returns a new instance of CrossPrincipalLeak.



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/reeve/testing/checks/cross_principal_leak.rb', line 28

def initialize(tool:, principals:, arguments: {}, expect: :disjoint, invoke: nil,
               ledger: nil)
  unless EXPECTATIONS.include?(expect)
    raise ArgumentError,
          "expect must be one of #{EXPECTATIONS.map(&:inspect).join(', ')}, " \
          "got #{expect.inspect}"
  end

  super(tool: tool, arguments: arguments, invoke: invoke, ledger: ledger)
  @principals = Array(principals)
  @expect = expect
end

Instance Method Details

#callObject



41
42
43
44
45
46
# File 'lib/reeve/testing/checks/cross_principal_leak.rb', line 41

def call
  return no_principals if principals.empty?

  attempts = principals.map { |principal| attempt(principal: principal) }
  @expect == :nothing ? verify_nothing(attempts) : verify_disjoint(attempts)
end