Rename Installation to Instance
Follows the portal: the noun is "instance" everywhere the app says it — UI strings, CLI output, error details, docs and comments. The wire keys (`instance_id`, `instance_token`) and the hub route this calls move with it. An existing cloud.json is adopted rather than refused: without the key alias the dataclass fails to parse, which the caller swallows and reads as "never enrolled" instead of "reconnect". `instance_key` on a node type becomes `target_key`. It means the outside thing a node points at, which is a different sense of the word, and keeping both would put two meanings of "instance" in one codebase. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015YrQnKV3bnQd4K342y8tKj
This commit is contained in:
+11
-11
@@ -1,7 +1,7 @@
|
||||
"""Remote access: off by default, and only ever as much as somebody granted.
|
||||
|
||||
The property worth pinning down is the one everything else rests on — a
|
||||
portal's token is worth nothing here until somebody at this installation
|
||||
portal's token is worth nothing here until somebody at this instance
|
||||
enrolled it, and even then it grants exactly the rights of the local account
|
||||
the portal identity holding it was mapped to. An identity nobody mapped gets
|
||||
nothing, which is what makes deleting that local account a revocation.
|
||||
@@ -31,7 +31,7 @@ from tests.utils.portal import ISSUER, portal_token
|
||||
def test_portal_token_is_refused_when_not_enrolled(
|
||||
portal_key: rsa.RSAPrivateKey, tmp_path_factory: pytest.TempPathFactory
|
||||
) -> None:
|
||||
"""An installation nobody connected trusts no portal at all."""
|
||||
"""An instance nobody connected trusts no portal at all."""
|
||||
original = settings.CLOUD_CONFIG_FILE
|
||||
settings.CLOUD_CONFIG_FILE = tmp_path_factory.mktemp("empty") / "cloud.json"
|
||||
try:
|
||||
@@ -55,11 +55,11 @@ def test_portal_token_resolves_by_portal_identity(
|
||||
assert user_from_token(db, portal_token(portal_key, subject="nobody")) is None
|
||||
|
||||
|
||||
def test_token_for_another_installation_is_refused(
|
||||
def test_token_for_another_instance_is_refused(
|
||||
enrolled: User, # noqa: ARG001 (fixture installs the enrolment)
|
||||
portal_key: rsa.RSAPrivateKey,
|
||||
) -> None:
|
||||
"""The audience is this installation's id, so someone else's is worthless."""
|
||||
"""The audience is this instance's id, so someone else's is worthless."""
|
||||
with pytest.raises(jwt.exceptions.InvalidTokenError):
|
||||
decode_token(portal_token(portal_key, audience=str(uuid.uuid4())))
|
||||
|
||||
@@ -67,7 +67,7 @@ def test_token_for_another_installation_is_refused(
|
||||
def test_token_from_an_unpinned_key_is_refused(
|
||||
enrolled: User, # noqa: ARG001 (fixture installs the enrolment)
|
||||
) -> None:
|
||||
"""A different portal, or a hijacked one, cannot sign for this installation."""
|
||||
"""A different portal, or a hijacked one, cannot sign for this instance."""
|
||||
impostor = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
with pytest.raises(jwt.exceptions.InvalidTokenError):
|
||||
decode_token(portal_token(impostor))
|
||||
@@ -104,7 +104,7 @@ def test_status_reports_not_enrolled(
|
||||
def test_enrolling_needs_a_superuser(
|
||||
client: TestClient, normal_user_token_headers: dict[str, str]
|
||||
) -> None:
|
||||
"""Remote access is an installation-wide grant, not a personal setting."""
|
||||
"""Remote access is an instance-wide grant, not a personal setting."""
|
||||
response = client.post(
|
||||
f"{settings.API_V1_STR}/cloud/enroll",
|
||||
headers=normal_user_token_headers,
|
||||
@@ -122,7 +122,7 @@ def test_a_panel_scoped_portal_token_reaches_only_its_panel(
|
||||
"""A screen paired through the portal is bounded here, not there.
|
||||
|
||||
The portal names the panel; everything about what that means is this
|
||||
installation's, which is the whole reason it may mint one at all.
|
||||
instance's, which is the whole reason it may mint one at all.
|
||||
"""
|
||||
write_config(
|
||||
PanelsConfig(
|
||||
@@ -241,7 +241,7 @@ def test_adding_a_remote_user_maps_and_revokes(
|
||||
f"{settings.API_V1_STR}/users/{body['id']}", headers=superuser_token_headers
|
||||
)
|
||||
assert removed.status_code == 200, removed.text
|
||||
assert delete.call_args.args[0].endswith("/installation-members/portal-user-9")
|
||||
assert delete.call_args.args[0].endswith("/instance-members/portal-user-9")
|
||||
db.expire_all()
|
||||
assert user_from_token(db, theirs) is None
|
||||
|
||||
@@ -251,7 +251,7 @@ def test_adding_a_remote_user_needs_a_superuser(
|
||||
enrolled: User, # noqa: ARG001 (fixture installs the enrolment)
|
||||
normal_user_token_headers: dict[str, str],
|
||||
) -> None:
|
||||
"""Widening who can reach this installation stays a superuser's decision."""
|
||||
"""Widening who can reach this instance stays a superuser's decision."""
|
||||
response = client.post(
|
||||
f"{settings.API_V1_STR}/cloud/users",
|
||||
headers=normal_user_token_headers,
|
||||
@@ -272,8 +272,8 @@ def test_enrolling_against_a_portal_without_an_owner_is_refused(
|
||||
status_code=200,
|
||||
json=Mock(
|
||||
return_value={
|
||||
"installation_id": str(uuid.uuid4()),
|
||||
"installation_token": "t",
|
||||
"instance_id": str(uuid.uuid4()),
|
||||
"instance_token": "t",
|
||||
"ws_url": f"{ISSUER}/api/v1/tunnel/attach",
|
||||
"issuer": ISSUER,
|
||||
"jwks": {"keys": []},
|
||||
|
||||
Reference in New Issue
Block a user