mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-15 17:51:10 +00:00
Use custom stage UIA error for MAS cross-signing reset (#17509)
Rather than 501 M_UNRECOGNISED Client side implementation at https://github.com/matrix-org/matrix-react-sdk/pull/12892/
This commit is contained in:
parent
cdd5979129
commit
02ebcf7725
5 changed files with 40 additions and 18 deletions
1
changelog.d/17509.feature
Normal file
1
changelog.d/17509.feature
Normal file
|
@ -0,0 +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.
|
|
@ -27,7 +27,7 @@ from twisted.web.server import Request
|
||||||
from synapse.api.constants import LoginType
|
from synapse.api.constants import LoginType
|
||||||
from synapse.api.errors import LoginError, SynapseError
|
from synapse.api.errors import LoginError, SynapseError
|
||||||
from synapse.api.urls import CLIENT_API_PREFIX
|
from synapse.api.urls import CLIENT_API_PREFIX
|
||||||
from synapse.http.server import HttpServer, respond_with_html
|
from synapse.http.server import HttpServer, respond_with_html, respond_with_redirect
|
||||||
from synapse.http.servlet import RestServlet, parse_string
|
from synapse.http.servlet import RestServlet, parse_string
|
||||||
from synapse.http.site import SynapseRequest
|
from synapse.http.site import SynapseRequest
|
||||||
|
|
||||||
|
@ -66,6 +66,17 @@ class AuthRestServlet(RestServlet):
|
||||||
if not session:
|
if not session:
|
||||||
raise SynapseError(400, "No session supplied")
|
raise SynapseError(400, "No session supplied")
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.hs.config.experimental.msc3861.enabled
|
||||||
|
and stagetype == "org.matrix.cross_signing_reset"
|
||||||
|
):
|
||||||
|
config = self.hs.config.experimental.msc3861
|
||||||
|
if config.account_management_url is not None:
|
||||||
|
url = f"{config.account_management_url}?action=org.matrix.cross_signing_reset"
|
||||||
|
else:
|
||||||
|
url = config.issuer
|
||||||
|
respond_with_redirect(request, str.encode(url))
|
||||||
|
|
||||||
if stagetype == LoginType.RECAPTCHA:
|
if stagetype == LoginType.RECAPTCHA:
|
||||||
html = self.recaptcha_template.render(
|
html = self.recaptcha_template.render(
|
||||||
session=session,
|
session=session,
|
||||||
|
|
|
@ -23,10 +23,13 @@
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from http import HTTPStatus
|
|
||||||
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
|
||||||
|
|
||||||
from synapse.api.errors import Codes, InvalidAPICallError, SynapseError
|
from synapse.api.errors import (
|
||||||
|
InteractiveAuthIncompleteError,
|
||||||
|
InvalidAPICallError,
|
||||||
|
SynapseError,
|
||||||
|
)
|
||||||
from synapse.http.server import HttpServer
|
from synapse.http.server import HttpServer
|
||||||
from synapse.http.servlet import (
|
from synapse.http.servlet import (
|
||||||
RestServlet,
|
RestServlet,
|
||||||
|
@ -409,11 +412,24 @@ class SigningKeyUploadServlet(RestServlet):
|
||||||
else:
|
else:
|
||||||
url = config.issuer
|
url = config.issuer
|
||||||
|
|
||||||
raise SynapseError(
|
# We use a dummy session ID as this isn't really a UIA flow, but we
|
||||||
HTTPStatus.NOT_IMPLEMENTED,
|
# reuse the same API shape for better client compatibility.
|
||||||
"To reset your end-to-end encryption cross-signing identity, "
|
raise InteractiveAuthIncompleteError(
|
||||||
f"you first need to approve it at {url} and then try again.",
|
"dummy",
|
||||||
Codes.UNRECOGNIZED,
|
{
|
||||||
|
"session": "dummy",
|
||||||
|
"flows": [
|
||||||
|
{"stages": ["org.matrix.cross_signing_reset"]},
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"org.matrix.cross_signing_reset": {
|
||||||
|
"url": url,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"msg": "To reset your end-to-end encryption cross-signing "
|
||||||
|
f"identity, you first need to approve it at {url} and "
|
||||||
|
"then try again.",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Without MSC3861, we require UIA.
|
# Without MSC3861, we require UIA.
|
||||||
|
|
|
@ -550,7 +550,7 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
|
||||||
access_token="mockAccessToken",
|
access_token="mockAccessToken",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body)
|
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
|
||||||
|
|
||||||
def expect_unauthorized(
|
def expect_unauthorized(
|
||||||
self, method: str, path: str, content: Union[bytes, str, JsonDict] = ""
|
self, method: str, path: str, content: Union[bytes, str, JsonDict] = ""
|
||||||
|
|
|
@ -315,9 +315,7 @@ class SigningKeyUploadServletTestCase(unittest.HomeserverTestCase):
|
||||||
"master_key": master_key2,
|
"master_key": master_key2,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
|
||||||
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
|
|
||||||
)
|
|
||||||
|
|
||||||
# Pretend that MAS did UIA and allowed us to replace the master key.
|
# Pretend that MAS did UIA and allowed us to replace the master key.
|
||||||
channel = self.make_request(
|
channel = self.make_request(
|
||||||
|
@ -349,9 +347,7 @@ class SigningKeyUploadServletTestCase(unittest.HomeserverTestCase):
|
||||||
"master_key": master_key3,
|
"master_key": master_key3,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
|
||||||
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
|
|
||||||
)
|
|
||||||
|
|
||||||
# Pretend that MAS did UIA and allowed us to replace the master key.
|
# Pretend that MAS did UIA and allowed us to replace the master key.
|
||||||
channel = self.make_request(
|
channel = self.make_request(
|
||||||
|
@ -376,6 +372,4 @@ class SigningKeyUploadServletTestCase(unittest.HomeserverTestCase):
|
||||||
"master_key": master_key3,
|
"master_key": master_key3,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
|
||||||
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in a new issue