run method
- FakeRequest r, {
- required String action,
- required String resourceKind,
- required FakeChange apply(),
Runs apply as one rights change of r with the audit row action on resourceKind.
Order of 10 11 point 4: the agents of resolve_i1 switch to organization (one audit row
each), then apply writes, then I1 is checked. On a violation everything is restored, a
deny row with deny_reason: i1_violation is written (10 5.4) and the answer is
409 i1_violation with conflicts. Every row of a successful request shares one
correlation_id. A FakeProblem of apply restores the switches and passes through.
Returns the response of apply.
Implementation
FakeResponse run(
FakeRequest r, {
required String action,
required String resourceKind,
required FakeChange Function() apply,
}) {
final agents = resolveAgents(r.json);
final saved = _Snapshot(world, audit);
final correlation = audit.nextCorrelationId;
final reason = (r.json['resolve_i1'] as JsonMap?)?['reason'] as String?;
final FakeChange change;
try {
for (final a in agents) {
switchToOrganization(
a,
actor: r.person.id,
reason: reason!,
correlationId: correlation,
);
}
change = apply();
} on Object {
saved.restore();
rethrow;
}
final conflicts = world.i1Conflicts();
if (conflicts.isNotEmpty) {
// Built before the rollback: the holder of a conflict is the one the change set.
final list = conflictsJson(conflicts);
saved.restore();
audit.add(
world,
action: action,
decision: 'deny',
denyReason: 'i1_violation',
actor: r.person.id,
resourceKind: resourceKind,
details: {'conflicts': list},
);
throw FakeProblem(
409,
'i1_violation',
extra: {'hint': i1Hint, 'conflicts': list},
);
}
audit.add(
world,
action: action,
actor: r.person.id,
resourceKind: resourceKind,
resourceId: change.resourceId,
details: change.details,
correlationId: correlation,
);
return change.response;
}