Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 327555dddf | |||
| fba9000152 | |||
| 2eb74c6bdb | |||
| ca8906be2c | |||
| 2d97d5b1c3 | |||
| 1a7aa81715 | |||
| 5feabbdf06 | |||
| 36a5bcae2c | |||
| 8ba530c0e3 |
@@ -0,0 +1 @@
|
||||
Enabled login_via_existing_session by default.
|
||||
@@ -21,7 +21,7 @@ FROM docker.io/library/debian:bullseye-slim AS deps_base
|
||||
# which makes it much easier to copy (but we need to make sure we use an image
|
||||
# based on the same debian version as the synapse image, to make sure we get
|
||||
# the expected version of libc.
|
||||
FROM docker.io/library/redis:6-bullseye AS redis_base
|
||||
FROM docker.io/library/redis:7-bullseye AS redis_base
|
||||
|
||||
# now build the final image, based on the the regular Synapse docker image
|
||||
FROM $FROM
|
||||
|
||||
@@ -2598,14 +2598,11 @@ ui_auth:
|
||||
Matrix supports the ability of an existing session to mint a login token for
|
||||
another client.
|
||||
|
||||
Synapse disables this by default as it has security ramifications -- a malicious
|
||||
client could use the mechanism to spawn more than one session.
|
||||
|
||||
The duration of time the generated token is valid for can be configured with the
|
||||
`token_timeout` sub-option.
|
||||
|
||||
User-interactive authentication is required when this is enabled unless the
|
||||
`require_ui_auth` sub-option is set to `False`.
|
||||
To protect against malicious clients abusing this capability, user-interactive authentication
|
||||
is required unless the `require_ui_auth` sub-option is set to `False`.
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
|
||||
Generated
+24
-23
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
@@ -867,14 +867,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "6.1.0"
|
||||
version = "6.6.0"
|
||||
description = "Read metadata from Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "importlib_metadata-6.1.0-py3-none-any.whl", hash = "sha256:ff80f3b5394912eb1b108fcfd444dc78b7f1f3e16b16188054bd01cb9cb86f09"},
|
||||
{file = "importlib_metadata-6.1.0.tar.gz", hash = "sha256:43ce9281e097583d758c2c708c4376371261a02c34682491a8e98352365aad20"},
|
||||
{file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"},
|
||||
{file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1863,14 +1863,14 @@ psycopg2 = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.4.8"
|
||||
description = "ASN.1 types and codecs"
|
||||
version = "0.5.0"
|
||||
description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||
files = [
|
||||
{file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
|
||||
{file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
|
||||
{file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"},
|
||||
{file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2397,19 +2397,19 @@ doc = ["Sphinx", "sphinx-rtd-theme"]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "1.22.1"
|
||||
version = "1.25.0"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
category = "main"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "sentry-sdk-1.22.1.tar.gz", hash = "sha256:052dff5069c6f0d836ee014323576824a9b40836fc003fb12489a1f19c60a3c9"},
|
||||
{file = "sentry_sdk-1.22.1-py2.py3-none-any.whl", hash = "sha256:c6c6946f8c927adb00af1c5ab6921df38775b2199b9003816d5935a1310352d5"},
|
||||
{file = "sentry-sdk-1.25.0.tar.gz", hash = "sha256:5be3296fc574fa8a4d9b213b4dcf8c8d0246c08f8bd78315c6286f386c37555a"},
|
||||
{file = "sentry_sdk-1.25.0-py2.py3-none-any.whl", hash = "sha256:fe85cf5d0b3d0aa3480df689f9f6dc487de783defb0a95043368375dc893645e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = "*"
|
||||
urllib3 = {version = ">=1.26.11,<2.0.0", markers = "python_version >= \"3.6\""}
|
||||
urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""}
|
||||
|
||||
[package.extras]
|
||||
aiohttp = ["aiohttp (>=3.5)"]
|
||||
@@ -2421,10 +2421,11 @@ chalice = ["chalice (>=1.16.0)"]
|
||||
django = ["django (>=1.8)"]
|
||||
falcon = ["falcon (>=1.4)"]
|
||||
fastapi = ["fastapi (>=0.79.0)"]
|
||||
flask = ["blinker (>=1.1)", "flask (>=0.11)"]
|
||||
flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
|
||||
grpcio = ["grpcio (>=1.21.1)"]
|
||||
httpx = ["httpx (>=0.16.0)"]
|
||||
huey = ["huey (>=2)"]
|
||||
loguru = ["loguru (>=0.5)"]
|
||||
opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
|
||||
pure-eval = ["asttokens", "executing", "pure-eval"]
|
||||
pymongo = ["pymongo (>=3.1)"]
|
||||
@@ -3037,14 +3038,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "types-jsonschema"
|
||||
version = "4.17.0.7"
|
||||
version = "4.17.0.8"
|
||||
description = "Typing stubs for jsonschema"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-jsonschema-4.17.0.7.tar.gz", hash = "sha256:130e57c5f1ca755f95775d0822ad7a3907294e1461306af54baf804f317fd54c"},
|
||||
{file = "types_jsonschema-4.17.0.7-py3-none-any.whl", hash = "sha256:e129b52be6df841d97a98f087631dd558f7812eb91ff7b733c3301bd2446271b"},
|
||||
{file = "types-jsonschema-4.17.0.8.tar.gz", hash = "sha256:96a56990910f405e62de58862c0bbb3ac29ee6dba6d3d99aa0ba7f874cc547de"},
|
||||
{file = "types_jsonschema-4.17.0.8-py3-none-any.whl", hash = "sha256:f5958eb7b53217dfb5125f0412aeaef226a8a9013eac95816c95b5b523f6796b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3124,14 +3125,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "types-requests"
|
||||
version = "2.31.0.0"
|
||||
version = "2.31.0.1"
|
||||
description = "Typing stubs for requests"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-requests-2.31.0.0.tar.gz", hash = "sha256:c1c29d20ab8d84dff468d7febfe8e0cb0b4664543221b386605e14672b44ea25"},
|
||||
{file = "types_requests-2.31.0.0-py3-none-any.whl", hash = "sha256:7c5cea7940f8e92ec560bbc468f65bf684aa3dcf0554a6f8c4710f5f708dc598"},
|
||||
{file = "types-requests-2.31.0.1.tar.gz", hash = "sha256:3de667cffa123ce698591de0ad7db034a5317457a596eb0b4944e5a9d9e8d1ac"},
|
||||
{file = "types_requests-2.31.0.1-py3-none-any.whl", hash = "sha256:afb06ef8f25ba83d59a1d424bd7a5a939082f94b94e90ab5e6116bd2559deaa3"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3424,18 +3425,18 @@ docs = ["Sphinx", "repoze.sphinx.autointerface"]
|
||||
test = ["zope.i18nmessageid", "zope.testing", "zope.testrunner"]
|
||||
|
||||
[extras]
|
||||
all = ["Pympler", "authlib", "hiredis", "jaeger-client", "lxml", "matrix-synapse-ldap3", "opentracing", "psycopg2", "psycopg2cffi", "psycopg2cffi-compat", "pyicu", "pysaml2", "sentry-sdk", "txredisapi"]
|
||||
all = ["matrix-synapse-ldap3", "psycopg2", "psycopg2cffi", "psycopg2cffi-compat", "pysaml2", "authlib", "lxml", "sentry-sdk", "jaeger-client", "opentracing", "txredisapi", "hiredis", "Pympler", "pyicu"]
|
||||
cache-memory = ["Pympler"]
|
||||
jwt = ["authlib"]
|
||||
matrix-synapse-ldap3 = ["matrix-synapse-ldap3"]
|
||||
oidc = ["authlib"]
|
||||
opentracing = ["jaeger-client", "opentracing"]
|
||||
postgres = ["psycopg2", "psycopg2cffi", "psycopg2cffi-compat"]
|
||||
redis = ["hiredis", "txredisapi"]
|
||||
redis = ["txredisapi", "hiredis"]
|
||||
saml2 = ["pysaml2"]
|
||||
sentry = ["sentry-sdk"]
|
||||
systemd = ["systemd-python"]
|
||||
test = ["idna", "parameterized"]
|
||||
test = ["parameterized", "idna"]
|
||||
url-preview = ["lxml"]
|
||||
user-search = ["pyicu"]
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class AuthConfig(Config):
|
||||
|
||||
# Logging in with an existing session.
|
||||
login_via_existing = config.get("login_via_existing_session", {})
|
||||
self.login_via_existing_enabled = login_via_existing.get("enabled", False)
|
||||
self.login_via_existing_enabled = login_via_existing.get("enabled", True)
|
||||
self.login_via_existing_require_ui_auth = login_via_existing.get(
|
||||
"require_ui_auth", True
|
||||
)
|
||||
|
||||
@@ -61,6 +61,9 @@ class MSC3861OAuthDelegation(TestCase):
|
||||
**default_config("test"),
|
||||
"public_baseurl": BASE_URL,
|
||||
"enable_registration": False,
|
||||
"login_via_existing_session": {
|
||||
"enabled": False,
|
||||
},
|
||||
"experimental_features": {
|
||||
"msc3861": {
|
||||
"enabled": True,
|
||||
|
||||
@@ -115,6 +115,9 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
|
||||
config = super().default_config()
|
||||
config["public_baseurl"] = BASE_URL
|
||||
config["disable_registration"] = True
|
||||
config["login_via_existing_session"] = {
|
||||
"enabled": False,
|
||||
}
|
||||
config["experimental_features"] = {
|
||||
"msc3861": {
|
||||
"enabled": True,
|
||||
|
||||
@@ -36,8 +36,9 @@ from tests.test_utils import make_awaitable
|
||||
from tests.unittest import override_config
|
||||
|
||||
# Login flows we expect to appear in the list after the normal ones.
|
||||
ADDITIONAL_LOGIN_FLOWS = [
|
||||
ADDITIONAL_LOGIN_FLOWS: List[Dict] = [
|
||||
{"type": "m.login.application_service"},
|
||||
{"type": "m.login.token", "get_login_token": True},
|
||||
]
|
||||
|
||||
# a mock instance which the dummy auth providers delegate to, so we can see what's going
|
||||
@@ -45,6 +46,10 @@ ADDITIONAL_LOGIN_FLOWS = [
|
||||
mock_password_provider = Mock()
|
||||
|
||||
|
||||
def sort_flows(flows: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||
return sorted(flows, key=lambda f: f["type"])
|
||||
|
||||
|
||||
class LegacyPasswordOnlyAuthProvider:
|
||||
"""A legacy password_provider which only implements `check_password`."""
|
||||
|
||||
@@ -184,7 +189,10 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
def password_only_auth_provider_login_test_body(self) -> None:
|
||||
# login flows should only have m.login.password
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(flows, [{"type": "m.login.password"}] + ADDITIONAL_LOGIN_FLOWS)
|
||||
self.assertEqual(
|
||||
sort_flows(flows),
|
||||
sort_flows([{"type": "m.login.password"}] + ADDITIONAL_LOGIN_FLOWS),
|
||||
)
|
||||
|
||||
# check_password must return an awaitable
|
||||
mock_password_provider.check_password.return_value = make_awaitable(True)
|
||||
@@ -365,7 +373,7 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
"""password auth doesn't work if it's disabled across the board"""
|
||||
# login flows should be empty
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(flows, ADDITIONAL_LOGIN_FLOWS)
|
||||
self.assertEqual(sort_flows(flows), sort_flows(ADDITIONAL_LOGIN_FLOWS))
|
||||
|
||||
# login shouldn't work and should be rejected with a 400 ("unknown login type")
|
||||
channel = self._send_password_login("u", "p")
|
||||
@@ -386,9 +394,11 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
# (password must come first, because reasons)
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(
|
||||
flows,
|
||||
[{"type": "m.login.password"}, {"type": "test.login_type"}]
|
||||
+ ADDITIONAL_LOGIN_FLOWS,
|
||||
sort_flows(flows),
|
||||
sort_flows(
|
||||
[{"type": "m.login.password"}, {"type": "test.login_type"}]
|
||||
+ ADDITIONAL_LOGIN_FLOWS
|
||||
),
|
||||
)
|
||||
|
||||
# login with missing param should be rejected
|
||||
@@ -519,7 +529,10 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
self.register_user("localuser", "localpass")
|
||||
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(flows, [{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS)
|
||||
self.assertEqual(
|
||||
sort_flows(flows),
|
||||
sort_flows([{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS),
|
||||
)
|
||||
|
||||
# login shouldn't work and should be rejected with a 400 ("unknown login type")
|
||||
channel = self._send_password_login("localuser", "localpass")
|
||||
@@ -554,7 +567,10 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
self.register_user("localuser", "localpass")
|
||||
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(flows, [{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS)
|
||||
self.assertEqual(
|
||||
sort_flows(flows),
|
||||
sort_flows([{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS),
|
||||
)
|
||||
|
||||
# login shouldn't work and should be rejected with a 400 ("unknown login type")
|
||||
channel = self._send_password_login("localuser", "localpass")
|
||||
@@ -585,7 +601,10 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
self.register_user("localuser", "localpass")
|
||||
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(flows, [{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS)
|
||||
self.assertEqual(
|
||||
sort_flows(flows),
|
||||
sort_flows([{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS),
|
||||
)
|
||||
|
||||
# login shouldn't work and should be rejected with a 400 ("unknown login type")
|
||||
channel = self._send_password_login("localuser", "localpass")
|
||||
@@ -690,7 +709,10 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
self.register_user("localuser", "localpass")
|
||||
|
||||
flows = self._get_login_flows()
|
||||
self.assertEqual(flows, [{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS)
|
||||
self.assertEqual(
|
||||
sort_flows(flows),
|
||||
sort_flows([{"type": "test.login_type"}] + ADDITIONAL_LOGIN_FLOWS),
|
||||
)
|
||||
|
||||
# password login shouldn't work and should be rejected with a 400
|
||||
# ("unknown login type")
|
||||
@@ -928,7 +950,7 @@ class PasswordAuthProviderTests(unittest.HomeserverTestCase):
|
||||
self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body)
|
||||
return channel.json_body
|
||||
|
||||
def _get_login_flows(self) -> JsonDict:
|
||||
def _get_login_flows(self) -> List[JsonDict]:
|
||||
channel = self.make_request("GET", "/_matrix/client/r0/login")
|
||||
self.assertEqual(channel.code, HTTPStatus.OK, channel.result)
|
||||
return channel.json_body["flows"]
|
||||
|
||||
@@ -45,6 +45,7 @@ class JWKSTestCase(HomeserverTestCase):
|
||||
@override_config(
|
||||
{
|
||||
"disable_registration": True,
|
||||
"login_via_existing_session": {"enabled": False},
|
||||
"experimental_features": {
|
||||
"msc3861": {
|
||||
"enabled": True,
|
||||
@@ -65,6 +66,7 @@ class JWKSTestCase(HomeserverTestCase):
|
||||
@override_config(
|
||||
{
|
||||
"disable_registration": True,
|
||||
"login_via_existing_session": {"enabled": False},
|
||||
"experimental_features": {
|
||||
"msc3861": {
|
||||
"enabled": True,
|
||||
|
||||
@@ -187,6 +187,7 @@ class CapabilitiesTestCase(unittest.HomeserverTestCase):
|
||||
for room_version in details["support"]:
|
||||
self.assertTrue(room_version in KNOWN_ROOM_VERSIONS, str(room_version))
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": False}})
|
||||
def test_get_get_token_login_fields_when_disabled(self) -> None:
|
||||
"""By default login via an existing session is disabled."""
|
||||
access_token = self.get_success(
|
||||
@@ -201,7 +202,6 @@ class CapabilitiesTestCase(unittest.HomeserverTestCase):
|
||||
self.assertEqual(channel.code, HTTPStatus.OK)
|
||||
self.assertFalse(capabilities["m.get_login_token"]["enabled"])
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": True}})
|
||||
def test_get_get_token_login_fields_when_enabled(self) -> None:
|
||||
access_token = self.get_success(
|
||||
self.auth_handler.create_access_token_for_user_id(
|
||||
|
||||
@@ -446,6 +446,7 @@ class LoginRestServletTestCase(unittest.HomeserverTestCase):
|
||||
ApprovalNoticeMedium.NONE, channel.json_body["approval_notice_medium"]
|
||||
)
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": False}})
|
||||
def test_get_login_flows_with_login_via_existing_disabled(self) -> None:
|
||||
"""GET /login should return m.login.token without get_login_token"""
|
||||
channel = self.make_request("GET", "/_matrix/client/r0/login")
|
||||
@@ -454,7 +455,6 @@ class LoginRestServletTestCase(unittest.HomeserverTestCase):
|
||||
flows = {flow["type"]: flow for flow in channel.json_body["flows"]}
|
||||
self.assertNotIn("m.login.token", flows)
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": True}})
|
||||
def test_get_login_flows_with_login_via_existing_enabled(self) -> None:
|
||||
"""GET /login should return m.login.token with get_login_token true"""
|
||||
channel = self.make_request("GET", "/_matrix/client/r0/login")
|
||||
|
||||
@@ -46,6 +46,7 @@ class LoginTokenRequestServletTestCase(unittest.HomeserverTestCase):
|
||||
self.user = "user123"
|
||||
self.password = "password"
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": False}})
|
||||
def test_disabled(self) -> None:
|
||||
channel = self.make_request("POST", GET_TOKEN_ENDPOINT, {}, access_token=None)
|
||||
self.assertEqual(channel.code, 404)
|
||||
@@ -56,12 +57,10 @@ class LoginTokenRequestServletTestCase(unittest.HomeserverTestCase):
|
||||
channel = self.make_request("POST", GET_TOKEN_ENDPOINT, {}, access_token=token)
|
||||
self.assertEqual(channel.code, 404)
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": True}})
|
||||
def test_require_auth(self) -> None:
|
||||
channel = self.make_request("POST", GET_TOKEN_ENDPOINT, {}, access_token=None)
|
||||
self.assertEqual(channel.code, 401)
|
||||
|
||||
@override_config({"login_via_existing_session": {"enabled": True}})
|
||||
def test_uia_on(self) -> None:
|
||||
user_id = self.register_user(self.user, self.password)
|
||||
token = self.login(self.user, self.password)
|
||||
@@ -95,9 +94,7 @@ class LoginTokenRequestServletTestCase(unittest.HomeserverTestCase):
|
||||
self.assertEqual(channel.code, 200, channel.result)
|
||||
self.assertEqual(channel.json_body["user_id"], user_id)
|
||||
|
||||
@override_config(
|
||||
{"login_via_existing_session": {"enabled": True, "require_ui_auth": False}}
|
||||
)
|
||||
@override_config({"login_via_existing_session": {"require_ui_auth": False}})
|
||||
def test_uia_off(self) -> None:
|
||||
user_id = self.register_user(self.user, self.password)
|
||||
token = self.login(self.user, self.password)
|
||||
@@ -119,7 +116,6 @@ class LoginTokenRequestServletTestCase(unittest.HomeserverTestCase):
|
||||
@override_config(
|
||||
{
|
||||
"login_via_existing_session": {
|
||||
"enabled": True,
|
||||
"require_ui_auth": False,
|
||||
"token_timeout": "15s",
|
||||
}
|
||||
@@ -136,7 +132,6 @@ class LoginTokenRequestServletTestCase(unittest.HomeserverTestCase):
|
||||
@override_config(
|
||||
{
|
||||
"login_via_existing_session": {
|
||||
"enabled": True,
|
||||
"require_ui_auth": False,
|
||||
"token_timeout": "15s",
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ class WellKnownTests(unittest.HomeserverTestCase):
|
||||
},
|
||||
},
|
||||
"disable_registration": True,
|
||||
"login_via_existing_session": {"enabled": False},
|
||||
}
|
||||
)
|
||||
def test_client_well_known_msc3861_oauth_delegation(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user