Synapse 1.24.0rc2 (2020-12-04)

==============================
 
 Bugfixes
 --------
 
 - Fix a regression in v1.24.0rc1 which failed to allow SAML mapping providers which were unable to redirect users to an additional page. ([\#8878](https://github.com/matrix-org/synapse/issues/8878))
 
 Internal Changes
 ----------------
 
 - Add support for the `prometheus_client` newer than 0.9.0. Contributed by Jordan Bancino. ([\#8875](https://github.com/matrix-org/synapse/issues/8875))
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEF3tZXk38tRDFVnUIM/xY9qcRMEgFAl/KQ6MACgkQM/xY9qcR
 MEjqOg/9Fd4Ow0QdnK3O6J0bmXP6+g2GfjJCAKlYlF/nwX1ez9jZVed00D2h9/hD
 YCUJCEv+XZpbv5F4usiYwoLGithbueo7AKEOQJQMEuQBHU1/E6TJ9iiKR3lTBNNw
 ccuyMMqqEatYxoa4DIO/lrwm2mhwRNdMPt0r1DPlML13bb/TVbeXXykbOCyZSKm1
 YuXpxYDngRPL9o46I77l7/KNTSpYYeZi2qwp2orl6GBfa0KSvR2Oi6uohKYzuoHC
 +XLvHSFMpHAZkaZsIMxU5hRVH6jtkb/D37CABuKQsdlvHcooGK4Sdt6aoUyhPtoh
 6YwajSazWKEJ/9YO5JV22qkWFPi9T6s/lPZfjOSu/euwMw7DDQJ/8t8Sm6N7sJDS
 A/5FctOAd1jd9BiAaqkHB2zLHZSomIHQpJJfDyE3UgAGQQ6fm2Wg7SkLByDx/MYC
 4D74dBuVBPENM2VxNoyjHbpVSeQi8t0RgWb44/PUAOtpwm3f3eVRuS8zY6uR2bZr
 YZUbJylqKhRW6dBdZH+EzVolRGvBgLkc27IzRCQ3kGUEo2Wem05s6MuKMvLxoIvN
 NHLWNClUWITT8FgkfFP3c6CK40dwIGJzYryI+71qPW/R7snf2fazuoHlH1pAmFh0
 E0/nBMTw1deixOYXbG1ah63AhJ1NjdTfimDsKmWZLqVc6g7g4d4=
 =is1Y
 -----END PGP SIGNATURE-----

Merge tag 'v1.24.0rc2' into develop

Synapse 1.24.0rc2 (2020-12-04)
==============================

Bugfixes
--------

- Fix a regression in v1.24.0rc1 which failed to allow SAML mapping providers which were unable to redirect users to an additional page. ([\#8878](https://github.com/matrix-org/synapse/issues/8878))

Internal Changes
----------------

- Add support for the `prometheus_client` newer than 0.9.0. Contributed by Jordan Bancino. ([\#8875](https://github.com/matrix-org/synapse/issues/8875))
This commit is contained in:
Patrick Cloke 2020-12-04 09:14:31 -05:00
commit 112f6bd49e
9 changed files with 81 additions and 18 deletions

View File

@ -1,3 +1,18 @@
Synapse 1.24.0rc2 (2020-12-04)
==============================
Bugfixes
--------
- Fix a regression in v1.24.0rc1 which failed to allow SAML mapping providers which were unable to redirect users to an additional page. ([\#8878](https://github.com/matrix-org/synapse/issues/8878))
Internal Changes
----------------
- Add support for the `prometheus_client` newer than 0.9.0. Contributed by Jordan Bancino. ([\#8875](https://github.com/matrix-org/synapse/issues/8875))
Synapse 1.24.0rc1 (2020-12-02) Synapse 1.24.0rc1 (2020-12-02)
============================== ==============================

View File

@ -37,7 +37,7 @@ RUN pip install --prefix="/install" --no-warn-script-location \
jaeger-client \ jaeger-client \
opentracing \ opentracing \
# Match the version constraints of Synapse # Match the version constraints of Synapse
"prometheus_client>=0.4.0,<0.9.0" \ "prometheus_client>=0.4.0" \
psycopg2 \ psycopg2 \
pycparser \ pycparser \
pyrsistent \ pyrsistent \

View File

@ -171,6 +171,13 @@ A custom mapping provider must specify the following methods:
* `emails` - A list of emails for the new user. If not provided, will * `emails` - A list of emails for the new user. If not provided, will
default to an empty list. default to an empty list.
Alternatively it can raise a `synapse.api.errors.RedirectException` to
redirect the user to another page. This is useful to prompt the user for
additional information, e.g. if you want them to provide their own username.
It is the responsibility of the mapping provider to either redirect back
to `client_redirect_url` (including any additional information) or to
complete registration using methods from the `ModuleApi`.
### Default SAML Mapping Provider ### Default SAML Mapping Provider
Synapse has a built-in SAML mapping provider if a custom provider isn't Synapse has a built-in SAML mapping provider if a custom provider isn't

View File

@ -48,7 +48,7 @@ try:
except ImportError: except ImportError:
pass pass
__version__ = "1.24.0rc1" __version__ = "1.24.0rc2"
if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)): if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)):
# We import here so that we don't have to install a bunch of deps when # We import here so that we don't have to install a bunch of deps when

View File

@ -888,7 +888,7 @@ class OidcHandler(BaseHandler):
# continue to already be in use. Note that the error raised is # continue to already be in use. Note that the error raised is
# arbitrary and will get turned into a MappingException. # arbitrary and will get turned into a MappingException.
if failures: if failures:
raise RuntimeError( raise MappingException(
"Mapping provider does not support de-duplicating Matrix IDs" "Mapping provider does not support de-duplicating Matrix IDs"
) )

View File

@ -17,6 +17,7 @@ from typing import TYPE_CHECKING, Awaitable, Callable, List, Optional
import attr import attr
from synapse.api.errors import RedirectException
from synapse.handlers._base import BaseHandler from synapse.handlers._base import BaseHandler
from synapse.http.server import respond_with_html from synapse.http.server import respond_with_html
from synapse.types import UserID, contains_invalid_mxid_characters from synapse.types import UserID, contains_invalid_mxid_characters
@ -28,7 +29,9 @@ logger = logging.getLogger(__name__)
class MappingException(Exception): class MappingException(Exception):
"""Used to catch errors when mapping the UserInfo object """Used to catch errors when mapping an SSO response to user attributes.
Note that the msg that is raised is shown to end-users.
""" """
@ -145,6 +148,14 @@ class SsoHandler(BaseHandler):
sso_to_matrix_id_mapper: A callable to generate the user attributes. sso_to_matrix_id_mapper: A callable to generate the user attributes.
The only parameter is an integer which represents the amount of The only parameter is an integer which represents the amount of
times the returned mxid localpart mapping has failed. times the returned mxid localpart mapping has failed.
It is expected that the mapper can raise two exceptions, which
will get passed through to the caller:
MappingException if there was a problem mapping the response
to the user.
RedirectException to redirect to an additional page (e.g.
to prompt the user for more information).
grandfather_existing_users: A callable which can return an previously grandfather_existing_users: A callable which can return an previously
existing matrix ID. The SSO ID is then linked to the returned existing matrix ID. The SSO ID is then linked to the returned
matrix ID. matrix ID.
@ -154,8 +165,8 @@ class SsoHandler(BaseHandler):
Raises: Raises:
MappingException if there was a problem mapping the response to a user. MappingException if there was a problem mapping the response to a user.
RedirectException: some mapping providers may raise this if they need RedirectException: if the mapping provider needs to redirect the user
to redirect to an interstitial page. to an additional page. (e.g. to prompt for more information)
""" """
# first of all, check if we already have a mapping for this user # first of all, check if we already have a mapping for this user
@ -179,10 +190,16 @@ class SsoHandler(BaseHandler):
for i in range(self._MAP_USERNAME_RETRIES): for i in range(self._MAP_USERNAME_RETRIES):
try: try:
attributes = await sso_to_matrix_id_mapper(i) attributes = await sso_to_matrix_id_mapper(i)
except (RedirectException, MappingException):
# Mapping providers are allowed to issue a redirect (e.g. to ask
# the user for more information) and can issue a mapping exception
# if a name cannot be generated.
raise
except Exception as e: except Exception as e:
# Any other exception is unexpected.
raise MappingException( raise MappingException(
"Could not extract user attributes from SSO response: " + str(e) "Could not extract user attributes from SSO response."
) ) from e
logger.debug( logger.debug(
"Retrieved user attributes from user mapping provider: %r (attempt %d)", "Retrieved user attributes from user mapping provider: %r (attempt %d)",

View File

@ -40,6 +40,10 @@ logger = logging.getLogger(__name__)
# Note that these both represent runtime dependencies (and the versions # Note that these both represent runtime dependencies (and the versions
# installed are checked at runtime). # installed are checked at runtime).
# #
# Also note that we replicate these constraints in the Synapse Dockerfile while
# pre-installing dependencies. If these constraints are updated here, the same
# change should be made in the Dockerfile.
#
# [1] https://pip.pypa.io/en/stable/reference/pip_install/#requirement-specifiers. # [1] https://pip.pypa.io/en/stable/reference/pip_install/#requirement-specifiers.
REQUIREMENTS = [ REQUIREMENTS = [
@ -69,14 +73,7 @@ REQUIREMENTS = [
"msgpack>=0.5.2", "msgpack>=0.5.2",
"phonenumbers>=8.2.0", "phonenumbers>=8.2.0",
# we use GaugeHistogramMetric, which was added in prom-client 0.4.0. # we use GaugeHistogramMetric, which was added in prom-client 0.4.0.
# prom-client has a history of breaking backwards compatibility between "prometheus_client>=0.4.0",
# minor versions (https://github.com/prometheus/client_python/issues/317),
# so we also pin the minor version.
#
# Note that we replicate these constraints in the Synapse Dockerfile while
# pre-installing dependencies. If these constraints are updated here, the
# same change should be made in the Dockerfile.
"prometheus_client>=0.4.0,<0.9.0",
# we use attr.validators.deep_iterable, which arrived in 19.1.0 (Note: # we use attr.validators.deep_iterable, which arrived in 19.1.0 (Note:
# Fedora 31 only has 19.1, so if we want to upgrade we should wait until 33 # Fedora 31 only has 19.1, so if we want to upgrade we should wait until 33
# is out in November.) # is out in November.)

View File

@ -690,8 +690,7 @@ class OidcHandlerTestCase(HomeserverTestCase):
MappingException, MappingException,
) )
self.assertEqual( self.assertEqual(
str(e.value), str(e.value), "Mapping provider does not support de-duplicating Matrix IDs",
"Could not extract user attributes from SSO response: Mapping provider does not support de-duplicating Matrix IDs",
) )
@override_config({"oidc_config": {"allow_existing_users": True}}) @override_config({"oidc_config": {"allow_existing_users": True}})

View File

@ -14,6 +14,7 @@
import attr import attr
from synapse.api.errors import RedirectException
from synapse.handlers.sso import MappingException from synapse.handlers.sso import MappingException
from tests.unittest import HomeserverTestCase, override_config from tests.unittest import HomeserverTestCase, override_config
@ -49,6 +50,13 @@ class TestMappingProvider:
return {"mxid_localpart": localpart, "displayname": None} return {"mxid_localpart": localpart, "displayname": None}
class TestRedirectMappingProvider(TestMappingProvider):
def saml_response_to_user_attributes(
self, saml_response, failures, client_redirect_url
):
raise RedirectException(b"https://custom-saml-redirect/")
class SamlHandlerTestCase(HomeserverTestCase): class SamlHandlerTestCase(HomeserverTestCase):
def default_config(self): def default_config(self):
config = super().default_config() config = super().default_config()
@ -166,3 +174,23 @@ class SamlHandlerTestCase(HomeserverTestCase):
self.assertEqual( self.assertEqual(
str(e.value), "Unable to generate a Matrix ID from the SSO response" str(e.value), "Unable to generate a Matrix ID from the SSO response"
) )
@override_config(
{
"saml2_config": {
"user_mapping_provider": {
"module": __name__ + ".TestRedirectMappingProvider"
},
}
}
)
def test_map_saml_response_redirect(self):
saml_response = FakeAuthnResponse({"uid": "test", "username": "test_user"})
redirect_url = ""
e = self.get_failure(
self.handler._map_saml_response_to_user(
saml_response, redirect_url, "user-agent", "10.10.10.10"
),
RedirectException,
)
self.assertEqual(e.value.location, b"https://custom-saml-redirect/")