Merge pull request #6688 from matrix-org/rav/module_api_extensions

Cleanups and additions to the module API
This commit is contained in:
Richard van der Hoff 2020-01-15 16:43:13 +00:00 committed by GitHub
commit 608bf7d741
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 7 deletions

1
changelog.d/6688.misc Normal file
View file

@ -0,0 +1 @@
Updates and extensions to the module API.

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 New Vector Ltd # Copyright 2017 New Vector Ltd
# Copyright 2020 The Matrix.org Foundation C.I.C.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -16,18 +17,26 @@ import logging
from twisted.internet import defer from twisted.internet import defer
from synapse.logging.context import make_deferred_yieldable, run_in_background
from synapse.types import UserID from synapse.types import UserID
"""
This package defines the 'stable' API which can be used by extension modules which
are loaded into Synapse.
"""
__all__ = ["errors", "make_deferred_yieldable", "run_in_background", "ModuleApi"]
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ModuleApi(object): class ModuleApi(object):
"""A proxy object that gets passed to password auth providers so they """A proxy object that gets passed to various plugin modules so they
can register new users etc if necessary. can register new users etc if necessary.
""" """
def __init__(self, hs, auth_handler): def __init__(self, hs, auth_handler):
self.hs = hs self._hs = hs
self._store = hs.get_datastore() self._store = hs.get_datastore()
self._auth = hs.get_auth() self._auth = hs.get_auth()
@ -64,7 +73,7 @@ class ModuleApi(object):
""" """
if username.startswith("@"): if username.startswith("@"):
return username return username
return UserID(username, self.hs.hostname).to_string() return UserID(username, self._hs.hostname).to_string()
def check_user_exists(self, user_id): def check_user_exists(self, user_id):
"""Check if user exists. """Check if user exists.
@ -111,10 +120,14 @@ class ModuleApi(object):
displayname (str|None): The displayname of the new user. displayname (str|None): The displayname of the new user.
emails (List[str]): Emails to bind to the new user. emails (List[str]): Emails to bind to the new user.
Raises:
SynapseError if there is an error performing the registration. Check the
'errcode' property for more information on the reason for failure
Returns: Returns:
Deferred[str]: user_id Deferred[str]: user_id
""" """
return self.hs.get_registration_handler().register_user( return self._hs.get_registration_handler().register_user(
localpart=localpart, default_display_name=displayname, bind_emails=emails localpart=localpart, default_display_name=displayname, bind_emails=emails
) )
@ -131,12 +144,34 @@ class ModuleApi(object):
Returns: Returns:
defer.Deferred[tuple[str, str]]: Tuple of device ID and access token defer.Deferred[tuple[str, str]]: Tuple of device ID and access token
""" """
return self.hs.get_registration_handler().register_device( return self._hs.get_registration_handler().register_device(
user_id=user_id, user_id=user_id,
device_id=device_id, device_id=device_id,
initial_display_name=initial_display_name, initial_display_name=initial_display_name,
) )
def record_user_external_id(
self, auth_provider_id: str, remote_user_id: str, registered_user_id: str
) -> defer.Deferred:
"""Record a mapping from an external user id to a mxid
Args:
auth_provider: identifier for the remote auth provider
external_id: id on that system
user_id: complete mxid that it is mapped to
"""
return self._store.record_user_external_id(
auth_provider_id, remote_user_id, registered_user_id
)
def generate_short_term_login_token(
self, user_id: str, duration_in_ms: int = (2 * 60 * 1000)
) -> str:
"""Generate a login token suitable for m.login.token authentication"""
return self._hs.get_macaroon_generator().generate_short_term_login_token(
user_id, duration_in_ms
)
@defer.inlineCallbacks @defer.inlineCallbacks
def invalidate_access_token(self, access_token): def invalidate_access_token(self, access_token):
"""Invalidate an access token for a user """Invalidate an access token for a user
@ -157,7 +192,7 @@ class ModuleApi(object):
user_id = user_info["user"].to_string() user_id = user_info["user"].to_string()
if device_id: if device_id:
# delete the device, which will also delete its access tokens # delete the device, which will also delete its access tokens
yield self.hs.get_device_handler().delete_device(user_id, device_id) yield self._hs.get_device_handler().delete_device(user_id, device_id)
else: else:
# no associated device. Just delete the access token. # no associated device. Just delete the access token.
yield self._auth_handler.delete_access_token(access_token) yield self._auth_handler.delete_access_token(access_token)

View file

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Copyright 2020 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Exception types which are exposed as part of the stable module API"""
from synapse.api.errors import RedirectException, SynapseError # noqa: F401

View file

@ -34,7 +34,7 @@ def load_module(provider):
provider_class = getattr(module, clz) provider_class = getattr(module, clz)
try: try:
provider_config = provider_class.parse_config(provider["config"]) provider_config = provider_class.parse_config(provider.get("config"))
except Exception as e: except Exception as e:
raise ConfigError("Failed to parse config for %r: %r" % (provider["module"], e)) raise ConfigError("Failed to parse config for %r: %r" % (provider["module"], e))