Add `federation.hostmeta` generators for Matrix client and server well-known files.

Django views and url configuration also included for convenience.
matrix-appservice
Jason Robinson 2020-12-20 17:55:01 +02:00
rodzic 34d04f01f1
commit 48be2cbb6e
5 zmienionych plików z 103 dodań i 2 usunięć

Wyświetl plik

@ -2,6 +2,11 @@
## [unreleased]
### Added
* Add `federation.hostmeta` generators for Matrix client and server well-known files.
Django views and url configuration also included for convenience.
## [0.21.0] - 2020-12-20
### Added

Wyświetl plik

@ -149,6 +149,8 @@ Generator classes
.. autoclass:: federation.hostmeta.generators.DiasporaHostMeta
.. autoclass:: federation.hostmeta.generators.DiasporaWebFinger
.. autoclass:: federation.hostmeta.generators.DiasporaHCard
.. autoclass:: federation.hostmeta.generators.MatrixClientWellKnown
.. autoclass:: federation.hostmeta.generators.MatrixServerWellKnown
.. autoclass:: federation.hostmeta.generators.NodeInfo
.. autoclass:: federation.hostmeta.generators.RFC7033Webfinger
.. autoclass:: federation.hostmeta.generators.SocialRelayWellKnown
@ -189,6 +191,8 @@ It must be installed separately.
.. autofunction:: federation.entities.activitypub.django.views.activitypub_object_view
.. autofunction:: federation.hostmeta.django.generators.rfc7033_webfinger_view
.. autofunction:: federation.hostmeta.django.generators.matrix_client_wellknown_view
.. autofunction:: federation.hostmeta.django.generators.matrix_server_wellknown_view
.. autofunction:: federation.hostmeta.django.generators.nodeinfo2_view
Configuration
@ -209,6 +213,7 @@ Some settings need to be set in Django settings. An example is below:
"get_object_function": "myproject.utils.get_object",
"get_private_key_function": "myproject.utils.get_private_key",
"get_profile_function": "myproject.utils.get_profile",
"matrix_config_function": "myproject.utils.matrix_config_funct",
"nodeinfo2_function": "myproject.utils.get_nodeinfo2_data",
"process_payload_function": "myproject.utils.process_payload",
"search_path": "/search/?q=",
@ -219,6 +224,23 @@ Some settings need to be set in Django settings. An example is below:
* ``get_object_function`` should be the full path to a function that will return the object matching the ActivityPub ID for the request object passed to this function.
* ``get_private_key_function`` should be the full path to a function that will accept a federation ID (url, handle or guid) and return the private key of the user (as an RSA object). Required for example to sign outbound messages in some cases.
* ``get_profile_function`` should be the full path to a function that should return a ``Profile`` entity. The function should take one or more keyword arguments: ``fid``, ``handle``, ``guid`` or ``request``. It should look up a profile with one or more of the provided parameters.
* ``matrix_config_function`` (optional) function that returns a Matrix configuration dictionary, with the following objects:
::
{
# Location of the homeserver (not server name)
"homeserver_base_url": "https://matrix.domain.tld",
# Homeserver domain and port (not server domain)
"homeserver_domain_with_port": "matrix.domain.tld:443",
# (Optional) location of identity server
"identity_server_base_url": "https://id.domain.tld",
# (Optional) other keys to include in the client well-known (must be a dictionary)
"client_wellknown_other_keys": {
"org.foo.key" "barfoo",
},
}
* ``nodeinfo2_function`` (optional) function that returns data for generating a `NodeInfo2 document <https://github.com/jaywink/nodeinfo2>`_. Once configured the path ``/.well-known/x-nodeinfo2`` will automatically generate a NodeInfo2 document. The function should return a ``dict`` corresponding to the NodeInfo2 schema, with the following minimum items:
::

Wyświetl plik

