Establish certifiable Voting provider boundary
This commit is contained in:
+104
-1
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, replace
|
||||
from datetime import UTC, datetime
|
||||
from datetime import UTC, datetime, timedelta
|
||||
import hashlib
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
@@ -10,10 +10,13 @@ from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from govoplan_core.core.voting import (
|
||||
VOTING_CERTIFICATION_CERTIFIED,
|
||||
VOTING_CERTIFICATION_IN_EVALUATION,
|
||||
VotingBallotCreateCommand,
|
||||
VotingCastCommand,
|
||||
VotingElector,
|
||||
VotingOption,
|
||||
VotingProviderAssuranceDeclaration,
|
||||
voting_provider_capability,
|
||||
)
|
||||
from govoplan_core.core.encryption import (
|
||||
@@ -51,6 +54,17 @@ class FakeRegistry:
|
||||
return self.capabilities.get(name)
|
||||
|
||||
|
||||
class FakeExternalVotingProvider:
|
||||
def __init__(self, declaration: VotingProviderAssuranceDeclaration) -> None:
|
||||
self.declaration = declaration
|
||||
|
||||
def assurance_declaration(self) -> VotingProviderAssuranceDeclaration:
|
||||
return self.declaration
|
||||
|
||||
def finalize_ballot(self, session, principal, *, request):
|
||||
raise AssertionError("finalization should not run in assurance gate tests")
|
||||
|
||||
|
||||
class FakeKeyVault:
|
||||
def __init__(self) -> None:
|
||||
self.vaults: dict[tuple[str, str], object] = {}
|
||||
@@ -290,6 +304,95 @@ class VotingTests(unittest.TestCase):
|
||||
idempotency_key="open-secret",
|
||||
)
|
||||
|
||||
def test_external_certified_provider_claim_is_current_and_frozen(self) -> None:
|
||||
now = datetime.now(UTC)
|
||||
candidate = FakeExternalVotingProvider(
|
||||
VotingProviderAssuranceDeclaration(
|
||||
provider_id="certified",
|
||||
implementation_ref="vendor/adapter@1",
|
||||
supported_assurance_profiles=("external_certified",),
|
||||
certification_state=VOTING_CERTIFICATION_IN_EVALUATION,
|
||||
protocol_ref="vendor:ballot",
|
||||
protocol_version="3.0",
|
||||
)
|
||||
)
|
||||
registry = FakeRegistry()
|
||||
registry.capabilities[voting_provider_capability("certified")] = candidate
|
||||
service = SqlVotingBallots(registry)
|
||||
|
||||
with self.Session() as session:
|
||||
created = service.create_ballot(
|
||||
session,
|
||||
self.manager,
|
||||
command=command(
|
||||
assurance="external_certified",
|
||||
provider_id="certified",
|
||||
),
|
||||
idempotency_key="create-certified-candidate",
|
||||
)
|
||||
with self.assertRaisesRegex(VotingStoreError, "currently valid"):
|
||||
service.open_ballot(
|
||||
session,
|
||||
self.manager,
|
||||
ballot_id=created.id,
|
||||
expected_revision=created.revision,
|
||||
idempotency_key="open-certified-candidate",
|
||||
)
|
||||
|
||||
candidate.declaration = VotingProviderAssuranceDeclaration(
|
||||
provider_id="certified",
|
||||
implementation_ref="vendor/adapter@1",
|
||||
supported_assurance_profiles=("external_certified",),
|
||||
certification_state=VOTING_CERTIFICATION_CERTIFIED,
|
||||
protocol_ref="vendor:ballot",
|
||||
protocol_version="3.0",
|
||||
certification_authority="Independent authority",
|
||||
certification_reference="certificate-2026-1",
|
||||
certification_evidence_ref="evidence://certificate-2026-1",
|
||||
certification_valid_from=now - timedelta(days=1),
|
||||
certification_valid_until=now + timedelta(days=1),
|
||||
)
|
||||
with self.Session() as session:
|
||||
created = service.create_ballot(
|
||||
session,
|
||||
self.manager,
|
||||
command=command(
|
||||
assurance="external_certified",
|
||||
provider_id="certified",
|
||||
),
|
||||
idempotency_key="create-certified",
|
||||
)
|
||||
opened = service.open_ballot(
|
||||
session,
|
||||
self.manager,
|
||||
ballot_id=created.id,
|
||||
expected_revision=created.revision,
|
||||
idempotency_key="open-certified",
|
||||
)
|
||||
detail = service.get_ballot(
|
||||
session,
|
||||
self.manager,
|
||||
ballot_id=created.id,
|
||||
)
|
||||
self.assertEqual(
|
||||
"certificate-2026-1",
|
||||
detail["provider_assurance"]["certification_reference"],
|
||||
)
|
||||
|
||||
candidate.declaration = replace(
|
||||
candidate.declaration,
|
||||
certification_reference="certificate-2026-2",
|
||||
certification_evidence_ref="evidence://certificate-2026-2",
|
||||
)
|
||||
with self.assertRaisesRegex(VotingStoreError, "changed after"):
|
||||
service.close_ballot(
|
||||
session,
|
||||
self.manager,
|
||||
ballot_id=opened.id,
|
||||
expected_revision=opened.revision,
|
||||
idempotency_key="close-certified",
|
||||
)
|
||||
|
||||
def test_local_confidential_provider_encrypts_casts_and_returns_aggregates(
|
||||
self,
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user