Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use custom stage UIA error for MAS cross-signing reset #17509

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/17509.feature
Original file line number Diff line number Diff line change
@@ -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.
13 changes: 12 additions & 1 deletion synapse/rest/client/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from synapse.api.constants import LoginType
from synapse.api.errors import LoginError, SynapseError
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.site import SynapseRequest

Expand Down Expand Up @@ -66,6 +66,17 @@ async def on_GET(self, request: SynapseRequest, stagetype: str) -> None:
if not session:
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:
html = self.recaptcha_template.render(
session=session,
Expand Down
30 changes: 23 additions & 7 deletions synapse/rest/client/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
import logging
import re
from collections import Counter
from http import HTTPStatus
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.servlet import (
RestServlet,
Expand Down Expand Up @@ -409,11 +412,24 @@ async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
else:
url = config.issuer

raise SynapseError(
HTTPStatus.NOT_IMPLEMENTED,
"To reset your end-to-end encryption cross-signing identity, "
f"you first need to approve it at {url} and then try again.",
Codes.UNRECOGNIZED,
# We use a dummy session ID as this isn't really a UIA flow, but we
# reuse the same API shape for better client compatibility.
raise InteractiveAuthIncompleteError(
"dummy",
{
"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:
# Without MSC3861, we require UIA.
Expand Down
2 changes: 1 addition & 1 deletion tests/handlers/test_oauth_delegation.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ def test_cross_signing(self) -> None:
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(
self, method: str, path: str, content: Union[bytes, str, JsonDict] = ""
Expand Down
12 changes: 3 additions & 9 deletions tests/rest/client/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,7 @@ async def mocked_get_user_by_access_token(
"master_key": master_key2,
},
)
self.assertEqual(
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
)
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)

# Pretend that MAS did UIA and allowed us to replace the master key.
channel = self.make_request(
Expand Down Expand Up @@ -349,9 +347,7 @@ async def mocked_get_user_by_access_token(
"master_key": master_key3,
},
)
self.assertEqual(
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
)
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)

# Pretend that MAS did UIA and allowed us to replace the master key.
channel = self.make_request(
Expand All @@ -376,6 +372,4 @@ async def mocked_get_user_by_access_token(
"master_key": master_key3,
},
)
self.assertEqual(
channel.code, HTTPStatus.NOT_IMPLEMENTED, channel.json_body
)
self.assertEqual(channel.code, HTTPStatus.UNAUTHORIZED, channel.json_body)
Loading