Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 41ac123

Browse files
committed
Merge commit '5c03134d0' into anoa/dinsic_release_1_21_x
* commit '5c03134d0': Convert additional database code to async/await. (#8195) Define StateMap as immutable and add a MutableStateMap type. (#8183) Move and refactor LoginRestServlet helper methods (#8182)
2 parents ff8a9a6 + 5c03134 commit 41ac123

File tree

21 files changed

+392
-262
lines changed

21 files changed

+392
-262
lines changed

changelog.d/8182.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Refactor some of `LoginRestServlet`'s helper methods, and move them to `AuthHandler` for easier reuse.

changelog.d/8183.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add type hints to `synapse.state`.

changelog.d/8195.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Convert various parts of the codebase to async/await.

synapse/appservice/__init__.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
# limitations under the License.
1515
import logging
1616
import re
17+
from typing import TYPE_CHECKING
1718

1819
from synapse.api.constants import EventTypes
20+
from synapse.appservice.api import ApplicationServiceApi
1921
from synapse.types import GroupID, get_domain_from_id
2022
from synapse.util.caches.descriptors import cached
2123

24+
if TYPE_CHECKING:
25+
from synapse.storage.databases.main import DataStore
26+
2227
logger = logging.getLogger(__name__)
2328

2429

@@ -35,30 +40,28 @@ def __init__(self, service, id, events):
3540
self.id = id
3641
self.events = events
3742

38-
def send(self, as_api):
43+
async def send(self, as_api: ApplicationServiceApi) -> bool:
3944
"""Sends this transaction using the provided AS API interface.
4045
4146
Args:
42-
as_api(ApplicationServiceApi): The API to use to send.
47+
as_api: The API to use to send.
4348
Returns:
44-
An Awaitable which resolves to True if the transaction was sent.
49+
True if the transaction was sent.
4550
"""
46-
return as_api.push_bulk(
51+
return await as_api.push_bulk(
4752
service=self.service, events=self.events, txn_id=self.id
4853
)
4954

50-
def complete(self, store):
55+
async def complete(self, store: "DataStore") -> None:
5156
"""Completes this transaction as successful.
5257
5358
Marks this transaction ID on the application service and removes the
5459
transaction contents from the database.
5560
5661
Args:
5762
store: The database store to operate on.
58-
Returns:
59-
A Deferred which resolves to True if the transaction was completed.
6063
"""
61-
return store.complete_appservice_txn(service=self.service, txn_id=self.id)
64+
await store.complete_appservice_txn(service=self.service, txn_id=self.id)
6265

6366

6467
class ApplicationService(object):

synapse/federation/persistence.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"""
2121

2222
import logging
23+
from typing import Optional, Tuple
2324

2425
from synapse.federation.units import Transaction
2526
from synapse.logging.utils import log_function
@@ -36,25 +37,27 @@ def __init__(self, datastore):
3637
self.store = datastore
3738

3839
@log_function
39-
def have_responded(self, origin, transaction):
40-
""" Have we already responded to a transaction with the same id and
40+
async def have_responded(
41+
self, origin: str, transaction: Transaction
42+
) -> Optional[Tuple[int, JsonDict]]:
43+
"""Have we already responded to a transaction with the same id and
4144
origin?
4245
4346
Returns:
44-
Deferred: Results in `None` if we have not previously responded to
45-
this transaction or a 2-tuple of `(int, dict)` representing the
46-
response code and response body.
47+
`None` if we have not previously responded to this transaction or a
48+
2-tuple of `(int, dict)` representing the response code and response body.
4749
"""
48-
if not transaction.transaction_id:
50+
transaction_id = transaction.transaction_id # type: ignore
51+
if not transaction_id:
4952
raise RuntimeError("Cannot persist a transaction with no transaction_id")
5053

51-
return self.store.get_received_txn_response(transaction.transaction_id, origin)
54+
return await self.store.get_received_txn_response(transaction_id, origin)
5255

5356
@log_function
5457
async def set_response(
5558
self, origin: str, transaction: Transaction, code: int, response: JsonDict
5659
) -> None:
57-
""" Persist how we responded to a transaction.
60+
"""Persist how we responded to a transaction.
5861
"""
5962
transaction_id = transaction.transaction_id # type: ignore
6063
if not transaction_id:

synapse/handlers/auth.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,101 @@
4242
from synapse.logging.context import defer_to_thread
4343
from synapse.metrics.background_process_metrics import run_as_background_process
4444
from synapse.module_api import ModuleApi
45-
from synapse.types import Requester, UserID
45+
from synapse.types import JsonDict, Requester, UserID
4646
from synapse.util import stringutils as stringutils
47+
from synapse.util.msisdn import phone_number_to_msisdn
4748
from synapse.util.threepids import canonicalise_email
4849

4950
from ._base import BaseHandler
5051

5152
logger = logging.getLogger(__name__)
5253

5354

55+
def convert_client_dict_legacy_fields_to_identifier(
56+
submission: JsonDict,
57+
) -> Dict[str, str]:
58+
"""
59+
Convert a legacy-formatted login submission to an identifier dict.
60+
61+
Legacy login submissions (used in both login and user-interactive authentication)
62+
provide user-identifying information at the top-level instead.
63+
64+
These are now deprecated and replaced with identifiers:
65+
https://matrix.org/docs/spec/client_server/r0.6.1#identifier-types
66+
67+
Args:
68+
submission: The client dict to convert
69+
70+
Returns:
71+
The matching identifier dict
72+
73+
Raises:
74+
SynapseError: If the format of the client dict is invalid
75+
"""
76+
identifier = submission.get("identifier", {})
77+
78+
# Generate an m.id.user identifier if "user" parameter is present
79+
user = submission.get("user")
80+
if user:
81+
identifier = {"type": "m.id.user", "user": user}
82+
83+
# Generate an m.id.thirdparty identifier if "medium" and "address" parameters are present
84+
medium = submission.get("medium")
85+
address = submission.get("address")
86+
if medium and address:
87+
identifier = {
88+
"type": "m.id.thirdparty",
89+
"medium": medium,
90+
"address": address,
91+
}
92+
93+
# We've converted valid, legacy login submissions to an identifier. If the
94+
# submission still doesn't have an identifier, it's invalid
95+
if not identifier:
96+
raise SynapseError(400, "Invalid login submission", Codes.INVALID_PARAM)
97+
98+
# Ensure the identifier has a type
99+
if "type" not in identifier:
100+
raise SynapseError(
101+
400, "'identifier' dict has no key 'type'", errcode=Codes.MISSING_PARAM,
102+
)
103+
104+
return identifier
105+
106+
107+
def login_id_phone_to_thirdparty(identifier: JsonDict) -> Dict[str, str]:
108+
"""
109+
Convert a phone login identifier type to a generic threepid identifier.
110+
111+
Args:
112+
identifier: Login identifier dict of type 'm.id.phone'
113+
114+
Returns:
115+
An equivalent m.id.thirdparty identifier dict
116+
"""
117+
if "country" not in identifier or (
118+
# The specification requires a "phone" field, while Synapse used to require a "number"
119+
# field. Accept both for backwards compatibility.
120+
"phone" not in identifier
121+
and "number" not in identifier
122+
):
123+
raise SynapseError(
124+
400, "Invalid phone-type identifier", errcode=Codes.INVALID_PARAM
125+
)
126+
127+
# Accept both "phone" and "number" as valid keys in m.id.phone
128+
phone_number = identifier.get("phone", identifier["number"])
129+
130+
# Convert user-provided phone number to a consistent representation
131+
msisdn = phone_number_to_msisdn(identifier["country"], phone_number)
132+
133+
return {
134+
"type": "m.id.thirdparty",
135+
"medium": "msisdn",
136+
"address": msisdn,
137+
}
138+
139+
54140
class AuthHandler(BaseHandler):
55141
SESSION_EXPIRE_MS = 48 * 60 * 60 * 1000
56142

synapse/handlers/federation.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@
7272
from synapse.replication.http.membership import ReplicationUserJoinedLeftRoomRestServlet
7373
from synapse.state import StateResolutionStore, resolve_events_with_store
7474
from synapse.storage.databases.main.events_worker import EventRedactBehaviour
75-
from synapse.types import JsonDict, StateMap, UserID, get_domain_from_id
75+
from synapse.types import (
76+
JsonDict,
77+
MutableStateMap,
78+
StateMap,
79+
UserID,
80+
get_domain_from_id,
81+
)
7682
from synapse.util.async_helpers import Linearizer, concurrently_execute
7783
from synapse.util.distributor import user_joined_room
7884
from synapse.util.retryutils import NotRetryingDestination
@@ -96,7 +102,7 @@ class _NewEventInfo:
96102

97103
event = attr.ib(type=EventBase)
98104
state = attr.ib(type=Optional[Sequence[EventBase]], default=None)
99-
auth_events = attr.ib(type=Optional[StateMap[EventBase]], default=None)
105+
auth_events = attr.ib(type=Optional[MutableStateMap[EventBase]], default=None)
100106

101107

102108
class FederationHandler(BaseHandler):
@@ -1883,8 +1889,8 @@ async def get_persisted_pdu(
18831889
else:
18841890
return None
18851891

1886-
def get_min_depth_for_context(self, context):
1887-
return self.store.get_min_depth(context)
1892+
async def get_min_depth_for_context(self, context):
1893+
return await self.store.get_min_depth(context)
18881894

18891895
async def _handle_new_event(
18901896
self, origin, event, state=None, auth_events=None, backfilled=False
@@ -2063,7 +2069,7 @@ async def _prep_event(
20632069
origin: str,
20642070
event: EventBase,
20652071
state: Optional[Iterable[EventBase]],
2066-
auth_events: Optional[StateMap[EventBase]],
2072+
auth_events: Optional[MutableStateMap[EventBase]],
20672073
backfilled: bool,
20682074
) -> EventContext:
20692075
context = await self.state_handler.compute_event_context(event, old_state=state)
@@ -2147,7 +2153,9 @@ async def _check_for_soft_fail(
21472153
current_states = await self.state_handler.resolve_events(
21482154
room_version, state_sets, event
21492155
)
2150-
current_state_ids = {k: e.event_id for k, e in current_states.items()}
2156+
current_state_ids = {
2157+
k: e.event_id for k, e in current_states.items()
2158+
} # type: StateMap[str]
21512159
else:
21522160
current_state_ids = await self.state_handler.get_current_state_ids(
21532161
event.room_id, latest_event_ids=extrem_ids
@@ -2233,7 +2241,7 @@ async def do_auth(
22332241
origin: str,
22342242
event: EventBase,
22352243
context: EventContext,
2236-
auth_events: StateMap[EventBase],
2244+
auth_events: MutableStateMap[EventBase],
22372245
) -> EventContext:
22382246
"""
22392247
@@ -2284,7 +2292,7 @@ async def _update_auth_events_and_context_for_auth(
22842292
origin: str,
22852293
event: EventBase,
22862294
context: EventContext,
2287-
auth_events: StateMap[EventBase],
2295+
auth_events: MutableStateMap[EventBase],
22882296
) -> EventContext:
22892297
"""Helper for do_auth. See there for docs.
22902298

synapse/handlers/room.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from synapse.storage.state import StateFilter
4242
from synapse.types import (
4343
JsonDict,
44+
MutableStateMap,
4445
Requester,
4546
RoomAlias,
4647
RoomID,
@@ -843,7 +844,7 @@ async def _send_events_for_new_room(
843844
room_id: str,
844845
preset_config: str,
845846
invite_list: List[str],
846-
initial_state: StateMap,
847+
initial_state: MutableStateMap,
847848
creation_content: JsonDict,
848849
room_alias: Optional[RoomAlias] = None,
849850
power_level_content_override: Optional[JsonDict] = None,

synapse/handlers/sync.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from synapse.types import (
3232
Collection,
3333
JsonDict,
34+
MutableStateMap,
3435
RoomStreamToken,
3536
StateMap,
3637
StreamToken,
@@ -588,7 +589,7 @@ async def compute_summary(
588589
room_id: str,
589590
sync_config: SyncConfig,
590591
batch: TimelineBatch,
591-
state: StateMap[EventBase],
592+
state: MutableStateMap[EventBase],
592593
now_token: StreamToken,
593594
) -> Optional[JsonDict]:
594595
""" Works out a room summary block for this room, summarising the number
@@ -736,7 +737,7 @@ async def compute_state_delta(
736737
since_token: Optional[StreamToken],
737738
now_token: StreamToken,
738739
full_state: bool,
739-
) -> StateMap[EventBase]:
740+
) -> MutableStateMap[EventBase]:
740741
""" Works out the difference in state between the start of the timeline
741742
and the previous sync.
742743

0 commit comments

Comments
 (0)