feat: publish Hermes Nextcloud calendar MCP under AGPL-3.0
This commit is contained in:
112
tests/keyring_fakes.py
Normal file
112
tests/keyring_fakes.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""Synthetic D-Bus boundary; real SecretStorage negotiates and decrypts sessions."""
|
||||
|
||||
import json
|
||||
from dataclasses import asdict
|
||||
|
||||
from jeepney import HeaderFields, new_error, new_method_return
|
||||
from secretstorage.dhcrypto import Session
|
||||
from secretstorage.util import format_secret
|
||||
|
||||
|
||||
class KeyringBus:
|
||||
def __init__(self, profile=None):
|
||||
self.names = {
|
||||
"org.gnome.keyring": ":1.10",
|
||||
"org.kde.secretservicecompat": ":1.20",
|
||||
"org.freedesktop.secrets": ":1.10",
|
||||
}
|
||||
self.activatable = set(self.names)
|
||||
self.locked = set()
|
||||
self.plain = set()
|
||||
self.missing_default = set()
|
||||
self.calls = []
|
||||
self.sessions = {}
|
||||
self.closed = False
|
||||
self.switch_default_on_read = False
|
||||
self.payload = (
|
||||
json.dumps({"version": 1, "profile": asdict(profile)}).encode()
|
||||
if profile
|
||||
else None
|
||||
)
|
||||
|
||||
def close(self):
|
||||
self.closed = True
|
||||
|
||||
def send_and_get_reply(self, message, *, timeout=None):
|
||||
fields = message.header.fields
|
||||
destination = fields[HeaderFields.destination]
|
||||
method = fields[HeaderFields.member]
|
||||
self.calls.append((destination, method, message.body, timeout))
|
||||
|
||||
def reply(signature, *body):
|
||||
return new_method_return(message, signature, body)
|
||||
|
||||
def error(name):
|
||||
return new_error(message, name, "s", ("synthetic error",))
|
||||
|
||||
if destination == "org.freedesktop.DBus":
|
||||
if method == "ListNames":
|
||||
return reply("as", list(self.names))
|
||||
if method == "ListActivatableNames":
|
||||
return reply("as", list(self.activatable))
|
||||
if method == "GetNameOwner":
|
||||
if message.body[0] not in self.names:
|
||||
return error("org.freedesktop.DBus.Error.NameHasNoOwner")
|
||||
return reply("s", self.names[message.body[0]])
|
||||
if method == "GetConnectionUnixProcessID":
|
||||
return reply("u", 123)
|
||||
owner = self.names.get(destination, destination)
|
||||
if owner not in {":1.10", ":1.20", ":1.30"}:
|
||||
return error("org.freedesktop.DBus.Error.ServiceUnknown")
|
||||
if method == "ReadAlias":
|
||||
if self.switch_default_on_read:
|
||||
self.names["org.freedesktop.secrets"] = ":1.20"
|
||||
return reply(
|
||||
"o",
|
||||
"/"
|
||||
if owner in self.missing_default
|
||||
else "/org/freedesktop/secrets/collection/default",
|
||||
)
|
||||
if method == "Get":
|
||||
name = message.body[1]
|
||||
values = {
|
||||
"Label": ("s", "Synthetic wallet"),
|
||||
"Locked": ("b", owner in self.locked),
|
||||
"Attributes": (
|
||||
"a{ss}",
|
||||
{"application": "hermes-caldav-mcp", "profile": "default"},
|
||||
),
|
||||
}
|
||||
return reply("v", values[name])
|
||||
if method == "OpenSession":
|
||||
if owner in self.plain:
|
||||
if message.body[0] != "plain":
|
||||
return error("org.freedesktop.DBus.Error.NotSupported")
|
||||
return reply("vo", ("s", ""), "/org/freedesktop/secrets/session/plain")
|
||||
session = Session()
|
||||
session.object_path = "/org/freedesktop/secrets/session/encrypted"
|
||||
session.set_server_public_key(int.from_bytes(message.body[1][1], "big"))
|
||||
self.sessions[owner] = session
|
||||
return reply(
|
||||
"vo",
|
||||
("ay", session.my_public_key.to_bytes(128, "big")),
|
||||
session.object_path,
|
||||
)
|
||||
if method == "SearchItems":
|
||||
return reply(
|
||||
"ao",
|
||||
["/org/freedesktop/secrets/collection/default/item"]
|
||||
if self.payload
|
||||
else [],
|
||||
)
|
||||
if method == "GetSecret":
|
||||
return reply(
|
||||
"(oayays)",
|
||||
format_secret(self.sessions[owner], self.payload, "application/json"),
|
||||
)
|
||||
if method == "CreateItem":
|
||||
return reply("oo", "/org/freedesktop/secrets/collection/default/item", "/")
|
||||
if method == "Delete":
|
||||
self.payload = None
|
||||
return reply("o", "/")
|
||||
raise AssertionError("Unexpected D-Bus method: " + method)
|
||||
Reference in New Issue
Block a user