diff --git a/synapse/handlers/groups_local.py b/synapse/handlers/groups_local.py
index 274fed9278..bfa10bde5a 100644
--- a/synapse/handlers/groups_local.py
+++ b/synapse/handlers/groups_local.py
@@ -56,6 +56,9 @@ class GroupsLocalHandler(object):
self.notifier = hs.get_notifier()
self.attestations = hs.get_groups_attestation_signing()
+ handlers = hs.get_handlers()
+ self.profile_handler = handlers.profile_handler
+
# Ensure attestations get renewed
hs.get_groups_attestation_renewer()
@@ -123,6 +126,7 @@ class GroupsLocalHandler(object):
defer.returnValue(res)
+ @defer.inlineCallbacks
def create_group(self, group_id, user_id, content):
"""Create a group
"""
@@ -130,13 +134,16 @@ class GroupsLocalHandler(object):
logger.info("Asking to create group with ID: %r", group_id)
if self.is_mine_id(group_id):
- return self.groups_server_handler.create_group(
+ res = yield self.groups_server_handler.create_group(
group_id, user_id, content
)
+ defer.returnValue(res)
- return self.transport_client.create_group(
+ content["user_profile"] = yield self.profile_handler.get_profile(user_id)
+ res = yield self.transport_client.create_group(
get_domain_from_id(group_id), group_id, user_id, content,
- ) # TODO
+ )
+ defer.returnValue(res)
@defer.inlineCallbacks
def get_users_in_group(self, group_id, requester_user_id):
@@ -265,7 +272,9 @@ class GroupsLocalHandler(object):
"groups_key", token, users=[user_id],
)
- defer.returnValue({"state": "invite"})
+ user_profile = yield self.profile_handler.get_profile(user_id)
+
+ defer.returnValue({"state": "invite", "user_profile": user_profile})
@defer.inlineCallbacks
def remove_user_from_group(self, group_id, user_id, requester_user_id, content):
diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py
index 7abee98dea..57e22edb0d 100644
--- a/synapse/handlers/profile.py
+++ b/synapse/handlers/profile.py
@@ -19,7 +19,7 @@ from twisted.internet import defer
import synapse.types
from synapse.api.errors import SynapseError, AuthError, CodeMessageException
-from synapse.types import UserID
+from synapse.types import UserID, get_domain_from_id
from ._base import BaseHandler
@@ -27,15 +27,53 @@ logger = logging.getLogger(__name__)
class ProfileHandler(BaseHandler):
+ PROFILE_UPDATE_MS = 60 * 1000
+ PROFILE_UPDATE_EVERY_MS = 24 * 60 * 60 * 1000
def __init__(self, hs):
super(ProfileHandler, self).__init__(hs)
+ self.clock = hs.get_clock()
+
self.federation = hs.get_replication_layer()
self.federation.register_query_handler(
"profile", self.on_profile_query
)
+ self.clock.looping_call(self._update_remote_profile_cache, self.PROFILE_UPDATE_MS)
+
+ @defer.inlineCallbacks
+ def get_profile(self, user_id):
+ target_user = UserID.from_string(user_id)
+ if self.hs.is_mine(target_user):
+ displayname = yield self.store.get_profile_displayname(
+ target_user.localpart
+ )
+ avatar_url = yield self.store.get_profile_avatar_url(
+ target_user.localpart
+ )
+
+ defer.returnValue({
+ "displayname": displayname,
+ "avatar_url": avatar_url,
+ })
+ else:
+ try:
+ result = yield self.federation.make_query(
+ destination=target_user.domain,
+ query_type="profile",
+ args={
+ "user_id": user_id,
+ },
+ ignore_backoff=True,
+ )
+ defer.returnValue(result)
+ except CodeMessageException as e:
+ if e.code != 404:
+ logger.exception("Failed to get displayname")
+
+ raise
+
@defer.inlineCallbacks
def get_displayname(self, target_user):
if self.hs.is_mine(target_user):
@@ -182,3 +220,44 @@ class ProfileHandler(BaseHandler):
"Failed to update join event for room %s - %s",
room_id, str(e.message)
)
+
+ def _update_remote_profile_cache(self):
+ """Called periodically to check profiles of remote users we havent'
+ checked in a while.
+ """
+ entries = yield self.store.get_remote_profile_cache_entries_that_expire(
+ last_checked=self.clock.time_msec() - self.PROFILE_UPDATE_EVERY_MS
+ )
+
+ for user_id, displayname, avatar_url in entries:
+ is_subcscribed = yield self.store.is_subscribed_remote_profile_for_user(
+ user_id,
+ )
+ if not is_subcscribed:
+ yield self.store.maybe_delete_remote_profile_cache(user_id)
+ continue
+
+ try:
+ profile = yield self.federation.make_query(
+ destination=get_domain_from_id(user_id),
+ query_type="profile",
+ args={
+ "user_id": user_id,
+ },
+ ignore_backoff=True,
+ )
+ except:
+ logger.exception("Failed to get avatar_url")
+
+ yield self.store.update_remote_profile_cache(
+ user_id, displayname, avatar_url
+ )
+ continue
+
+ new_name = profile.get("displayname")
+ new_avatar = profile.get("avatar_url")
+
+ # We always hit update to update the last_check timestamp
+ yield self.store.update_remote_profile_cache(
+ user_id, new_name, new_avatar
+ )
|