Skip to content

Commit 02ebcf7

Browse files
authored
Use custom stage UIA error for MAS cross-signing reset (#17509)
Rather than 501 M_UNRECOGNISED Client side implementation at matrix-org/matrix-react-sdk#12892
1 parent cdd5979 commit 02ebcf7

File tree

5 files changed

+40
-18
lines changed

5 files changed

+40
-18
lines changed

changelog.d/17509.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve cross-signing upload when using [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) to use a custom UIA flow stage, with web fallback support.

synapse/rest/client/auth.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from synapse.api.constants import LoginType
2828
from synapse.api.errors import LoginError, SynapseError
2929
from synapse.api.urls import CLIENT_API_PREFIX
30-
from synapse.http.server import HttpServer, respond_with_html
30+
from synapse.http.server import HttpServer, respond_with_html, respond_with_redirect
3131
from synapse.http.servlet import RestServlet, parse_string
3232
from synapse.http.site import SynapseRequest
3333

@@ -66,6 +66,17 @@ async def on_GET(self, request: SynapseRequest, stagetype: str) -> None:
6666
if not session:
6767
raise SynapseError(400, "No session supplied")
6868

69+
if (
70+
self.hs.config.experimental.msc3861.enabled
71+
and stagetype == "org.matrix.cross_signing_reset"
72+
):
73+
config = self.hs.config.experimental.msc3861
74+
if config.account_management_url is not None:
75+
url = f"{config.account_management_url}?action=org.matrix.cross_signing_reset"
76+
else:
77+
url = config.issuer
78+
respond_with_redirect(request, str.encode(url))
79+
6980
if stagetype == LoginType.RECAPTCHA:
7081
html = self.recaptcha_template.render(
7182
session=session,

synapse/rest/client/keys.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@
2323
import logging
2424
import re
2525
from collections import Counter
26-
from http import HTTPStatus
2726
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
2827

29-
from synapse.api.errors import Codes, InvalidAPICallError, SynapseError
28+
from synapse.api.errors import (
29+
InteractiveAuthIncompleteError,
30+
InvalidAPICallError,
31+
SynapseError,
32+
)
3033
from synapse.http.server import HttpServer
3134
from synapse.http.servlet import (
3235
RestServlet,
@@ -409,11 +412,24 @@ async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
409412
else:
410413
url = config.issuer
411414

412-
raise SynapseError(
413-
HTTPStatus.NOT_IMPLEMENTED,
414-
"To reset your end-to-end encryption cross-signing identity, "
415-
f"you first need to approve it at {url} and then try again.",
416-
Codes.UNRECOGNIZED,
415+
# We use a dummy session ID as this isn't really a UIA flow, but we
416+
# reuse the same API shape for better client compatibility.
417+
raise InteractiveAuthIncompleteError(
418+
"dummy",
419+
{
420+
"session": "dummy",
421+
"flows": [
422+
{"stages": ["org.matrix.cross_signing_reset"]},
423+
],
424+
"params": {
425+
"org.matrix.cross_signing_reset": {
426+
"url": url,
427+
},
428+
},
429+
"msg": "To reset your end-to-end encryption cross-signing "
430+
f"identity, you first need to approve it at {url} and "
431+
"then try again.",
432+
},
417433
)
418434
else:
419435
# Without MSC3861, we require UIA.

tests/handlers/test_oauth_delegation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ def test_cross_signing(self) -> None:
550550
access_token="mockAccessToken",
551551
)
552552

553-
self.assertEqual(channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body)
553+
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
554554

555555
def expect_unauthorized(
556556
self, method: str, path: str, content: Union[bytes, str, JsonDict] = ""

tests/rest/client/test_keys.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,7 @@ async def mocked_get_user_by_access_token(
315315
"master_key": master_key2,
316316
},
317317
)
318-
self.assertEqual(
319-
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
320-
)
318+
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
321319

322320
# Pretend that MAS did UIA and allowed us to replace the master key.
323321
channel = self.make_request(
@@ -349,9 +347,7 @@ async def mocked_get_user_by_access_token(
349347
"master_key": master_key3,
350348
},
351349
)
352-
self.assertEqual(
353-
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
354-
)
350+
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
355351

356352
# Pretend that MAS did UIA and allowed us to replace the master key.
357353
channel = self.make_request(
@@ -376,6 +372,4 @@ async def mocked_get_user_by_access_token(
376372
"master_key": master_key3,
377373
},
378374
)
379-
self.assertEqual(
380-
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
381-
)
375+
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)

0 commit comments

Comments
 (0)