2019-09-25 06:33:03 -04:00
|
|
|
#
|
2023-11-21 15:29:58 -05:00
|
|
|
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
|
|
#
|
2024-01-23 06:26:48 -05:00
|
|
|
# Copyright 2019 The Matrix.org Foundation C.I.C.
|
2023-11-21 15:29:58 -05:00
|
|
|
# Copyright (C) 2023 New Vector, Ltd
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# See the GNU Affero General Public License for more details:
|
|
|
|
# <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
|
|
#
|
|
|
|
# Originally licensed under the Apache License, Version 2.0:
|
|
|
|
# <http://www.apache.org/licenses/LICENSE-2.0>.
|
|
|
|
#
|
|
|
|
# [This file includes modifications made by New Vector Limited]
|
2019-09-25 06:33:03 -04:00
|
|
|
#
|
|
|
|
#
|
2020-07-15 13:40:54 -04:00
|
|
|
|
2019-09-25 06:33:03 -04:00
|
|
|
import logging
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
from abc import ABC, abstractmethod
|
|
|
|
from typing import TYPE_CHECKING, Any, ClassVar, Sequence, Type
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
from twisted.web.client import PartialDownloadError
|
|
|
|
|
|
|
|
from synapse.api.constants import LoginType
|
|
|
|
from synapse.api.errors import Codes, LoginError, SynapseError
|
2020-08-19 07:26:03 -04:00
|
|
|
from synapse.util import json_decoder
|
2019-09-25 06:33:03 -04:00
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from synapse.server import HomeServer
|
|
|
|
|
2019-09-25 06:33:03 -04:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
class UserInteractiveAuthChecker(ABC):
|
2019-09-25 06:33:03 -04:00
|
|
|
"""Abstract base class for an interactive auth checker"""
|
|
|
|
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
# This should really be an "abstract class property", i.e. it should
|
|
|
|
# be an error to instantiate a subclass that doesn't specify an AUTH_TYPE.
|
|
|
|
# But calling this a `ClassVar` is simpler than a decorator stack of
|
|
|
|
# @property @abstractmethod and @classmethod (if that's even the right order).
|
|
|
|
AUTH_TYPE: ClassVar[str]
|
|
|
|
|
|
|
|
def __init__(self, hs: "HomeServer"): # noqa: B027
|
2019-09-25 06:33:03 -04:00
|
|
|
pass
|
|
|
|
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
@abstractmethod
|
2020-07-23 15:45:39 -04:00
|
|
|
def is_enabled(self) -> bool:
|
2019-09-25 07:10:26 -04:00
|
|
|
"""Check if the configuration of the homeserver allows this checker to work
|
|
|
|
|
|
|
|
Returns:
|
2020-07-23 15:45:39 -04:00
|
|
|
True if this login type is enabled.
|
2019-09-25 07:10:26 -04:00
|
|
|
"""
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
raise NotImplementedError()
|
2019-09-25 07:10:26 -04:00
|
|
|
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
@abstractmethod
|
2020-07-23 15:45:39 -04:00
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
2019-09-25 06:33:03 -04:00
|
|
|
"""Given the authentication dict from the client, attempt to check this step
|
|
|
|
|
|
|
|
Args:
|
2020-07-23 15:45:39 -04:00
|
|
|
authdict: authentication dictionary from the client
|
|
|
|
clientip: The IP address of the client.
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
Raises:
|
2021-08-18 08:13:35 -04:00
|
|
|
LoginError if authentication failed.
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
Returns:
|
2020-07-23 15:45:39 -04:00
|
|
|
The result of authentication (to pass back to the client?)
|
2019-09-25 06:33:03 -04:00
|
|
|
"""
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
class DummyAuthChecker(UserInteractiveAuthChecker):
|
|
|
|
AUTH_TYPE = LoginType.DUMMY
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def is_enabled(self) -> bool:
|
2019-09-25 07:10:26 -04:00
|
|
|
return True
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
2020-07-23 15:45:39 -04:00
|
|
|
return True
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
class TermsAuthChecker(UserInteractiveAuthChecker):
|
|
|
|
AUTH_TYPE = LoginType.TERMS
|
|
|
|
|
2021-09-20 08:56:23 -04:00
|
|
|
def is_enabled(self) -> bool:
|
2019-09-25 07:10:26 -04:00
|
|
|
return True
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
2020-07-23 15:45:39 -04:00
|
|
|
return True
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
class RecaptchaAuthChecker(UserInteractiveAuthChecker):
|
|
|
|
AUTH_TYPE = LoginType.RECAPTCHA
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def __init__(self, hs: "HomeServer"):
|
2019-09-25 06:33:03 -04:00
|
|
|
super().__init__(hs)
|
2021-09-23 07:13:34 -04:00
|
|
|
self._enabled = bool(hs.config.captcha.recaptcha_private_key)
|
2019-11-01 10:07:44 -04:00
|
|
|
self._http_client = hs.get_proxied_http_client()
|
2021-09-23 07:13:34 -04:00
|
|
|
self._url = hs.config.captcha.recaptcha_siteverify_api
|
|
|
|
self._secret = hs.config.captcha.recaptcha_private_key
|
2019-09-25 06:33:03 -04:00
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def is_enabled(self) -> bool:
|
2019-09-25 07:10:26 -04:00
|
|
|
return self._enabled
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
2019-09-25 06:33:03 -04:00
|
|
|
try:
|
|
|
|
user_response = authdict["response"]
|
|
|
|
except KeyError:
|
|
|
|
# Client tried to provide captcha but didn't give the parameter:
|
|
|
|
# bad request.
|
|
|
|
raise LoginError(
|
|
|
|
400, "Captcha response is required", errcode=Codes.CAPTCHA_NEEDED
|
|
|
|
)
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
"Submitting recaptcha response %s with remoteip %s", user_response, clientip
|
|
|
|
)
|
|
|
|
|
|
|
|
# TODO: get this from the homeserver rather than creating a new one for
|
|
|
|
# each request
|
|
|
|
try:
|
2022-04-11 12:07:23 -04:00
|
|
|
assert self._secret is not None
|
|
|
|
|
2020-07-23 15:45:39 -04:00
|
|
|
resp_body = await self._http_client.post_urlencoded_get_json(
|
2019-09-25 06:33:03 -04:00
|
|
|
self._url,
|
|
|
|
args={
|
|
|
|
"secret": self._secret,
|
|
|
|
"response": user_response,
|
|
|
|
"remoteip": clientip,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
except PartialDownloadError as pde:
|
|
|
|
# Twisted is silly
|
|
|
|
data = pde.response
|
2022-10-03 09:26:49 -04:00
|
|
|
# For mypy's benefit. A general Error.response is Optional[bytes], but
|
|
|
|
# a PartialDownloadError.response should be bytes AFAICS.
|
|
|
|
assert data is not None
|
2020-08-19 07:26:03 -04:00
|
|
|
resp_body = json_decoder.decode(data.decode("utf-8"))
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
if "success" in resp_body:
|
|
|
|
# Note that we do NOT check the hostname here: we explicitly
|
|
|
|
# intend the CAPTCHA to be presented by whatever client the
|
|
|
|
# user is using, we just care that they have completed a CAPTCHA.
|
|
|
|
logger.info(
|
|
|
|
"%s reCAPTCHA from hostname %s",
|
|
|
|
"Successful" if resp_body["success"] else "Failed",
|
|
|
|
resp_body.get("hostname"),
|
|
|
|
)
|
|
|
|
if resp_body["success"]:
|
|
|
|
return True
|
2021-08-18 08:13:35 -04:00
|
|
|
raise LoginError(
|
|
|
|
401, "Captcha authentication failed", errcode=Codes.UNAUTHORIZED
|
|
|
|
)
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
class _BaseThreepidAuthChecker:
|
2021-04-29 07:17:28 -04:00
|
|
|
def __init__(self, hs: "HomeServer"):
|
2019-09-25 06:33:03 -04:00
|
|
|
self.hs = hs
|
2022-02-23 06:04:02 -05:00
|
|
|
self.store = hs.get_datastores().main
|
2019-09-25 06:33:03 -04:00
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
async def _check_threepid(self, medium: str, authdict: dict) -> dict:
|
2019-09-25 06:33:03 -04:00
|
|
|
if "threepid_creds" not in authdict:
|
|
|
|
raise LoginError(400, "Missing threepid_creds", Codes.MISSING_PARAM)
|
|
|
|
|
|
|
|
threepid_creds = authdict["threepid_creds"]
|
|
|
|
|
2020-10-09 07:24:34 -04:00
|
|
|
identity_handler = self.hs.get_identity_handler()
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
|
2019-09-25 07:29:35 -04:00
|
|
|
|
2022-08-23 07:40:00 -04:00
|
|
|
# msisdns are currently always verified via the IS
|
2019-09-25 07:29:35 -04:00
|
|
|
if medium == "msisdn":
|
2021-10-04 07:18:54 -04:00
|
|
|
if not self.hs.config.registration.account_threepid_delegate_msisdn:
|
2019-09-25 07:29:35 -04:00
|
|
|
raise SynapseError(
|
|
|
|
400, "Phone number verification is not enabled on this homeserver"
|
|
|
|
)
|
2020-05-26 13:46:22 -04:00
|
|
|
threepid = await identity_handler.threepid_from_creds(
|
2021-10-04 07:18:54 -04:00
|
|
|
self.hs.config.registration.account_threepid_delegate_msisdn,
|
|
|
|
threepid_creds,
|
2019-09-25 07:29:35 -04:00
|
|
|
)
|
|
|
|
elif medium == "email":
|
2022-08-23 07:40:00 -04:00
|
|
|
if self.hs.config.email.can_verify_email:
|
2019-09-25 07:29:35 -04:00
|
|
|
threepid = None
|
2020-05-26 13:46:22 -04:00
|
|
|
row = await self.store.get_threepid_validation_session(
|
2019-09-25 07:29:35 -04:00
|
|
|
medium,
|
|
|
|
threepid_creds["client_secret"],
|
|
|
|
sid=threepid_creds["sid"],
|
|
|
|
validated=True,
|
2019-09-25 06:33:03 -04:00
|
|
|
)
|
|
|
|
|
2019-09-25 07:29:35 -04:00
|
|
|
if row:
|
|
|
|
threepid = {
|
2023-10-26 15:12:28 -04:00
|
|
|
"medium": row.medium,
|
|
|
|
"address": row.address,
|
|
|
|
"validated_at": row.validated_at,
|
2019-09-25 07:29:35 -04:00
|
|
|
}
|
2019-09-25 06:33:03 -04:00
|
|
|
|
2019-09-25 07:29:35 -04:00
|
|
|
# Valid threepid returned, delete from the db
|
2020-05-26 13:46:22 -04:00
|
|
|
await self.store.delete_threepid_session(threepid_creds["sid"])
|
2019-09-25 07:29:35 -04:00
|
|
|
else:
|
|
|
|
raise SynapseError(
|
|
|
|
400, "Email address verification is not enabled on this homeserver"
|
|
|
|
)
|
2019-09-25 06:33:03 -04:00
|
|
|
else:
|
2019-09-25 07:29:35 -04:00
|
|
|
# this can't happen!
|
|
|
|
raise AssertionError("Unrecognized threepid medium: %s" % (medium,))
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
if not threepid:
|
2021-08-18 08:13:35 -04:00
|
|
|
raise LoginError(
|
|
|
|
401, "Unable to get validated threepid", errcode=Codes.UNAUTHORIZED
|
|
|
|
)
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
if threepid["medium"] != medium:
|
|
|
|
raise LoginError(
|
|
|
|
401,
|
|
|
|
"Expecting threepid of type '%s', got '%s'"
|
|
|
|
% (medium, threepid["medium"]),
|
|
|
|
errcode=Codes.UNAUTHORIZED,
|
|
|
|
)
|
|
|
|
|
|
|
|
threepid["threepid_creds"] = authdict["threepid_creds"]
|
|
|
|
|
|
|
|
return threepid
|
|
|
|
|
|
|
|
|
|
|
|
class EmailIdentityAuthChecker(UserInteractiveAuthChecker, _BaseThreepidAuthChecker):
|
|
|
|
AUTH_TYPE = LoginType.EMAIL_IDENTITY
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def __init__(self, hs: "HomeServer"):
|
2019-09-25 06:33:03 -04:00
|
|
|
UserInteractiveAuthChecker.__init__(self, hs)
|
|
|
|
_BaseThreepidAuthChecker.__init__(self, hs)
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def is_enabled(self) -> bool:
|
2022-08-23 07:40:00 -04:00
|
|
|
return self.hs.config.email.can_verify_email
|
2019-09-25 07:10:26 -04:00
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
2020-07-23 15:45:39 -04:00
|
|
|
return await self._check_threepid("email", authdict)
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
class MsisdnAuthChecker(UserInteractiveAuthChecker, _BaseThreepidAuthChecker):
|
|
|
|
AUTH_TYPE = LoginType.MSISDN
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def __init__(self, hs: "HomeServer"):
|
2019-09-25 06:33:03 -04:00
|
|
|
UserInteractiveAuthChecker.__init__(self, hs)
|
|
|
|
_BaseThreepidAuthChecker.__init__(self, hs)
|
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
def is_enabled(self) -> bool:
|
2021-10-04 07:18:54 -04:00
|
|
|
return bool(self.hs.config.registration.account_threepid_delegate_msisdn)
|
2019-09-25 07:10:26 -04:00
|
|
|
|
2021-04-29 07:17:28 -04:00
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
2020-07-23 15:45:39 -04:00
|
|
|
return await self._check_threepid("msisdn", authdict)
|
2019-09-25 06:33:03 -04:00
|
|
|
|
|
|
|
|
2021-08-21 17:14:43 -04:00
|
|
|
class RegistrationTokenAuthChecker(UserInteractiveAuthChecker):
|
|
|
|
AUTH_TYPE = LoginType.REGISTRATION_TOKEN
|
|
|
|
|
|
|
|
def __init__(self, hs: "HomeServer"):
|
|
|
|
super().__init__(hs)
|
|
|
|
self.hs = hs
|
2022-04-27 08:57:53 -04:00
|
|
|
self._enabled = bool(
|
|
|
|
hs.config.registration.registration_requires_token
|
2022-05-05 07:11:52 -04:00
|
|
|
) or bool(hs.config.registration.enable_registration_token_3pid_bypass)
|
2022-02-23 06:04:02 -05:00
|
|
|
self.store = hs.get_datastores().main
|
2021-08-21 17:14:43 -04:00
|
|
|
|
|
|
|
def is_enabled(self) -> bool:
|
|
|
|
return self._enabled
|
|
|
|
|
|
|
|
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
|
|
|
if "token" not in authdict:
|
|
|
|
raise LoginError(400, "Missing registration token", Codes.MISSING_PARAM)
|
|
|
|
if not isinstance(authdict["token"], str):
|
|
|
|
raise LoginError(
|
|
|
|
400, "Registration token must be a string", Codes.INVALID_PARAM
|
|
|
|
)
|
|
|
|
if "session" not in authdict:
|
|
|
|
raise LoginError(400, "Missing UIA session", Codes.MISSING_PARAM)
|
|
|
|
|
|
|
|
# Get these here to avoid cyclic dependencies
|
|
|
|
from synapse.handlers.ui_auth import UIAuthSessionDataConstants
|
|
|
|
|
|
|
|
auth_handler = self.hs.get_auth_handler()
|
|
|
|
|
|
|
|
session = authdict["session"]
|
|
|
|
token = authdict["token"]
|
|
|
|
|
|
|
|
# If the LoginType.REGISTRATION_TOKEN stage has already been completed,
|
|
|
|
# return early to avoid incrementing `pending` again.
|
|
|
|
stored_token = await auth_handler.get_session_data(
|
|
|
|
session, UIAuthSessionDataConstants.REGISTRATION_TOKEN
|
|
|
|
)
|
|
|
|
if stored_token:
|
|
|
|
if token != stored_token:
|
|
|
|
raise LoginError(
|
|
|
|
400, "Registration token has changed", Codes.INVALID_PARAM
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return token
|
|
|
|
|
|
|
|
if await self.store.registration_token_is_valid(token):
|
|
|
|
# Increment pending counter, so that if token has limited uses it
|
|
|
|
# can't be used up by someone else in the meantime.
|
|
|
|
await self.store.set_registration_token_pending(token)
|
|
|
|
# Store the token in the UIA session, so that once registration
|
|
|
|
# is complete `completed` can be incremented.
|
|
|
|
await auth_handler.set_session_data(
|
|
|
|
session,
|
|
|
|
UIAuthSessionDataConstants.REGISTRATION_TOKEN,
|
|
|
|
token,
|
|
|
|
)
|
|
|
|
# The token will be stored as the result of the authentication stage
|
|
|
|
# in ui_auth_sessions_credentials. This allows the pending counter
|
|
|
|
# for tokens to be decremented when expired sessions are deleted.
|
|
|
|
return token
|
|
|
|
else:
|
|
|
|
raise LoginError(
|
|
|
|
401, "Invalid registration token", errcode=Codes.UNAUTHORIZED
|
|
|
|
)
|
|
|
|
|
|
|
|
|
Use mypy 1.0 (#15052)
* Update mypy and mypy-zope
* Remove unused ignores
These used to suppress
```
synapse/storage/engines/__init__.py:28: error: "__new__" must return a
class instance (got "NoReturn") [misc]
```
and
```
synapse/http/matrixfederationclient.py:1270: error: "BaseException" has no attribute "reasons" [attr-defined]
```
(note that we check `hasattr(e, "reasons")` above)
* Avoid empty body warnings, sometimes by marking methods as abstract
E.g.
```
tests/handlers/test_register.py:58: error: Missing return statement [empty-body]
tests/handlers/test_register.py:108: error: Missing return statement [empty-body]
```
* Suppress false positive about `JaegerConfig`
Complaint was
```
synapse/logging/opentracing.py:450: error: Function "Type[Config]" could always be true in boolean context [truthy-function]
```
* Fix not calling `is_state()`
Oops!
```
tests/rest/client/test_third_party_rules.py:428: error: Function "Callable[[], bool]" could always be true in boolean context [truthy-function]
```
* Suppress false positives from ParamSpecs
````
synapse/logging/opentracing.py:971: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
synapse/logging/opentracing.py:1017: error: Argument 2 to "_custom_sync_async_decorator" has incompatible type "Callable[[Arg(Callable[P, R], 'func'), **P], _GeneratorContextManager[None]]"; expected "Callable[[Callable[P, R], **P], _GeneratorContextManager[None]]" [arg-type]
````
* Drive-by improvement to `wrapping_logic` annotation
* Workaround false "unreachable" positives
See https://github.com/Shoobx/mypy-zope/issues/91
```
tests/http/test_proxyagent.py:626: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:762: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:826: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:838: error: Statement is unreachable [unreachable]
tests/http/test_proxyagent.py:845: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:151: error: Statement is unreachable [unreachable]
tests/http/federation/test_matrix_federation_agent.py:452: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:60: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:93: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:127: error: Statement is unreachable [unreachable]
tests/logging/test_remote_handler.py:152: error: Statement is unreachable [unreachable]
```
* Changelog
* Tweak DBAPI2 Protocol to be accepted by mypy 1.0
Some extra context in:
- https://github.com/matrix-org/python-canonicaljson/pull/57
- https://github.com/python/mypy/issues/6002
- https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected
* Pull in updated canonicaljson lib
so the protocol check just works
* Improve comments in opentracing
I tried to workaround the ignores but found it too much trouble.
I think the corresponding issue is
https://github.com/python/mypy/issues/12909. The mypy repo has a PR
claiming to fix this (https://github.com/python/mypy/pull/14677) which
might mean this gets resolved soon?
* Better annotation for INTERACTIVE_AUTH_CHECKERS
* Drive-by AUTH_TYPE annotation, to remove an ignore
2023-02-16 11:09:11 -05:00
|
|
|
INTERACTIVE_AUTH_CHECKERS: Sequence[Type[UserInteractiveAuthChecker]] = [
|
2019-09-25 06:33:03 -04:00
|
|
|
DummyAuthChecker,
|
|
|
|
TermsAuthChecker,
|
|
|
|
RecaptchaAuthChecker,
|
|
|
|
EmailIdentityAuthChecker,
|
|
|
|
MsisdnAuthChecker,
|
2021-08-21 17:14:43 -04:00
|
|
|
RegistrationTokenAuthChecker,
|
2019-09-25 06:33:03 -04:00
|
|
|
]
|
|
|
|
"""A list of UserInteractiveAuthChecker classes"""
|