-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add support for stable MSC2858 API #9617
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Finalise support for allowing clients to pick an SSO Identity Provider ([MSC2858](https://github.com/matrix-org/matrix-doc/pull/2858)). |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,10 +14,12 @@ | |
# limitations under the License. | ||
|
||
import logging | ||
import re | ||
from typing import TYPE_CHECKING, Awaitable, Callable, Dict, Optional | ||
|
||
from synapse.api.errors import Codes, LoginError, SynapseError | ||
from synapse.api.ratelimiting import Ratelimiter | ||
from synapse.api.urls import CLIENT_API_PREFIX | ||
from synapse.appservice import ApplicationService | ||
from synapse.handlers.sso import SsoIdentityProvider | ||
from synapse.http import get_request_uri | ||
|
@@ -94,11 +96,21 @@ def on_GET(self, request: SynapseRequest): | |
flows.append({"type": LoginRestServlet.CAS_TYPE}) | ||
|
||
if self.cas_enabled or self.saml2_enabled or self.oidc_enabled: | ||
sso_flow = {"type": LoginRestServlet.SSO_TYPE} # type: JsonDict | ||
sso_flow = { | ||
"type": LoginRestServlet.SSO_TYPE, | ||
"identity_providers": [ | ||
_get_auth_flow_dict_for_idp( | ||
idp, | ||
) | ||
for idp in self._sso_handler.get_identity_providers().values() | ||
], | ||
} # type: JsonDict | ||
|
||
if self._msc2858_enabled: | ||
# backwards-compatibility support for clients which don't | ||
# support the stable API yet | ||
sso_flow["org.matrix.msc2858.identity_providers"] = [ | ||
_get_auth_flow_dict_for_idp(idp) | ||
_get_auth_flow_dict_for_idp(idp, use_unstable_brands=True) | ||
for idp in self._sso_handler.get_identity_providers().values() | ||
] | ||
|
||
|
@@ -331,22 +343,38 @@ async def _do_jwt_login(self, login_submission: JsonDict) -> Dict[str, str]: | |
return result | ||
|
||
|
||
def _get_auth_flow_dict_for_idp(idp: SsoIdentityProvider) -> JsonDict: | ||
def _get_auth_flow_dict_for_idp( | ||
idp: SsoIdentityProvider, use_unstable_brands: bool = False | ||
) -> JsonDict: | ||
"""Return an entry for the login flow dict | ||
|
||
Returns an entry suitable for inclusion in "identity_providers" in the | ||
response to GET /_matrix/client/r0/login | ||
|
||
Args: | ||
idp: the identity provider to describe | ||
use_unstable_brands: whether we should use brand identifiers suitable | ||
for the unstable API | ||
""" | ||
e = {"id": idp.idp_id, "name": idp.idp_name} # type: JsonDict | ||
if idp.idp_icon: | ||
e["icon"] = idp.idp_icon | ||
if idp.idp_brand: | ||
e["brand"] = idp.idp_brand | ||
# use the stable brand identifier if the unstable identifier isn't defined. | ||
if use_unstable_brands and idp.unstable_idp_brand: | ||
e["brand"] = idp.unstable_idp_brand | ||
return e | ||
|
||
|
||
class SsoRedirectServlet(RestServlet): | ||
PATTERNS = client_patterns("/login/(cas|sso)/redirect$", v1=True) | ||
PATTERNS = list(client_patterns("/login/(cas|sso)/redirect$", v1=True)) + [ | ||
re.compile( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well, good question. I think it's slightly more verbose to call client_patterns (especially with the cast to list), but I could do so. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My only argument for changing it is that if we ever added another path to all our stable endpoints this would happen automatically. (Also I think it is OK to leave it if we don't find any of the above compelling. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah. I think most of |
||
"^" | ||
+ CLIENT_API_PREFIX | ||
+ "/r0/login/sso/redirect/(?P<idp_id>[A-Za-z0-9_.~-]+)$" | ||
) | ||
] | ||
|
||
def __init__(self, hs: "HomeServer"): | ||
# make sure that the relevant handlers are instantiated, so that they | ||
|
@@ -364,7 +392,8 @@ def __init__(self, hs: "HomeServer"): | |
def register(self, http_server: HttpServer) -> None: | ||
super().register(http_server) | ||
if self._msc2858_enabled: | ||
# expose additional endpoint for MSC2858 support | ||
# expose additional endpoint for MSC2858 support: backwards-compat support | ||
# for clients which don't yet support the stable endpoints. | ||
http_server.register_paths( | ||
"GET", | ||
client_patterns( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to already be a list, we could probably update the type hint of
client_patterns
instead of casting here. 🤷There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might not be a
list
in some tests?