From 60d8a877d08eaa6276b4317f3218dff41e7e4ad7 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 27 Oct 2016 11:02:03 +0100 Subject: [PATCH] Add federation profile endpoints --- synapse/federation/federation_client.py | 4 ++++ synapse/federation/federation_server.py | 11 +++++++++++ synapse/federation/transport/client.py | 10 ++++++++++ synapse/federation/transport/server.py | 14 ++++++++++++++ synapse/handlers/profile.py | 24 ++++++++++++++++++------ synapse/storage/profile.py | 2 +- 6 files changed, 58 insertions(+), 7 deletions(-) diff --git a/synapse/federation/federation_client.py b/synapse/federation/federation_client.py index 94e76b1978..972c1fa91a 100644 --- a/synapse/federation/federation_client.py +++ b/synapse/federation/federation_client.py @@ -878,6 +878,10 @@ class FederationClient(FederationBase): defer.returnValue(signed_events) + def get_profile(self, user_id, persona=None, key=None): + destination = get_domain_from_id(user_id) + return self.transport_layer.get_profile(destination, user_id, persona, key) + def event_from_pdu_json(self, pdu_json, outlier=False): event = FrozenEvent( pdu_json diff --git a/synapse/federation/federation_server.py b/synapse/federation/federation_server.py index 3fa7b2315c..bcfb6e4d8a 100644 --- a/synapse/federation/federation_server.py +++ b/synapse/federation/federation_server.py @@ -442,6 +442,17 @@ class FederationServer(FederationBase): "events": [ev.get_pdu_json(time_now) for ev in missing_events], }) + def on_profile_request(self, user_id, persona, key): + if not self.hs.is_mine_id(user_id): + raise SynapseError(400, "Not a local user") + + if key is not None: + return self.store.get_profile_key(user_id, persona, key) + elif persona is not None: + return self.store.get_persona_profile(user_id, persona) + else: + return self.store.get_full_profile(user_id) + @log_function def on_openid_userinfo(self, token): ts_now_ms = self._clock.time_msec() diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py index db45c7826c..51ae3a56fb 100644 --- a/synapse/federation/transport/client.py +++ b/synapse/federation/transport/client.py @@ -396,3 +396,13 @@ class TransportLayerClient(object): ) defer.returnValue(content) + + def get_profile(self, destination, user_id, persona=None, key=None): + if key: + path = PREFIX + "/profile/%s/%s/%s" % (user_id, persona, key) + elif persona: + path = PREFIX + "/profile/%s/%s/" % (user_id, persona) + else: + path = PREFIX + "/profile/%s/" % (user_id,) + + return self.client.get_json(destination, path) diff --git a/synapse/federation/transport/server.py b/synapse/federation/transport/server.py index fec337be64..103cfd4427 100644 --- a/synapse/federation/transport/server.py +++ b/synapse/federation/transport/server.py @@ -578,6 +578,19 @@ class FederationVersionServlet(BaseFederationServlet): })) +class FederationProfileServlet(BaseFederationServlet): + # This matches all three of: + # - /profile/@foo:bar/ + # - /profile/@foo:bar/default/ + # - /profile/@foo:bar/default/m.displayname + PATH = "/profile/(?P[^/]+)/((?P[^/]+)/(?P[^/]+)?)?$" + + @defer.inlineCallbacks + def on_GET(self, origin, content, query, user_id, persona, key): + profile = yield self.handler.on_profile_request(user_id, persona, key) + defer.returnValue((200, profile)) + + SERVLET_CLASSES = ( FederationSendServlet, FederationPullServlet, @@ -602,6 +615,7 @@ SERVLET_CLASSES = ( OpenIdUserInfo, PublicRoomList, FederationVersionServlet, + FederationProfileServlet, ) diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py index be8cd5545b..61649aa62e 100644 --- a/synapse/handlers/profile.py +++ b/synapse/handlers/profile.py @@ -182,15 +182,27 @@ class ProfileHandler(BaseHandler): ) def get_full_profile_for_user(self, user_id): - return self.store.get_full_profile(user_id) + if self.hs.is_mine_id(user_id): + return self.store.get_full_profile(user_id) + else: + return self.federation.get_profile(user_id) def get_persona_profile_for_user(self, user_id, persona): - return self.store.get_persona_profile(user_id, persona) + if self.hs.is_mine_id(user_id): + return self.store.get_persona_profile(user_id, persona) + else: + return self.federation.get_profile(user_id, persona) def get_profile_key_for_user(self, user_id, persona, key): - return self.store.get_profile_key(user_id, persona, key) + if self.hs.is_mine_id(user_id): + return self.store.get_profile_key(user_id, persona, key) + else: + return self.federation.get_profile(user_id, persona, key) def update_profile_key(self, user_id, persona, key, content): - return self.store.update_profile_key( - user_id, persona, key, content - ) + if self.hs.is_mine_id(user_id): + return self.store.update_profile_key( + user_id, persona, key, content + ) + else: + raise AuthError("Cannot set a remote profile") diff --git a/synapse/storage/profile.py b/synapse/storage/profile.py index caf33293a5..f0e281a483 100644 --- a/synapse/storage/profile.py +++ b/synapse/storage/profile.py @@ -74,7 +74,7 @@ class ProfileStore(SQLBaseStore): content = ujson.loads(row["content"]) personas.setdefault( row["persona"], {"rows": {}} - )["entries"][row["key"]] = content + )["rows"][row["key"]] = content defer.returnValue(profile)