2015-01-16 08:21:14 -05:00
|
|
|
# -*- coding: utf-8 -*-
|
2016-01-06 23:26:29 -05:00
|
|
|
# Copyright 2014-2016 OpenMarket Ltd
|
2018-03-28 09:03:37 -04:00
|
|
|
# Copyright 2018 New Vector Ltd
|
2015-01-16 08:21:14 -05:00
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
|
|
|
|
from twisted.internet import defer
|
2015-10-20 06:58:58 -04:00
|
|
|
from synapse.api.constants import Membership
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
from synapse.api.urls import FEDERATION_PREFIX as PREFIX
|
|
|
|
from synapse.util.logutils import log_function
|
|
|
|
|
|
|
|
import logging
|
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class TransportLayerClient(object):
|
|
|
|
"""Sends federation HTTP requests to other servers"""
|
|
|
|
|
2016-01-26 08:52:29 -05:00
|
|
|
def __init__(self, hs):
|
|
|
|
self.server_name = hs.hostname
|
|
|
|
self.client = hs.get_http_client()
|
|
|
|
|
2015-01-16 08:21:14 -05:00
|
|
|
@log_function
|
2015-01-16 13:59:04 -05:00
|
|
|
def get_room_state(self, destination, room_id, event_id):
|
|
|
|
""" Requests all state for a given room from the given server at the
|
|
|
|
given event.
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
Args:
|
|
|
|
destination (str): The host name of the remote home server we want
|
|
|
|
to get the state from.
|
|
|
|
context (str): The name of the context we want the state of
|
2015-01-16 13:20:19 -05:00
|
|
|
event_id (str): The event we want the context at.
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
Deferred: Results in a dict received from the remote homeserver.
|
|
|
|
"""
|
2015-01-16 13:59:04 -05:00
|
|
|
logger.debug("get_room_state dest=%s, room=%s",
|
|
|
|
destination, room_id)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2015-01-16 13:59:04 -05:00
|
|
|
path = PREFIX + "/state/%s/" % room_id
|
2015-01-16 13:20:19 -05:00
|
|
|
return self.client.get_json(
|
|
|
|
destination, path=path, args={"event_id": event_id},
|
2016-08-03 09:47:37 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def get_room_state_ids(self, destination, room_id, event_id):
|
|
|
|
""" Requests all state for a given room from the given server at the
|
|
|
|
given event. Returns the state's event_id's
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination (str): The host name of the remote home server we want
|
|
|
|
to get the state from.
|
|
|
|
context (str): The name of the context we want the state of
|
|
|
|
event_id (str): The event we want the context at.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Deferred: Results in a dict received from the remote homeserver.
|
|
|
|
"""
|
|
|
|
logger.debug("get_room_state_ids dest=%s, room=%s",
|
|
|
|
destination, room_id)
|
|
|
|
|
|
|
|
path = PREFIX + "/state_ids/%s/" % room_id
|
|
|
|
return self.client.get_json(
|
|
|
|
destination, path=path, args={"event_id": event_id},
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
2015-05-19 09:53:32 -04:00
|
|
|
def get_event(self, destination, event_id, timeout=None):
|
2015-01-16 08:21:14 -05:00
|
|
|
""" Requests the pdu with give id and origin from the given server.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination (str): The host name of the remote home server we want
|
|
|
|
to get the state from.
|
|
|
|
event_id (str): The id of the event being requested.
|
2015-05-22 10:18:04 -04:00
|
|
|
timeout (int): How long to try (in ms) the destination for before
|
|
|
|
giving up. None indicates no timeout.
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
Deferred: Results in a dict received from the remote homeserver.
|
|
|
|
"""
|
|
|
|
logger.debug("get_pdu dest=%s, event_id=%s",
|
|
|
|
destination, event_id)
|
|
|
|
|
2015-01-16 13:20:19 -05:00
|
|
|
path = PREFIX + "/event/%s/" % (event_id, )
|
2015-05-19 09:53:32 -04:00
|
|
|
return self.client.get_json(destination, path=path, timeout=timeout)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
@log_function
|
2015-01-16 13:59:04 -05:00
|
|
|
def backfill(self, destination, room_id, event_tuples, limit):
|
2015-01-16 08:21:14 -05:00
|
|
|
""" Requests `limit` previous PDUs in a given context before list of
|
|
|
|
PDUs.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
dest (str)
|
2015-01-16 13:59:04 -05:00
|
|
|
room_id (str)
|
2015-01-16 08:21:14 -05:00
|
|
|
event_tuples (list)
|
|
|
|
limt (int)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Deferred: Results in a dict received from the remote homeserver.
|
|
|
|
"""
|
|
|
|
logger.debug(
|
2015-01-16 13:59:04 -05:00
|
|
|
"backfill dest=%s, room_id=%s, event_tuples=%s, limit=%s",
|
|
|
|
destination, room_id, repr(event_tuples), str(limit)
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
if not event_tuples:
|
|
|
|
# TODO: raise?
|
|
|
|
return
|
|
|
|
|
2015-01-16 13:59:04 -05:00
|
|
|
path = PREFIX + "/backfill/%s/" % (room_id,)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
args = {
|
|
|
|
"v": event_tuples,
|
|
|
|
"limit": [str(limit)],
|
|
|
|
}
|
|
|
|
|
2015-01-16 13:20:19 -05:00
|
|
|
return self.client.get_json(
|
|
|
|
destination,
|
|
|
|
path=path,
|
2015-01-16 08:21:14 -05:00
|
|
|
args=args,
|
|
|
|
)
|
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
|
|
|
def send_transaction(self, transaction, json_data_callback=None):
|
|
|
|
""" Sends the given Transaction to its destination
|
|
|
|
|
|
|
|
Args:
|
|
|
|
transaction (Transaction)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Deferred: Results of the deferred is a tuple in the form of
|
|
|
|
(response_code, response_body) where the response_body is a
|
|
|
|
python dict decoded from json
|
|
|
|
"""
|
|
|
|
logger.debug(
|
|
|
|
"send_data dest=%s, txid=%s",
|
|
|
|
transaction.destination, transaction.transaction_id
|
|
|
|
)
|
|
|
|
|
|
|
|
if transaction.destination == self.server_name:
|
|
|
|
raise RuntimeError("Transport layer cannot send to itself!")
|
|
|
|
|
|
|
|
# FIXME: This is only used by the tests. The actual json sent is
|
|
|
|
# generated by the json_data_callback.
|
|
|
|
json_data = transaction.get_dict()
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
response = yield self.client.put_json(
|
2015-01-16 08:21:14 -05:00
|
|
|
transaction.destination,
|
|
|
|
path=PREFIX + "/send/%s/" % transaction.transaction_id,
|
|
|
|
data=json_data,
|
|
|
|
json_data_callback=json_data_callback,
|
2015-11-17 13:26:50 -05:00
|
|
|
long_retries=True,
|
2017-03-22 20:12:21 -04:00
|
|
|
backoff_on_404=True, # If we get a 404 the other side has gone
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
logger.debug(
|
2015-02-04 11:28:12 -05:00
|
|
|
"send_data dest=%s, txid=%s, got response: 200",
|
|
|
|
transaction.destination, transaction.transaction_id,
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(response)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2017-03-23 07:10:36 -04:00
|
|
|
def make_query(self, destination, query_type, args, retry_on_dns_fail,
|
|
|
|
ignore_backoff=False):
|
2015-01-16 08:21:14 -05:00
|
|
|
path = PREFIX + "/query/%s" % query_type
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
content = yield self.client.get_json(
|
2015-01-16 08:21:14 -05:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args=args,
|
|
|
|
retry_on_dns_fail=retry_on_dns_fail,
|
2016-03-04 09:29:58 -05:00
|
|
|
timeout=10000,
|
2017-03-23 07:10:36 -04:00
|
|
|
ignore_backoff=ignore_backoff,
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(content)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2015-11-05 11:43:19 -05:00
|
|
|
def make_membership_event(self, destination, room_id, user_id, membership):
|
2017-04-20 19:46:54 -04:00
|
|
|
"""Asks a remote server to build and sign us a membership event
|
|
|
|
|
|
|
|
Note that this does not append any events to any graphs.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination (str): address of remote homeserver
|
|
|
|
room_id (str): room to join/leave
|
|
|
|
user_id (str): user to be joined/left
|
|
|
|
membership (str): one of join/leave
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Deferred: Succeeds when we get a 2xx HTTP response. The result
|
|
|
|
will be the decoded JSON body (ie, the new event).
|
|
|
|
|
|
|
|
Fails with ``HTTPRequestException`` if we get an HTTP response
|
|
|
|
code >= 300.
|
|
|
|
|
|
|
|
Fails with ``NotRetryingDestination`` if we are not yet ready
|
|
|
|
to retry this server.
|
2018-01-22 13:11:18 -05:00
|
|
|
|
|
|
|
Fails with ``FederationDeniedError`` if the remote destination
|
|
|
|
is not in our federation whitelist
|
2017-04-20 19:46:54 -04:00
|
|
|
"""
|
2015-10-20 06:58:58 -04:00
|
|
|
valid_memberships = {Membership.JOIN, Membership.LEAVE}
|
|
|
|
if membership not in valid_memberships:
|
|
|
|
raise RuntimeError(
|
|
|
|
"make_membership_event called with membership='%s', must be one of %s" %
|
|
|
|
(membership, ",".join(valid_memberships))
|
|
|
|
)
|
|
|
|
path = PREFIX + "/make_%s/%s/%s" % (membership, room_id, user_id)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2017-04-20 20:50:36 -04:00
|
|
|
ignore_backoff = False
|
|
|
|
retry_on_dns_fail = False
|
|
|
|
|
|
|
|
if membership == Membership.LEAVE:
|
|
|
|
# we particularly want to do our best to send leave events. The
|
|
|
|
# problem is that if it fails, we won't retry it later, so if the
|
|
|
|
# remote server was just having a momentary blip, the room will be
|
|
|
|
# out of sync.
|
|
|
|
ignore_backoff = True
|
|
|
|
retry_on_dns_fail = True
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
content = yield self.client.get_json(
|
2015-01-16 08:21:14 -05:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-04-20 20:50:36 -04:00
|
|
|
retry_on_dns_fail=retry_on_dns_fail,
|
2016-04-15 06:22:23 -04:00
|
|
|
timeout=20000,
|
2017-04-20 20:50:36 -04:00
|
|
|
ignore_backoff=ignore_backoff,
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(content)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2015-01-16 13:59:04 -05:00
|
|
|
def send_join(self, destination, room_id, event_id, content):
|
|
|
|
path = PREFIX + "/send_join/%s/%s" % (room_id, event_id)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
response = yield self.client.put_json(
|
2015-01-16 08:21:14 -05:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(response)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2015-10-20 06:58:58 -04:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
|
|
|
def send_leave(self, destination, room_id, event_id, content):
|
|
|
|
path = PREFIX + "/send_leave/%s/%s" % (room_id, event_id)
|
|
|
|
|
|
|
|
response = yield self.client.put_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
2017-04-20 20:50:36 -04:00
|
|
|
|
|
|
|
# we want to do our best to send this through. The problem is
|
|
|
|
# that if it fails, we won't retry it later, so if the remote
|
|
|
|
# server was just having a momentary blip, the room will be out of
|
|
|
|
# sync.
|
|
|
|
ignore_backoff=True,
|
2015-10-20 06:58:58 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
defer.returnValue(response)
|
|
|
|
|
2015-01-16 08:21:14 -05:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2015-01-16 13:59:04 -05:00
|
|
|
def send_invite(self, destination, room_id, event_id, content):
|
|
|
|
path = PREFIX + "/invite/%s/%s" % (room_id, event_id)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
response = yield self.client.put_json(
|
2015-01-16 08:21:14 -05:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
2017-03-23 07:10:36 -04:00
|
|
|
ignore_backoff=True,
|
2015-01-16 08:21:14 -05:00
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(response)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2016-05-31 12:20:07 -04:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2016-09-16 05:24:15 -04:00
|
|
|
def get_public_rooms(self, remote_server, limit, since_token,
|
2016-12-06 05:43:48 -05:00
|
|
|
search_filter=None, include_all_networks=False,
|
|
|
|
third_party_instance_id=None):
|
2016-05-31 12:20:07 -04:00
|
|
|
path = PREFIX + "/publicRooms"
|
|
|
|
|
2016-12-06 05:43:48 -05:00
|
|
|
args = {
|
|
|
|
"include_all_networks": "true" if include_all_networks else "false",
|
|
|
|
}
|
|
|
|
if third_party_instance_id:
|
|
|
|
args["third_party_instance_id"] = third_party_instance_id,
|
2016-09-15 05:36:19 -04:00
|
|
|
if limit:
|
|
|
|
args["limit"] = [str(limit)]
|
|
|
|
if since_token:
|
|
|
|
args["since"] = [since_token]
|
|
|
|
|
2016-09-16 05:24:15 -04:00
|
|
|
# TODO(erikj): Actually send the search_filter across federation.
|
|
|
|
|
2016-05-31 12:20:07 -04:00
|
|
|
response = yield self.client.get_json(
|
|
|
|
destination=remote_server,
|
|
|
|
path=path,
|
2016-09-15 05:36:19 -04:00
|
|
|
args=args,
|
2017-03-23 07:10:36 -04:00
|
|
|
ignore_backoff=True,
|
2016-05-31 12:20:07 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
defer.returnValue(response)
|
|
|
|
|
2015-11-05 11:43:19 -05:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
|
|
|
def exchange_third_party_invite(self, destination, room_id, event_dict):
|
|
|
|
path = PREFIX + "/exchange_third_party_invite/%s" % (room_id,)
|
|
|
|
|
|
|
|
response = yield self.client.put_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=event_dict,
|
|
|
|
)
|
|
|
|
|
|
|
|
defer.returnValue(response)
|
|
|
|
|
2015-01-16 08:21:14 -05:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2015-01-16 13:59:04 -05:00
|
|
|
def get_event_auth(self, destination, room_id, event_id):
|
|
|
|
path = PREFIX + "/event_auth/%s/%s" % (room_id, event_id)
|
2015-01-16 08:21:14 -05:00
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
content = yield self.client.get_json(
|
2015-01-16 08:21:14 -05:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(content)
|
2015-01-29 11:50:23 -05:00
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
|
|
|
def send_query_auth(self, destination, room_id, event_id, content):
|
|
|
|
path = PREFIX + "/query_auth/%s/%s" % (room_id, event_id)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
content = yield self.client.post_json(
|
2015-01-29 11:50:23 -05:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
)
|
|
|
|
|
2015-02-04 11:28:12 -05:00
|
|
|
defer.returnValue(content)
|
2015-02-23 08:58:02 -05:00
|
|
|
|
2015-07-23 11:03:38 -04:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2016-09-12 13:17:09 -04:00
|
|
|
def query_client_keys(self, destination, query_content, timeout):
|
2015-07-23 11:03:38 -04:00
|
|
|
"""Query the device keys for a list of user ids hosted on a remote
|
|
|
|
server.
|
|
|
|
|
|
|
|
Request:
|
|
|
|
{
|
|
|
|
"device_keys": {
|
|
|
|
"<user_id>": ["<device_id>"]
|
|
|
|
} }
|
|
|
|
|
|
|
|
Response:
|
|
|
|
{
|
|
|
|
"device_keys": {
|
|
|
|
"<user_id>": {
|
|
|
|
"<device_id>": {...}
|
|
|
|
} } }
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination(str): The server to query.
|
|
|
|
query_content(dict): The user ids to query.
|
|
|
|
Returns:
|
|
|
|
A dict containg the device keys.
|
|
|
|
"""
|
2015-07-24 13:26:46 -04:00
|
|
|
path = PREFIX + "/user/keys/query"
|
2015-07-23 11:03:38 -04:00
|
|
|
|
|
|
|
content = yield self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=query_content,
|
2016-09-12 13:17:09 -04:00
|
|
|
timeout=timeout,
|
2015-07-23 11:03:38 -04:00
|
|
|
)
|
|
|
|
defer.returnValue(content)
|
|
|
|
|
2017-01-26 11:06:54 -05:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
|
|
|
def query_user_devices(self, destination, user_id, timeout):
|
|
|
|
"""Query the devices for a user id hosted on a remote server.
|
|
|
|
|
|
|
|
Response:
|
|
|
|
{
|
|
|
|
"stream_id": "...",
|
|
|
|
"devices": [ { ... } ]
|
|
|
|
}
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination(str): The server to query.
|
|
|
|
query_content(dict): The user ids to query.
|
|
|
|
Returns:
|
|
|
|
A dict containg the device keys.
|
|
|
|
"""
|
|
|
|
path = PREFIX + "/user/devices/" + user_id
|
|
|
|
|
|
|
|
content = yield self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
timeout=timeout,
|
|
|
|
)
|
|
|
|
defer.returnValue(content)
|
|
|
|
|
2015-07-23 11:03:38 -04:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
2016-09-12 13:17:09 -04:00
|
|
|
def claim_client_keys(self, destination, query_content, timeout):
|
2015-07-23 11:03:38 -04:00
|
|
|
"""Claim one-time keys for a list of devices hosted on a remote server.
|
|
|
|
|
|
|
|
Request:
|
|
|
|
{
|
|
|
|
"one_time_keys": {
|
|
|
|
"<user_id>": {
|
|
|
|
"<device_id>": "<algorithm>"
|
|
|
|
} } }
|
|
|
|
|
|
|
|
Response:
|
|
|
|
{
|
|
|
|
"device_keys": {
|
|
|
|
"<user_id>": {
|
|
|
|
"<device_id>": {
|
|
|
|
"<algorithm>:<key_id>": "<key_base64>"
|
|
|
|
} } } }
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination(str): The server to query.
|
|
|
|
query_content(dict): The user ids to query.
|
|
|
|
Returns:
|
|
|
|
A dict containg the one-time keys.
|
|
|
|
"""
|
|
|
|
|
2015-07-24 13:26:46 -04:00
|
|
|
path = PREFIX + "/user/keys/claim"
|
2015-07-23 11:03:38 -04:00
|
|
|
|
|
|
|
content = yield self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=query_content,
|
2016-09-12 13:17:09 -04:00
|
|
|
timeout=timeout,
|
2015-07-23 11:03:38 -04:00
|
|
|
)
|
|
|
|
defer.returnValue(content)
|
|
|
|
|
2015-02-23 08:58:02 -05:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
@log_function
|
|
|
|
def get_missing_events(self, destination, room_id, earliest_events,
|
2016-12-31 10:21:37 -05:00
|
|
|
latest_events, limit, min_depth, timeout):
|
2015-02-23 08:58:02 -05:00
|
|
|
path = PREFIX + "/get_missing_events/%s" % (room_id,)
|
|
|
|
|
|
|
|
content = yield self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data={
|
|
|
|
"limit": int(limit),
|
|
|
|
"min_depth": int(min_depth),
|
|
|
|
"earliest_events": earliest_events,
|
|
|
|
"latest_events": latest_events,
|
2016-12-31 10:21:37 -05:00
|
|
|
},
|
|
|
|
timeout=timeout,
|
2015-02-23 08:58:02 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
defer.returnValue(content)
|
2017-07-10 10:44:15 -04:00
|
|
|
|
2017-07-10 09:52:27 -04:00
|
|
|
@log_function
|
|
|
|
def get_group_profile(self, destination, group_id, requester_user_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get a group profile
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/profile" % (group_id,)
|
|
|
|
|
2017-07-18 09:37:06 -04:00
|
|
|
return self.client.get_json(
|
2017-07-10 09:52:27 -04:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-07-18 09:37:06 -04:00
|
|
|
args={"requester_user_id": requester_user_id},
|
2017-07-10 09:52:27 -04:00
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-10-23 10:19:28 -04:00
|
|
|
@log_function
|
|
|
|
def update_group_profile(self, destination, group_id, requester_user_id, content):
|
|
|
|
"""Update a remote group profile
|
|
|
|
|
|
|
|
Args:
|
|
|
|
destination (str)
|
|
|
|
group_id (str)
|
|
|
|
requester_user_id (str)
|
|
|
|
content (dict): The new profile of the group
|
|
|
|
"""
|
|
|
|
path = PREFIX + "/groups/%s/profile" % (group_id,)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-07-10 09:52:27 -04:00
|
|
|
@log_function
|
|
|
|
def get_group_summary(self, destination, group_id, requester_user_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get a group summary
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/summary" % (group_id,)
|
|
|
|
|
2017-07-18 09:37:06 -04:00
|
|
|
return self.client.get_json(
|
2017-07-10 09:52:27 -04:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-07-18 09:37:06 -04:00
|
|
|
args={"requester_user_id": requester_user_id},
|
2017-07-10 09:52:27 -04:00
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
2017-07-18 11:38:54 -04:00
|
|
|
def get_rooms_in_group(self, destination, group_id, requester_user_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get all rooms in a group
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/rooms" % (group_id,)
|
|
|
|
|
2017-07-18 09:37:06 -04:00
|
|
|
return self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-11-08 10:43:34 -05:00
|
|
|
def add_room_to_group(self, destination, group_id, requester_user_id, room_id,
|
|
|
|
content):
|
|
|
|
"""Add a room to a group
|
2017-07-18 12:19:39 -04:00
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/room/%s" % (group_id, room_id,)
|
|
|
|
|
2017-07-10 09:52:27 -04:00
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-07-18 09:37:06 -04:00
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
2017-07-10 09:52:27 -04:00
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-11-08 11:13:27 -05:00
|
|
|
def update_room_in_group(self, destination, group_id, requester_user_id, room_id,
|
|
|
|
config_key, content):
|
|
|
|
"""Update room in group
|
|
|
|
"""
|
|
|
|
path = PREFIX + "/groups/%s/room/%s/config/%s" % (group_id, room_id, config_key,)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-11-08 10:43:34 -05:00
|
|
|
def remove_room_from_group(self, destination, group_id, requester_user_id, room_id):
|
2017-09-26 10:52:41 -04:00
|
|
|
"""Remove a room from a group
|
|
|
|
"""
|
|
|
|
path = PREFIX + "/groups/%s/room/%s" % (group_id, room_id,)
|
|
|
|
|
|
|
|
return self.client.delete_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-07-10 09:52:27 -04:00
|
|
|
@log_function
|
2017-07-18 11:38:54 -04:00
|
|
|
def get_users_in_group(self, destination, group_id, requester_user_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get users in a group
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/users" % (group_id,)
|
|
|
|
|
2017-07-18 09:37:06 -04:00
|
|
|
return self.client.get_json(
|
2017-07-10 09:52:27 -04:00
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-07-18 09:37:06 -04:00
|
|
|
args={"requester_user_id": requester_user_id},
|
2017-07-10 09:52:27 -04:00
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-10-16 10:31:11 -04:00
|
|
|
@log_function
|
|
|
|
def get_invited_users_in_group(self, destination, group_id, requester_user_id):
|
|
|
|
"""Get users that have been invited to a group
|
|
|
|
"""
|
|
|
|
path = PREFIX + "/groups/%s/invited_users" % (group_id,)
|
|
|
|
|
|
|
|
return self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-07-10 09:52:27 -04:00
|
|
|
@log_function
|
|
|
|
def accept_group_invite(self, destination, group_id, user_id, content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Accept a group invite
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/users/%s/accept_invite" % (group_id, user_id)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
2017-07-18 09:37:06 -04:00
|
|
|
def invite_to_group(self, destination, group_id, user_id, requester_user_id, content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Invite a user to a group
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/users/%s/invite" % (group_id, user_id)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-10-11 09:44:51 -04:00
|
|
|
args={"requester_user_id": requester_user_id},
|
2017-07-10 09:52:27 -04:00
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-07-10 10:44:15 -04:00
|
|
|
@log_function
|
|
|
|
def invite_to_group_notification(self, destination, group_id, user_id, content):
|
2017-07-11 06:52:03 -04:00
|
|
|
"""Sent by group server to inform a user's server that they have been
|
|
|
|
invited.
|
|
|
|
"""
|
|
|
|
|
2017-07-10 10:44:15 -04:00
|
|
|
path = PREFIX + "/groups/local/%s/users/%s/invite" % (group_id, user_id)
|
|
|
|
|
2017-07-10 09:52:27 -04:00
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
2017-07-18 09:37:06 -04:00
|
|
|
def remove_user_from_group(self, destination, group_id, requester_user_id,
|
|
|
|
user_id, content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Remove a user fron a group
|
|
|
|
"""
|
2017-07-10 09:52:27 -04:00
|
|
|
path = PREFIX + "/groups/%s/users/%s/remove" % (group_id, user_id)
|
|
|
|
|
2017-07-10 10:44:15 -04:00
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
2017-07-18 09:37:06 -04:00
|
|
|
args={"requester_user_id": requester_user_id},
|
2017-07-10 10:44:15 -04:00
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def remove_user_from_group_notification(self, destination, group_id, user_id,
|
|
|
|
content):
|
2017-07-11 06:52:03 -04:00
|
|
|
"""Sent by group server to inform a user's server that they have been
|
|
|
|
kicked from the group.
|
|
|
|
"""
|
|
|
|
|
2017-07-10 10:44:15 -04:00
|
|
|
path = PREFIX + "/groups/local/%s/users/%s/remove" % (group_id, user_id)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def renew_group_attestation(self, destination, group_id, user_id, content):
|
2017-07-11 06:52:03 -04:00
|
|
|
"""Sent by either a group server or a user's server to periodically update
|
|
|
|
the attestations
|
|
|
|
"""
|
|
|
|
|
2017-07-10 10:44:15 -04:00
|
|
|
path = PREFIX + "/groups/%s/renew_attestation/%s" % (group_id, user_id)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
2017-07-18 09:37:06 -04:00
|
|
|
|
|
|
|
@log_function
|
|
|
|
def update_group_summary_room(self, destination, group_id, user_id, room_id,
|
|
|
|
category_id, content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Update a room entry in a group summary
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
if category_id:
|
|
|
|
path = PREFIX + "/groups/%s/summary/categories/%s/rooms/%s" % (
|
|
|
|
group_id, category_id, room_id,
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
path = PREFIX + "/groups/%s/summary/rooms/%s" % (group_id, room_id,)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def delete_group_summary_room(self, destination, group_id, user_id, room_id,
|
|
|
|
category_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Delete a room entry in a group summary
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
if category_id:
|
|
|
|
path = PREFIX + "/groups/%s/summary/categories/%s/rooms/%s" % (
|
|
|
|
group_id, category_id, room_id,
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
path = PREFIX + "/groups/%s/summary/rooms/%s" % (group_id, room_id,)
|
|
|
|
|
|
|
|
return self.client.delete_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def get_group_categories(self, destination, group_id, requester_user_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get all categories in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/categories" % (group_id,)
|
|
|
|
|
|
|
|
return self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def get_group_category(self, destination, group_id, requester_user_id, category_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get category info in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/categories/%s" % (group_id, category_id,)
|
|
|
|
|
|
|
|
return self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def update_group_category(self, destination, group_id, requester_user_id, category_id,
|
|
|
|
content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Update a category in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/categories/%s" % (group_id, category_id,)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def delete_group_category(self, destination, group_id, requester_user_id,
|
|
|
|
category_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Delete a category in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/categories/%s" % (group_id, category_id,)
|
|
|
|
|
|
|
|
return self.client.delete_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def get_group_roles(self, destination, group_id, requester_user_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get all roles in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/roles" % (group_id,)
|
|
|
|
|
|
|
|
return self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def get_group_role(self, destination, group_id, requester_user_id, role_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Get a roles info
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/roles/%s" % (group_id, role_id,)
|
|
|
|
|
|
|
|
return self.client.get_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def update_group_role(self, destination, group_id, requester_user_id, role_id,
|
|
|
|
content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Update a role in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/roles/%s" % (group_id, role_id,)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def delete_group_role(self, destination, group_id, requester_user_id, role_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Delete a role in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
path = PREFIX + "/groups/%s/roles/%s" % (group_id, role_id,)
|
|
|
|
|
|
|
|
return self.client.delete_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
@log_function
|
|
|
|
def update_group_summary_user(self, destination, group_id, requester_user_id,
|
|
|
|
user_id, role_id, content):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Update a users entry in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
if role_id:
|
|
|
|
path = PREFIX + "/groups/%s/summary/roles/%s/users/%s" % (
|
|
|
|
group_id, role_id, user_id,
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
path = PREFIX + "/groups/%s/summary/users/%s" % (group_id, user_id,)
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2018-03-28 09:03:37 -04:00
|
|
|
@log_function
|
|
|
|
def set_group_joinable(self, destination, group_id, requester_user_id,
|
2018-03-28 09:29:42 -04:00
|
|
|
content):
|
2018-04-03 10:40:43 -04:00
|
|
|
"""Sets the join policy for a group
|
2018-03-28 09:03:37 -04:00
|
|
|
"""
|
2018-04-03 10:40:43 -04:00
|
|
|
path = PREFIX + "/groups/%s/setting/m.join_policy" % (group_id,)
|
2018-03-28 09:03:37 -04:00
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
|
|
|
|
2017-07-18 09:37:06 -04:00
|
|
|
@log_function
|
|
|
|
def delete_group_summary_user(self, destination, group_id, requester_user_id,
|
|
|
|
user_id, role_id):
|
2017-07-18 12:19:39 -04:00
|
|
|
"""Delete a users entry in a group
|
|
|
|
"""
|
2017-07-18 09:37:06 -04:00
|
|
|
if role_id:
|
|
|
|
path = PREFIX + "/groups/%s/summary/roles/%s/users/%s" % (
|
|
|
|
group_id, role_id, user_id,
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
path = PREFIX + "/groups/%s/summary/users/%s" % (group_id, user_id,)
|
|
|
|
|
|
|
|
return self.client.delete_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
args={"requester_user_id": requester_user_id},
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|
2017-08-09 08:36:22 -04:00
|
|
|
|
|
|
|
def bulk_get_publicised_groups(self, destination, user_ids):
|
|
|
|
"""Get the groups a list of users are publicising
|
|
|
|
"""
|
|
|
|
|
|
|
|
path = PREFIX + "/get_groups_publicised"
|
|
|
|
|
|
|
|
content = {"user_ids": user_ids}
|
|
|
|
|
|
|
|
return self.client.post_json(
|
|
|
|
destination=destination,
|
|
|
|
path=path,
|
|
|
|
data=content,
|
|
|
|
ignore_backoff=True,
|
|
|
|
)
|