@ -1,8 +1,11 @@
import logging
# noinspection PyPackageRequirements
from django.http import HttpResponseBadRequest, JsonResponse, HttpResponseNotFound
from federation.hostmeta.generators import RFC7033Webfinger, generate_nodeinfo2_document
from federation.hostmeta.generators import (
RFC7033Webfinger, generate_nodeinfo2_document, MatrixClientWellKnown, MatrixServerWellKnown,
)
from federation.utils.django import get_configuration, get_function_from_config
from federation.utils.text import get_path_from_url
@ -19,6 +22,34 @@ def nodeinfo2_view(request, *args, **kwargs):
return JsonResponse(generate_nodeinfo2_document(**nodeinfo2))
def matrix_client_wellknown_view(request, *args, **kwargs):
try:
matrix_config_func = get_function_from_config("matrix_config_function")
except AttributeError:
return HttpResponseBadRequest("Not configured")
matrix_config = matrix_config_func()
wellknown = MatrixClientWellKnown(
homeserver_base_url=matrix_config["homeserver_base_url"],
identity_server_base_url=matrix_config.get("identity_server_base_url"),
other_keys=matrix_config.get("client_wellknown_other_keys"),
)
return JsonResponse(wellknown.render())
def matrix_server_wellknown_view(request, *args, **kwargs):
try:
matrix_config_func = get_function_from_config("matrix_config_function")
except AttributeError:
return HttpResponseBadRequest("Not configured")
matrix_config = matrix_config_func()
wellknown = MatrixServerWellKnown(
homeserver_domain_with_port=matrix_config["homeserver_domain_with_port"],
)
return JsonResponse(wellknown.render())
def rfc7033_webfinger_view(request, *args, **kwargs):
"""
Django view to generate an RFC7033 webfinger.

Wyświetl plik

@ -1,9 +1,14 @@
# noinspection PyPackageRequirements
from django.conf.urls import url
from federation.hostmeta.django import rfc7033_webfinger_view
from federation.hostmeta.django.generators import nodeinfo2_view
from federation.hostmeta.django.generators import (
nodeinfo2_view, matrix_client_wellknown_view, matrix_server_wellknown_view,
)
urlpatterns = [
url(r'^.well-known/matrix/client$', matrix_client_wellknown_view, name="matrix-client-wellknown"),
url(r'^.well-known/matrix/server$', matrix_server_wellknown_view, name="matrix-server-wellknown"),
url(r'^.well-known/webfinger$', rfc7033_webfinger_view, name="rfc7033-webfinger"),
url(r'^.well-known/x-nodeinfo2$', nodeinfo2_view, name="nodeinfo2"),
]

Wyświetl plik

@ -3,6 +3,7 @@ import os
import warnings
from base64 import b64encode
from string import Template
from typing import Dict
from jsonschema import validate
from jsonschema.exceptions import ValidationError
@ -331,6 +332,43 @@ def get_nodeinfo_well_known_document(url, document_path=None):
}
class MatrixClientWellKnown:
"""
Matrix Client well-known as per https://matrix.org/docs/spec/client_server/r0.6.1#server-discovery
"""
def __init__(self, homeserver_base_url: str, identity_server_base_url: str = None, other_keys: Dict = None):
self.homeserver_base_url = homeserver_base_url
self.identity_server_base_url = identity_server_base_url
self.other_keys = other_keys
def render(self):
doc = {
"m.homeserver": {
"base_url": self.homeserver_base_url,
}
}
if self.identity_server_base_url:
doc["m.identity_server"] = {
"base_url": self.identity_server_base_url,
}
if self.other_keys:
doc.update(self.other_keys)
return doc
class MatrixServerWellKnown:
"""
Matrix Server well-known as per https://matrix.org/docs/spec/server_server/r0.1.4#server-discovery
"""
def __init__(self, homeserver_domain_with_port: str):
self.homeserver_domain_with_port = homeserver_domain_with_port
def render(self):
return {
"m.server": self.homeserver_domain_with_port,
}
class RFC7033Webfinger:
"""
RFC 7033 webfinger - see https://tools.ietf.org/html/rfc7033