diff --git a/changelog.d/5638.bugfix b/changelog.d/5638.bugfix
new file mode 100644
index 0000000000..66781ad9e6
--- /dev/null
+++ b/changelog.d/5638.bugfix
@@ -0,0 +1 @@
+Fix requests to the `/store_invite` endpoint of identity servers being sent in the wrong format.
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index ccf99bfff2..07aea3330e 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -25,8 +25,14 @@ from twisted.internet import defer
import synapse.server
import synapse.types
from synapse.api.constants import EventTypes, Membership
-from synapse.api.errors import AuthError, Codes, ProxiedRequestError, SynapseError
from synapse.api.ratelimiting import Ratelimiter
+from synapse.api.errors import (
+ AuthError,
+ Codes,
+ ProxiedRequestError,
+ HttpResponseException,
+ SynapseError,
+)
from synapse.types import RoomID, UserID
from synapse.util.async_helpers import Linearizer
from synapse.util.distributor import user_joined_room, user_left_room
@@ -932,9 +938,23 @@ class RoomMemberHandler(object):
"sender_avatar_url": inviter_avatar_url,
}
- data = yield self.simple_http_client.post_urlencoded_get_json(
- is_url, invite_config
- )
+ try:
+ data = yield self.simple_http_client.post_json_get_json(
+ is_url, invite_config
+ )
+ except HttpResponseException as e:
+ # Some identity servers may only support application/x-www-form-urlencoded
+ # types. This is especially true with old instances of Sydent, see
+ # https://github.com/matrix-org/sydent/pull/170
+ logger.info(
+ "Failed to POST %s with JSON, falling back to urlencoded form: %s",
+ is_url,
+ e,
+ )
+ data = yield self.simple_http_client.post_urlencoded_get_json(
+ is_url, invite_config
+ )
+
# TODO: Check for success
token = data["token"]
public_keys = data.get("public_keys", [])
diff --git a/tests/rest/client/test_room_access_rules.py b/tests/rest/client/test_room_access_rules.py
index c17b0c226d..d44f5c2c8c 100644
--- a/tests/rest/client/test_room_access_rules.py
+++ b/tests/rest/client/test_room_access_rules.py
@@ -21,7 +21,6 @@ import string
from mock import Mock
from twisted.internet import defer
-
from synapse.api.constants import EventTypes, JoinRules, RoomCreationPreset
from synapse.rest import admin
from synapse.rest.client.v1 import login, room
@@ -62,7 +61,7 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
address_domain = args["address"].split("@")[1]
return defer.succeed({"hs": address_domain})
- def post_urlencoded_get_json(uri, args={}, headers=None):
+ def post_json_get_json(uri, post_json, args={}, headers=None):
token = "".join(random.choice(string.ascii_letters) for _ in range(10))
return defer.succeed(
{
@@ -84,11 +83,13 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
mock_federation_client = Mock(spec=["send_invite"])
mock_federation_client.send_invite.side_effect = send_invite
- mock_http_client = Mock(spec=["get_json", "post_urlencoded_get_json"])
+ mock_http_client = Mock(
+ spec=["get_json", "post_json_get_json"],
+ )
# Mocking the response for /info on the IS API.
mock_http_client.get_json.side_effect = get_json
# Mocking the response for /store-invite on the IS API.
- mock_http_client.post_urlencoded_get_json.side_effect = post_urlencoded_get_json
+ mock_http_client.post_json_get_json.side_effect = post_json_get_json
self.hs = self.setup_test_homeserver(
config=config,
federation_client=mock_federation_client,
|