diff --git a/tests/http/test_proxyagent.py b/tests/http/test_proxyagent.py
index 34df39429b..3ea8b5bec7 100644
--- a/tests/http/test_proxyagent.py
+++ b/tests/http/test_proxyagent.py
@@ -361,81 +361,41 @@ class MatrixFederationAgentTests(TestCase):
body = self.successResultOf(treq.content(resp))
self.assertEqual(body, b"result")
- @patch.dict(os.environ, {"HTTPS_PROXY": "proxy.com"})
- def test_https_request_via_uppercase_proxy_with_blacklist(self):
+ @patch.dict(os.environ, {"http_proxy": "proxy.com:8888"})
+ def test_http_request_via_proxy_with_blacklist(self):
# The blacklist includes the configured proxy IP.
agent = ProxyAgent(
BlacklistingReactorWrapper(
self.reactor, ip_whitelist=None, ip_blacklist=IPSet(["1.0.0.0/8"])
),
self.reactor,
- contextFactory=get_test_https_policy(),
use_proxy=True,
)
self.reactor.lookups["proxy.com"] = "1.2.3.5"
- d = agent.request(b"GET", b"https://test.com/abc")
+ d = agent.request(b"GET", b"http://test.com")
# there should be a pending TCP connection
clients = self.reactor.tcpClients
self.assertEqual(len(clients), 1)
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
self.assertEqual(host, "1.2.3.5")
- self.assertEqual(port, 1080)
+ self.assertEqual(port, 8888)
- # make a test HTTP server, and wire up the client
- proxy_server = self._make_connection(
+ # make a test server, and wire up the client
+ http_server = self._make_connection(
client_factory, _get_test_protocol_factory()
)
- # fish the transports back out so that we can do the old switcheroo
- s2c_transport = proxy_server.transport
- client_protocol = s2c_transport.other
- c2s_transport = client_protocol.transport
-
# the FakeTransport is async, so we need to pump the reactor
self.reactor.advance(0)
- # now there should be a pending CONNECT request
- self.assertEqual(len(proxy_server.requests), 1)
-
- request = proxy_server.requests[0]
- self.assertEqual(request.method, b"CONNECT")
- self.assertEqual(request.path, b"test.com:443")
-
- # tell the proxy server not to close the connection
- proxy_server.persistent = True
-
- # this just stops the http Request trying to do a chunked response
- # request.setHeader(b"Content-Length", b"0")
- request.finish()
-
- # now we can replace the proxy channel with a new, SSL-wrapped HTTP channel
- ssl_factory = _wrap_server_factory_for_tls(_get_test_protocol_factory())
- ssl_protocol = ssl_factory.buildProtocol(None)
- http_server = ssl_protocol.wrappedProtocol
-
- ssl_protocol.makeConnection(
- FakeTransport(client_protocol, self.reactor, ssl_protocol)
- )
- c2s_transport.other = ssl_protocol
-
- self.reactor.advance(0)
-
- server_name = ssl_protocol._tlsConnection.get_servername()
- expected_sni = b"test.com"
- self.assertEqual(
- server_name,
- expected_sni,
- "Expected SNI %s but got %s" % (expected_sni, server_name),
- )
-
# now there should be a pending request
self.assertEqual(len(http_server.requests), 1)
request = http_server.requests[0]
self.assertEqual(request.method, b"GET")
- self.assertEqual(request.path, b"/abc")
+ self.assertEqual(request.path, b"http://test.com")
self.assertEqual(request.requestHeaders.getRawHeaders(b"host"), [b"test.com"])
request.write(b"result")
request.finish()
@@ -446,8 +406,8 @@ class MatrixFederationAgentTests(TestCase):
body = self.successResultOf(treq.content(resp))
self.assertEqual(body, b"result")
- @patch.dict(os.environ, {"https_proxy": "proxy.com"})
- def test_https_request_via_proxy_with_blacklist(self):
+ @patch.dict(os.environ, {"HTTPS_PROXY": "proxy.com"})
+ def test_https_request_via_uppercase_proxy_with_blacklist(self):
# The blacklist includes the configured proxy IP.
agent = ProxyAgent(
BlacklistingReactorWrapper(
diff --git a/tests/push/test_email.py b/tests/push/test_email.py
index 22f452ec24..941cf42429 100644
--- a/tests/push/test_email.py
+++ b/tests/push/test_email.py
@@ -21,6 +21,7 @@ import pkg_resources
from twisted.internet.defer import Deferred
import synapse.rest.admin
+from synapse.api.errors import Codes, SynapseError
from synapse.rest.client.v1 import login, room
from tests.unittest import HomeserverTestCase
@@ -100,12 +101,19 @@ class EmailPusherTests(HomeserverTestCase):
user_tuple = self.get_success(
self.hs.get_datastore().get_user_by_access_token(self.access_token)
)
- token_id = user_tuple.token_id
+ self.token_id = user_tuple.token_id
+
+ # We need to add email to account before we can create a pusher.
+ self.get_success(
+ hs.get_datastore().user_add_threepid(
+ self.user_id, "email", "a@example.com", 0, 0
+ )
+ )
self.pusher = self.get_success(
self.hs.get_pusherpool().add_pusher(
user_id=self.user_id,
- access_token=token_id,
+ access_token=self.token_id,
kind="email",
app_id="m.email",
app_display_name="Email Notifications",
@@ -116,6 +124,28 @@ class EmailPusherTests(HomeserverTestCase):
)
)
+ def test_need_validated_email(self):
+ """Test that we can only add an email pusher if the user has validated
+ their email.
+ """
+ with self.assertRaises(SynapseError) as cm:
+ self.get_success_or_raise(
+ self.hs.get_pusherpool().add_pusher(
+ user_id=self.user_id,
+ access_token=self.token_id,
+ kind="email",
+ app_id="m.email",
+ app_display_name="Email Notifications",
+ device_display_name="b@example.com",
+ pushkey="b@example.com",
+ lang=None,
+ data={},
+ )
+ )
+
+ self.assertEqual(400, cm.exception.code)
+ self.assertEqual(Codes.THREEPID_NOT_FOUND, cm.exception.errcode)
+
def test_simple_sends_email(self):
# Create a simple room with two users
room = self.helper.create_room_as(self.user_id, tok=self.access_token)
diff --git a/tests/rest/client/v1/test_login.py b/tests/rest/client/v1/test_login.py
index fb29eaed6f..744d8d0941 100644
--- a/tests/rest/client/v1/test_login.py
+++ b/tests/rest/client/v1/test_login.py
@@ -15,7 +15,7 @@
import time
import urllib.parse
-from typing import Any, Dict, List, Union
+from typing import Any, Dict, List, Optional, Union
from urllib.parse import urlencode
from mock import Mock
@@ -47,8 +47,14 @@ except ImportError:
HAS_JWT = False
-# public_base_url used in some tests
-BASE_URL = "https://synapse/"
+# synapse server name: used to populate public_baseurl in some tests
+SYNAPSE_SERVER_PUBLIC_HOSTNAME = "synapse"
+
+# public_baseurl for some tests. It uses an http:// scheme because
+# FakeChannel.isSecure() returns False, so synapse will see the requested uri as
+# http://..., so using http in the public_baseurl stops Synapse trying to redirect to
+# https://....
+BASE_URL = "http://%s/" % (SYNAPSE_SERVER_PUBLIC_HOSTNAME,)
# CAS server used in some tests
CAS_SERVER = "https://fake.test"
@@ -480,11 +486,7 @@ class MultiSSOTestCase(unittest.HomeserverTestCase):
def test_multi_sso_redirect(self):
"""/login/sso/redirect should redirect to an identity picker"""
# first hit the redirect url, which should redirect to our idp picker
- channel = self.make_request(
- "GET",
- "/_matrix/client/r0/login/sso/redirect?redirectUrl="
- + urllib.parse.quote_plus(TEST_CLIENT_REDIRECT_URL),
- )
+ channel = self._make_sso_redirect_request(False, None)
self.assertEqual(channel.code, 302, channel.result)
uri = channel.headers.getRawHeaders("Location")[0]
@@ -628,34 +630,21 @@ class MultiSSOTestCase(unittest.HomeserverTestCase):
def test_client_idp_redirect_msc2858_disabled(self):
"""If the client tries to pick an IdP but MSC2858 is disabled, return a 400"""
- channel = self.make_request(
- "GET",
- "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect/oidc?redirectUrl="
- + urllib.parse.quote_plus(TEST_CLIENT_REDIRECT_URL),
- )
+ channel = self._make_sso_redirect_request(True, "oidc")
self.assertEqual(channel.code, 400, channel.result)
self.assertEqual(channel.json_body["errcode"], "M_UNRECOGNIZED")
@override_config({"experimental_features": {"msc2858_enabled": True}})
def test_client_idp_redirect_to_unknown(self):
"""If the client tries to pick an unknown IdP, return a 404"""
- channel = self.make_request(
- "GET",
- "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect/xxx?redirectUrl="
- + urllib.parse.quote_plus(TEST_CLIENT_REDIRECT_URL),
- )
+ channel = self._make_sso_redirect_request(True, "xxx")
self.assertEqual(channel.code, 404, channel.result)
self.assertEqual(channel.json_body["errcode"], "M_NOT_FOUND")
@override_config({"experimental_features": {"msc2858_enabled": True}})
def test_client_idp_redirect_to_oidc(self):
"""If the client pick a known IdP, redirect to it"""
- channel = self.make_request(
- "GET",
- "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect/oidc?redirectUrl="
- + urllib.parse.quote_plus(TEST_CLIENT_REDIRECT_URL),
- )
-
+ channel = self._make_sso_redirect_request(True, "oidc")
self.assertEqual(channel.code, 302, channel.result)
oidc_uri = channel.headers.getRawHeaders("Location")[0]
oidc_uri_path, oidc_uri_query = oidc_uri.split("?", 1)
@@ -663,6 +652,30 @@ class MultiSSOTestCase(unittest.HomeserverTestCase):
# it should redirect us to the auth page of the OIDC server
self.assertEqual(oidc_uri_path, TEST_OIDC_AUTH_ENDPOINT)
+ def _make_sso_redirect_request(
+ self, unstable_endpoint: bool = False, idp_prov: Optional[str] = None
+ ):
+ """Send a request to /_matrix/client/r0/login/sso/redirect
+
+ ... or the unstable equivalent
+
+ ... possibly specifying an IDP provider
+ """
+ endpoint = (
+ "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect"
+ if unstable_endpoint
+ else "/_matrix/client/r0/login/sso/redirect"
+ )
+ if idp_prov is not None:
+ endpoint += "/" + idp_prov
+ endpoint += "?redirectUrl=" + urllib.parse.quote_plus(TEST_CLIENT_REDIRECT_URL)
+
+ return self.make_request(
+ "GET",
+ endpoint,
+ custom_headers=[("Host", SYNAPSE_SERVER_PUBLIC_HOSTNAME)],
+ )
+
@staticmethod
def _get_value_from_macaroon(macaroon: pymacaroons.Macaroon, key: str) -> str:
prefix = key + " = "
diff --git a/tests/rest/client/v1/utils.py b/tests/rest/client/v1/utils.py
index 8231a423f3..946740aa5d 100644
--- a/tests/rest/client/v1/utils.py
+++ b/tests/rest/client/v1/utils.py
@@ -542,13 +542,30 @@ class RestHelper:
if client_redirect_url:
params["redirectUrl"] = client_redirect_url
- # hit the redirect url (which will issue a cookie and state)
+ # hit the redirect url (which should redirect back to the redirect url. This
+ # is the easiest way of figuring out what the Host header ought to be set to
+ # to keep Synapse happy.
channel = make_request(
self.hs.get_reactor(),
self.site,
"GET",
"/_matrix/client/r0/login/sso/redirect?" + urllib.parse.urlencode(params),
)
+ assert channel.code == 302
+
+ # hit the redirect url again with the right Host header, which should now issue
+ # a cookie and redirect to the SSO provider.
+ location = channel.headers.getRawHeaders("Location")[0]
+ parts = urllib.parse.urlsplit(location)
+ channel = make_request(
+ self.hs.get_reactor(),
+ self.site,
+ "GET",
+ urllib.parse.urlunsplit(("", "") + parts[2:]),
+ custom_headers=[
+ ("Host", parts[1]),
+ ],
+ )
assert channel.code == 302
channel.extract_cookies(cookies)
diff --git a/tests/rest/client/v2_alpha/test_auth.py b/tests/rest/client/v2_alpha/test_auth.py
index c26ad824f7..9734a2159a 100644
--- a/tests/rest/client/v2_alpha/test_auth.py
+++ b/tests/rest/client/v2_alpha/test_auth.py
@@ -161,7 +161,11 @@ class UIAuthTests(unittest.HomeserverTestCase):
def default_config(self):
config = super().default_config()
- config["public_baseurl"] = "https://synapse.test"
+
+ # public_baseurl uses an http:// scheme because FakeChannel.isSecure() returns
+ # False, so synapse will see the requested uri as http://..., so using http in
+ # the public_baseurl stops Synapse trying to redirect to https.
+ config["public_baseurl"] = "http://synapse.test"
if HAS_OIDC:
# we enable OIDC as a way of testing SSO flows
diff --git a/tests/server.py b/tests/server.py
index d4ece5c448..939a0008ca 100644
--- a/tests/server.py
+++ b/tests/server.py
@@ -124,7 +124,11 @@ class FakeChannel:
return address.IPv4Address("TCP", self._ip, 3423)
def getHost(self):
- return None
+ # this is called by Request.__init__ to configure Request.host.
+ return address.IPv4Address("TCP", "127.0.0.1", 8888)
+
+ def isSecure(self):
+ return False
@property
def transport(self):
|