🚧 WIP
This commit is contained in:
@@ -87,16 +87,19 @@ def client(db_session, monkeypatch):
|
||||
|
||||
# Fake dynsec so no broker is needed for API tests.
|
||||
class FakeDynsec:
|
||||
"""Mirrors the corrected wire contract: _command returns the `data`
|
||||
object; client objects use `disabled` (absent == enabled)."""
|
||||
|
||||
def __init__(self):
|
||||
self.clients: dict[str, dict] = {}
|
||||
self.roles: dict[str, dict] = {}
|
||||
self.groups: dict[str, dict] = {}
|
||||
|
||||
def _command(self, command, **kwargs):
|
||||
return {"success": True}
|
||||
return {}
|
||||
|
||||
def create_client(self, username, password, **kwargs):
|
||||
self.clients[username] = {"username": username, "enabled": True, **kwargs}
|
||||
self.clients[username] = {"username": username, "disabled": False, **kwargs}
|
||||
|
||||
def list_clients(self):
|
||||
return list(self.clients.values())
|
||||
@@ -105,10 +108,10 @@ def client(db_session, monkeypatch):
|
||||
self.clients.pop(username, None)
|
||||
|
||||
def disable_client(self, username):
|
||||
self.clients[username]["enabled"] = False
|
||||
self.clients[username]["disabled"] = True
|
||||
|
||||
def enable_client(self, username):
|
||||
self.clients[username]["enabled"] = True
|
||||
self.clients[username]["disabled"] = False
|
||||
|
||||
def set_client_password(self, username, password):
|
||||
pass
|
||||
@@ -140,6 +143,43 @@ def client(db_session, monkeypatch):
|
||||
def get_role(self, rolename):
|
||||
return self.roles[rolename]
|
||||
|
||||
def add_client_role(self, username, rolename, priority=-1):
|
||||
client = self.clients.setdefault(username, {"username": username, "disabled": False})
|
||||
client["roles"] = [
|
||||
*client.get("roles", []),
|
||||
{"rolename": rolename, "priority": priority},
|
||||
]
|
||||
|
||||
def remove_client_role(self, username, rolename):
|
||||
client = self.clients.get(username, {})
|
||||
client["roles"] = [
|
||||
r for r in client.get("roles", []) if r["rolename"] != rolename
|
||||
]
|
||||
|
||||
def add_group_client(self, groupname, username, priority=1):
|
||||
self.clients.setdefault(username, {}).setdefault("groups", []).append(
|
||||
{"groupname": groupname, "priority": priority}
|
||||
)
|
||||
|
||||
def remove_group_client(self, groupname, username):
|
||||
client = self.clients.get(username, {})
|
||||
client["groups"] = [
|
||||
g for g in client.get("groups", []) if g["groupname"] != groupname
|
||||
]
|
||||
|
||||
def add_group_role(self, groupname, rolename, priority=-1):
|
||||
group = self.groups.setdefault(groupname, {"groupname": groupname, "roles": []})
|
||||
group["roles"] = [
|
||||
*group.get("roles", []),
|
||||
{"rolename": rolename, "priority": priority},
|
||||
]
|
||||
|
||||
def remove_group_role(self, groupname, rolename):
|
||||
group = self.groups.get(groupname, {})
|
||||
group["roles"] = [
|
||||
r for r in group.get("roles", []) if r["rolename"] != rolename
|
||||
]
|
||||
|
||||
def connect(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -99,6 +99,66 @@ def test_group_lifecycle(admin_client):
|
||||
assert admin_client.delete("/api/v1/mqtt/groups/sensors").status_code == 204
|
||||
|
||||
|
||||
def test_client_role_assignment(admin_client):
|
||||
admin_client.post("/api/v1/mqtt/roles", json={"rolename": "telemetry"})
|
||||
admin_client.post("/api/v1/mqtt/clients", json={"username": "assign-test"})
|
||||
|
||||
response = admin_client.post(
|
||||
"/api/v1/mqtt/clients/assign-test/roles",
|
||||
json={"rolename": "telemetry", "priority": 5},
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
client = admin_client.get("/api/v1/mqtt/clients/assign-test").json()
|
||||
roles = {r["rolename"] for r in client["roles"]}
|
||||
assert "telemetry" in roles
|
||||
|
||||
assert (
|
||||
admin_client.delete("/api/v1/mqtt/clients/assign-test/roles/telemetry").status_code
|
||||
== 204
|
||||
)
|
||||
client = admin_client.get("/api/v1/mqtt/clients/assign-test").json()
|
||||
assert all(r["rolename"] != "telemetry" for r in client["roles"])
|
||||
|
||||
|
||||
def test_group_member_assignment(admin_client):
|
||||
admin_client.post("/api/v1/mqtt/groups", json={"groupname": "sensors"})
|
||||
admin_client.post("/api/v1/mqtt/clients", json={"username": "member-test"})
|
||||
|
||||
response = admin_client.post(
|
||||
"/api/v1/mqtt/groups/sensors/clients",
|
||||
json={"username": "member-test", "priority": 1},
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
client = admin_client.get("/api/v1/mqtt/clients/member-test").json()
|
||||
groups = {g["groupname"] for g in client["groups"]}
|
||||
assert "sensors" in groups
|
||||
|
||||
assert (
|
||||
admin_client.delete("/api/v1/mqtt/groups/sensors/clients/member-test").status_code
|
||||
== 204
|
||||
)
|
||||
client = admin_client.get("/api/v1/mqtt/clients/member-test").json()
|
||||
assert all(g["groupname"] != "sensors" for g in client["groups"])
|
||||
|
||||
|
||||
def test_group_role_assignment(admin_client):
|
||||
admin_client.post("/api/v1/mqtt/groups", json={"groupname": "sensors"})
|
||||
admin_client.post("/api/v1/mqtt/roles", json={"rolename": "telemetry"})
|
||||
|
||||
response = admin_client.post(
|
||||
"/api/v1/mqtt/groups/sensors/roles",
|
||||
json={"rolename": "telemetry", "priority": 2},
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
assert (
|
||||
admin_client.delete("/api/v1/mqtt/groups/sensors/roles/telemetry").status_code
|
||||
== 204
|
||||
)
|
||||
|
||||
|
||||
def test_listener_management_and_preview(admin_client):
|
||||
response = admin_client.post(
|
||||
"/api/v1/broker/listeners",
|
||||
@@ -114,7 +174,7 @@ def test_listener_management_and_preview(admin_client):
|
||||
# Generated config must not use options deprecated in 2.1 (spec 3.1).
|
||||
assert "password_file" not in config_text
|
||||
assert "acl_file" not in config_text
|
||||
assert "per_listener_settings false" in config_text
|
||||
assert "per_listener_settings" not in config_text
|
||||
|
||||
delete = admin_client.delete(f"/api/v1/broker/listeners/{listener_id}")
|
||||
assert delete.status_code == 204
|
||||
|
||||
@@ -30,9 +30,10 @@ def test_generate_with_one_listener(session):
|
||||
|
||||
result = generate_config(session)
|
||||
assert "listener 1883" in result.config_text
|
||||
assert "per_listener_settings false" in result.config_text
|
||||
assert "global_plugin /usr/lib/mosquitto_dynamic_security.so" in result.config_text
|
||||
assert "allow_anonymous false" in result.config_text
|
||||
# Must NOT use options deprecated in 2.1 (spec 3.1).
|
||||
assert "per_listener_settings" not in result.config_text
|
||||
assert result.warnings == []
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user