Merge pull request #1091 from matrix-org/paul/third-party-lookup
Improvements to 3PE lookup API
This commit is contained in:
commit
56f38d1776
|
@ -32,6 +32,14 @@ HOUR_IN_MS = 60 * 60 * 1000
|
||||||
APP_SERVICE_PREFIX = "/_matrix/app/unstable"
|
APP_SERVICE_PREFIX = "/_matrix/app/unstable"
|
||||||
|
|
||||||
|
|
||||||
|
def _is_valid_3pe_metadata(info):
|
||||||
|
if "instances" not in info:
|
||||||
|
return False
|
||||||
|
if not isinstance(info["instances"], list):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _is_valid_3pe_result(r, field):
|
def _is_valid_3pe_result(r, field):
|
||||||
if not isinstance(r, dict):
|
if not isinstance(r, dict):
|
||||||
return False
|
return False
|
||||||
|
@ -162,11 +170,18 @@ class ApplicationServiceApi(SimpleHttpClient):
|
||||||
urllib.quote(protocol)
|
urllib.quote(protocol)
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
defer.returnValue((yield self.get_json(uri, {})))
|
info = yield self.get_json(uri, {})
|
||||||
|
|
||||||
|
if not _is_valid_3pe_metadata(info):
|
||||||
|
logger.warning("query_3pe_protocol to %s did not return a"
|
||||||
|
" valid result", uri)
|
||||||
|
defer.returnValue(None)
|
||||||
|
|
||||||
|
defer.returnValue(info)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning("query_3pe_protocol to %s threw exception %s",
|
logger.warning("query_3pe_protocol to %s threw exception %s",
|
||||||
uri, ex)
|
uri, ex)
|
||||||
defer.returnValue({})
|
defer.returnValue(None)
|
||||||
|
|
||||||
key = (service.id, protocol)
|
key = (service.id, protocol)
|
||||||
return self.protocol_meta_cache.get(key) or (
|
return self.protocol_meta_cache.get(key) or (
|
||||||
|
|
|
@ -176,12 +176,41 @@ class ApplicationServicesHandler(object):
|
||||||
defer.returnValue(ret)
|
defer.returnValue(ret)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_3pe_protocols(self):
|
def get_3pe_protocols(self, only_protocol=None):
|
||||||
services = yield self.store.get_app_services()
|
services = yield self.store.get_app_services()
|
||||||
protocols = {}
|
protocols = {}
|
||||||
|
|
||||||
|
# Collect up all the individual protocol responses out of the ASes
|
||||||
for s in services:
|
for s in services:
|
||||||
for p in s.protocols:
|
for p in s.protocols:
|
||||||
protocols[p] = yield self.appservice_api.get_3pe_protocol(s, p)
|
if only_protocol is not None and p != only_protocol:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if p not in protocols:
|
||||||
|
protocols[p] = []
|
||||||
|
|
||||||
|
info = yield self.appservice_api.get_3pe_protocol(s, p)
|
||||||
|
|
||||||
|
if info is not None:
|
||||||
|
protocols[p].append(info)
|
||||||
|
|
||||||
|
def _merge_instances(infos):
|
||||||
|
if not infos:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
# Merge the 'instances' lists of multiple results, but just take
|
||||||
|
# the other fields from the first as they ought to be identical
|
||||||
|
# copy the result so as not to corrupt the cached one
|
||||||
|
combined = dict(infos[0])
|
||||||
|
combined["instances"] = list(combined["instances"])
|
||||||
|
|
||||||
|
for info in infos[1:]:
|
||||||
|
combined["instances"].extend(info["instances"])
|
||||||
|
|
||||||
|
return combined
|
||||||
|
|
||||||
|
for p in protocols.keys():
|
||||||
|
protocols[p] = _merge_instances(protocols[p])
|
||||||
|
|
||||||
defer.returnValue(protocols)
|
defer.returnValue(protocols)
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,29 @@ class ThirdPartyProtocolsServlet(RestServlet):
|
||||||
defer.returnValue((200, protocols))
|
defer.returnValue((200, protocols))
|
||||||
|
|
||||||
|
|
||||||
|
class ThirdPartyProtocolServlet(RestServlet):
|
||||||
|
PATTERNS = client_v2_patterns("/thirdparty/protocol/(?P<protocol>[^/]+)$",
|
||||||
|
releases=())
|
||||||
|
|
||||||
|
def __init__(self, hs):
|
||||||
|
super(ThirdPartyProtocolServlet, self).__init__()
|
||||||
|
|
||||||
|
self.auth = hs.get_auth()
|
||||||
|
self.appservice_handler = hs.get_application_service_handler()
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def on_GET(self, request, protocol):
|
||||||
|
yield self.auth.get_user_by_req(request)
|
||||||
|
|
||||||
|
protocols = yield self.appservice_handler.get_3pe_protocols(
|
||||||
|
only_protocol=protocol,
|
||||||
|
)
|
||||||
|
if protocol in protocols:
|
||||||
|
defer.returnValue((200, protocols[protocol]))
|
||||||
|
else:
|
||||||
|
defer.returnValue((404, {"error": "Unknown protocol"}))
|
||||||
|
|
||||||
|
|
||||||
class ThirdPartyUserServlet(RestServlet):
|
class ThirdPartyUserServlet(RestServlet):
|
||||||
PATTERNS = client_v2_patterns("/thirdparty/user(/(?P<protocol>[^/]+))?$",
|
PATTERNS = client_v2_patterns("/thirdparty/user(/(?P<protocol>[^/]+))?$",
|
||||||
releases=())
|
releases=())
|
||||||
|
@ -92,5 +115,6 @@ class ThirdPartyLocationServlet(RestServlet):
|
||||||
|
|
||||||
def register_servlets(hs, http_server):
|
def register_servlets(hs, http_server):
|
||||||
ThirdPartyProtocolsServlet(hs).register(http_server)
|
ThirdPartyProtocolsServlet(hs).register(http_server)
|
||||||
|
ThirdPartyProtocolServlet(hs).register(http_server)
|
||||||
ThirdPartyUserServlet(hs).register(http_server)
|
ThirdPartyUserServlet(hs).register(http_server)
|
||||||
ThirdPartyLocationServlet(hs).register(http_server)
|
ThirdPartyLocationServlet(hs).register(http_server)
|
||||||
|
|
Loading…
Reference in New Issue