19
19
from synapse .api .errors import Codes , LoginError , SynapseError
20
20
from synapse .api .ratelimiting import Ratelimiter
21
21
from synapse .appservice import ApplicationService
22
- from synapse .http .server import finish_request
22
+ from synapse .handlers .sso import SsoIdentityProvider
23
+ from synapse .http .server import HttpServer , finish_request
23
24
from synapse .http .servlet import (
24
25
RestServlet ,
25
26
parse_json_object_from_request ,
@@ -60,11 +61,14 @@ def __init__(self, hs: "HomeServer"):
60
61
self .saml2_enabled = hs .config .saml2_enabled
61
62
self .cas_enabled = hs .config .cas_enabled
62
63
self .oidc_enabled = hs .config .oidc_enabled
64
+ self ._msc2858_enabled = hs .config .experimental .msc2858_enabled
63
65
64
66
self .auth = hs .get_auth ()
65
67
66
68
self .auth_handler = self .hs .get_auth_handler ()
67
69
self .registration_handler = hs .get_registration_handler ()
70
+ self ._sso_handler = hs .get_sso_handler ()
71
+
68
72
self ._well_known_builder = WellKnownBuilder (hs )
69
73
self ._address_ratelimiter = Ratelimiter (
70
74
clock = hs .get_clock (),
@@ -89,8 +93,17 @@ def on_GET(self, request: SynapseRequest):
89
93
flows .append ({"type" : LoginRestServlet .CAS_TYPE })
90
94
91
95
if self .cas_enabled or self .saml2_enabled or self .oidc_enabled :
92
- flows .append ({"type" : LoginRestServlet .SSO_TYPE })
93
- # While its valid for us to advertise this login type generally,
96
+ sso_flow = {"type" : LoginRestServlet .SSO_TYPE } # type: JsonDict
97
+
98
+ if self ._msc2858_enabled :
99
+ sso_flow ["org.matrix.msc2858.identity_providers" ] = [
100
+ _get_auth_flow_dict_for_idp (idp )
101
+ for idp in self ._sso_handler .get_identity_providers ().values ()
102
+ ]
103
+
104
+ flows .append (sso_flow )
105
+
106
+ # While it's valid for us to advertise this login type generally,
94
107
# synapse currently only gives out these tokens as part of the
95
108
# SSO login flow.
96
109
# Generally we don't want to advertise login flows that clients
@@ -311,8 +324,20 @@ async def _do_jwt_login(self, login_submission: JsonDict) -> Dict[str, str]:
311
324
return result
312
325
313
326
327
+ def _get_auth_flow_dict_for_idp (idp : SsoIdentityProvider ) -> JsonDict :
328
+ """Return an entry for the login flow dict
329
+
330
+ Returns an entry suitable for inclusion in "identity_providers" in the
331
+ response to GET /_matrix/client/r0/login
332
+ """
333
+ e = {"id" : idp .idp_id , "name" : idp .idp_name } # type: JsonDict
334
+ if idp .idp_icon :
335
+ e ["icon" ] = idp .idp_icon
336
+ return e
337
+
338
+
314
339
class SsoRedirectServlet (RestServlet ):
315
- PATTERNS = client_patterns ("/login/(cas|sso)/redirect" , v1 = True )
340
+ PATTERNS = client_patterns ("/login/(cas|sso)/redirect$ " , v1 = True )
316
341
317
342
def __init__ (self , hs : "HomeServer" ):
318
343
# make sure that the relevant handlers are instantiated, so that they
@@ -324,13 +349,31 @@ def __init__(self, hs: "HomeServer"):
324
349
if hs .config .oidc_enabled :
325
350
hs .get_oidc_handler ()
326
351
self ._sso_handler = hs .get_sso_handler ()
352
+ self ._msc2858_enabled = hs .config .experimental .msc2858_enabled
353
+
354
+ def register (self , http_server : HttpServer ) -> None :
355
+ super ().register (http_server )
356
+ if self ._msc2858_enabled :
357
+ # expose additional endpoint for MSC2858 support
358
+ http_server .register_paths (
359
+ "GET" ,
360
+ client_patterns (
361
+ "/org.matrix.msc2858/login/sso/redirect/(?P<idp_id>[A-Za-z0-9_.~-]+)$" ,
362
+ releases = (),
363
+ unstable = True ,
364
+ ),
365
+ self .on_GET ,
366
+ self .__class__ .__name__ ,
367
+ )
327
368
328
- async def on_GET (self , request : SynapseRequest ):
369
+ async def on_GET (
370
+ self , request : SynapseRequest , idp_id : Optional [str ] = None
371
+ ) -> None :
329
372
client_redirect_url = parse_string (
330
373
request , "redirectUrl" , required = True , encoding = None
331
374
)
332
375
sso_url = await self ._sso_handler .handle_redirect_request (
333
- request , client_redirect_url
376
+ request , client_redirect_url , idp_id ,
334
377
)
335
378
logger .info ("Redirecting to %s" , sso_url )
336
379
request .redirect (sso_url )
0 commit comments