connect fix 4

This commit is contained in:
2026-08-21 06:14:10 +02:00
parent bf2a02679d
commit 5e506c9921
17 changed files with 1266 additions and 162 deletions

View File

@ -25,6 +25,25 @@ from __future__ import annotations
import pyotp
import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
def _key_pem() -> str:
"""Echtes, unverschluesseltes Schluesselmaterial.
Seit Phase 10 prueft POST/PUT /admin/ssh-keys das Material sofort gegen
asyncssh (damit ein unbrauchbarer Schluessel nicht erst beim ersten
Verbindungsversuch auffaellt). Platzhalter wie "PEM" werden deshalb --
voellig korrekt -- mit HTTP 400 abgelehnt; diese Tests hier pruefen aber
Mandantenisolation und CRUD und brauchen einen gueltigen Schluessel.
"""
return ed25519.Ed25519PrivateKey.generate().private_bytes(
serialization.Encoding.PEM,
serialization.PrivateFormat.OpenSSH,
serialization.NoEncryption(),
).decode()
async def _create_user(conn, username: str, password: str, *, is_admin: bool = False, home_tenant_id=None) -> int:
from app.security.passwords import hash_password
@ -244,7 +263,7 @@ async def test_tenant_admin_isolated_from_other_tenants_users_and_ssh_keys(clien
resp = await client.post(
"/admin/ssh-keys",
json={
"label": "std-key", "private_key_pem": "PEM", "public_key": "PUB",
"label": "std-key", "private_key_pem": _key_pem(), "public_key": "PUB",
"key_type": "ed25519", "tenant_id": 1,
},
)
@ -273,7 +292,7 @@ async def test_tenant_admin_isolated_from_other_tenants_users_and_ssh_keys(clien
# Eigenen SSH-Key anlegen -- ohne tenant_id automatisch auf E erzwungen.
resp = await client.post(
"/admin/ssh-keys",
json={"label": "e-key", "private_key_pem": "PEM2", "public_key": "PUB2", "key_type": "ed25519"},
json={"label": "e-key", "private_key_pem": _key_pem(), "public_key": "PUB2", "key_type": "ed25519"},
)
assert resp.status_code == 201, resp.text
e_key_id = resp.json()["id"]
@ -513,19 +532,20 @@ async def test_ssh_key_update_rotate_and_delete(client):
resp = await client.post(
"/admin/ssh-keys",
json={"label": "orig-key", "private_key_pem": "PEM", "public_key": "PUB", "key_type": "ed25519"},
json={"label": "orig-key", "private_key_pem": _key_pem(), "public_key": "PUB", "key_type": "ed25519"},
)
key_id = resp.json()["id"]
resp = await client.put(f"/admin/ssh-keys/{key_id}", json={"label": "renamed-key"})
assert resp.status_code == 200, resp.text
# Rotation erfordert alle drei Felder gemeinsam.
# Rotation erfordert alle drei Felder gemeinsam (400 noch vor jeder
# Materialpruefung -- der Platzhalter hier ist deshalb Absicht).
resp = await client.put(f"/admin/ssh-keys/{key_id}", json={"private_key_pem": "NEWPEM"})
assert resp.status_code == 400, resp.text
resp = await client.put(
f"/admin/ssh-keys/{key_id}",
json={"private_key_pem": "NEWPEM", "public_key": "NEWPUB", "key_type": "rsa-4096"},
json={"private_key_pem": _key_pem(), "public_key": "NEWPUB", "key_type": "rsa-4096"},
)
assert resp.status_code == 200, resp.text
@ -579,13 +599,16 @@ async def test_host_detail_endpoint_includes_ssh_keys_and_rdp_flag(client):
resp = await client.post(
"/admin/ssh-keys",
json={"label": "detail-key", "private_key_pem": "PEM", "public_key": "PUB", "key_type": "ed25519"},
json={"label": "detail-key", "private_key_pem": _key_pem(), "public_key": "PUB", "key_type": "ed25519"},
)
key_id = resp.json()["id"]
resp = await client.post(f"/admin/hosts/{host_id}/ssh-keys/{key_id}")
assert resp.status_code == 200, resp.text
resp = await client.put(f"/admin/hosts/{host_id}/rdp-credentials", json={"password": "Correct-Horse-Battery-Staple-O2"})
resp = await client.put(
f"/admin/hosts/{host_id}/rdp-credentials",
json={"password": "Correct-Horse-Battery-Staple-O2", "username": "Administrator"},
)
assert resp.status_code == 200, resp.text
resp = await client.get(f"/admin/hosts/{host_id}")