Skip to content

Commit 434365e

Browse files
authored
fix: wire BadgeKeeper.on_renew to SimpleGuard.set_badge_token (#40) (#42)
_setup_badge() creates a BadgeKeeper and SimpleGuard but did not wire the on_renew callback. When the keeper renewed the badge in the background, the guard's badge token was never updated — causing stale badge tokens for outbound request signing. Now passes on_renew=lambda token: guard.set_badge_token(token) to the BadgeKeeper constructor so the guard stays in sync automatically.
1 parent f20dee9 commit 434365e

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

capiscio_sdk/connect.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,12 +815,15 @@ def _setup_badge(self):
815815
)
816816

817817
# Set up BadgeKeeper with correct parameters
818+
# Wire on_renew so the guard's badge token stays in sync
819+
# when the keeper renews it in the background.
818820
keeper = BadgeKeeper(
819821
api_url=self.server_url,
820822
api_key=self.api_key,
821823
agent_id=self.agent_id,
822824
mode="dev" if self.dev_mode else "ca",
823825
output_file=str(self.keys_dir / "badge.jwt"),
826+
on_renew=lambda token: guard.set_badge_token(token),
824827
)
825828

826829
# Start the keeper and get initial badge

tests/unit/test_connect.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,42 @@ def test_setup_badge_success(self, tmp_path):
997997
mock_keeper.start.assert_called_once()
998998
mock_keeper.get_current_badge.assert_called_once()
999999

1000+
def test_setup_badge_wires_on_renew(self, tmp_path):
1001+
"""Test _setup_badge wires on_renew callback to guard.set_badge_token."""
1002+
connector = _Connector(
1003+
api_key="sk_test",
1004+
name="Test",
1005+
agent_id="agent-123",
1006+
server_url="https://test.server.com",
1007+
keys_dir=tmp_path,
1008+
auto_badge=True,
1009+
dev_mode=False,
1010+
)
1011+
connector.did = "did:key:z6Mktest"
1012+
1013+
mock_keeper = MagicMock()
1014+
mock_keeper.get_current_badge.return_value = "badge-jwt"
1015+
mock_keeper.badge_expires_at = "2026-12-31T00:00:00Z"
1016+
1017+
mock_guard = MagicMock()
1018+
1019+
captured_on_renew = None
1020+
1021+
def capture_keeper_init(**kwargs):
1022+
nonlocal captured_on_renew
1023+
captured_on_renew = kwargs.get("on_renew")
1024+
return mock_keeper
1025+
1026+
with patch("capiscio_sdk.badge_keeper.BadgeKeeper", side_effect=capture_keeper_init):
1027+
with patch("capiscio_sdk.simple_guard.SimpleGuard", return_value=mock_guard):
1028+
connector._setup_badge()
1029+
1030+
# on_renew should have been passed to BadgeKeeper
1031+
assert captured_on_renew is not None
1032+
# Calling on_renew should forward to guard.set_badge_token
1033+
captured_on_renew("new-token-xyz")
1034+
mock_guard.set_badge_token.assert_called_once_with("new-token-xyz")
1035+
10001036
def test_setup_badge_failure_continues(self, tmp_path):
10011037
"""Test _setup_badge returns None on failure without raising."""
10021038
connector = _Connector(

0 commit comments

Comments
 (0)