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

Commit 1baab20

Browse files
authored
Add type hints to various handlers. (#9223)
With this change all handlers except the e2e_* ones have type hints enabled.
1 parent 26837d5 commit 1baab20

File tree

14 files changed

+205
-138
lines changed

14 files changed

+205
-138
lines changed

changelog.d/9223.misc

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

mypy.ini

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ files =
2626
synapse/handlers/_base.py,
2727
synapse/handlers/account_data.py,
2828
synapse/handlers/account_validity.py,
29+
synapse/handlers/acme.py,
30+
synapse/handlers/acme_issuing_service.py,
2931
synapse/handlers/admin.py,
3032
synapse/handlers/appservice.py,
3133
synapse/handlers/auth.py,
@@ -36,6 +38,7 @@ files =
3638
synapse/handlers/directory.py,
3739
synapse/handlers/events.py,
3840
synapse/handlers/federation.py,
41+
synapse/handlers/groups_local.py,
3942
synapse/handlers/identity.py,
4043
synapse/handlers/initial_sync.py,
4144
synapse/handlers/message.py,
@@ -52,8 +55,13 @@ files =
5255
synapse/handlers/room_member.py,
5356
synapse/handlers/room_member_worker.py,
5457
synapse/handlers/saml_handler.py,
58+
synapse/handlers/search.py,
59+
synapse/handlers/set_password.py,
5560
synapse/handlers/sso.py,
61+
synapse/handlers/state_deltas.py,
62+
synapse/handlers/stats.py,
5663
synapse/handlers/sync.py,
64+
synapse/handlers/typing.py,
5765
synapse/handlers/user_directory.py,
5866
synapse/handlers/ui_auth,
5967
synapse/http/client.py,
@@ -194,3 +202,9 @@ ignore_missing_imports = True
194202

195203
[mypy-hiredis]
196204
ignore_missing_imports = True
205+
206+
[mypy-josepy.*]
207+
ignore_missing_imports = True
208+
209+
[mypy-txacme.*]
210+
ignore_missing_imports = True

synapse/handlers/acme.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# limitations under the License.
1515

1616
import logging
17+
from typing import TYPE_CHECKING
1718

1819
import twisted
1920
import twisted.internet.error
@@ -22,6 +23,9 @@
2223

2324
from synapse.app import check_bind_error
2425

26+
if TYPE_CHECKING:
27+
from synapse.app.homeserver import HomeServer
28+
2529
logger = logging.getLogger(__name__)
2630

2731
ACME_REGISTER_FAIL_ERROR = """
@@ -35,12 +39,12 @@
3539

3640

3741
class AcmeHandler:
38-
def __init__(self, hs):
42+
def __init__(self, hs: "HomeServer"):
3943
self.hs = hs
4044
self.reactor = hs.get_reactor()
4145
self._acme_domain = hs.config.acme_domain
4246

43-
async def start_listening(self):
47+
async def start_listening(self) -> None:
4448
from synapse.handlers import acme_issuing_service
4549

4650
# Configure logging for txacme, if you need to debug
@@ -85,7 +89,7 @@ async def start_listening(self):
8589
logger.error(ACME_REGISTER_FAIL_ERROR)
8690
raise
8791

88-
async def provision_certificate(self):
92+
async def provision_certificate(self) -> None:
8993

9094
logger.warning("Reprovisioning %s", self._acme_domain)
9195

@@ -110,5 +114,3 @@ async def provision_certificate(self):
110114
except Exception:
111115
logger.exception("Failed saving!")
112116
raise
113-
114-
return True

synapse/handlers/acme_issuing_service.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
imported conditionally.
2323
"""
2424
import logging
25+
from typing import Dict, Iterable, List
2526

2627
import attr
28+
import pem
2729
from cryptography.hazmat.backends import default_backend
2830
from cryptography.hazmat.primitives import serialization
2931
from josepy import JWKRSA
@@ -36,20 +38,27 @@
3638
from zope.interface import implementer
3739

3840
from twisted.internet import defer
41+
from twisted.internet.interfaces import IReactorTCP
3942
from twisted.python.filepath import FilePath
4043
from twisted.python.url import URL
44+
from twisted.web.resource import IResource
4145

4246
logger = logging.getLogger(__name__)
4347

4448

45-
def create_issuing_service(reactor, acme_url, account_key_file, well_known_resource):
49+
def create_issuing_service(
50+
reactor: IReactorTCP,
51+
acme_url: str,
52+
account_key_file: str,
53+
well_known_resource: IResource,
54+
) -> AcmeIssuingService:
4655
"""Create an ACME issuing service, and attach it to a web Resource
4756
4857
Args:
4958
reactor: twisted reactor
50-
acme_url (str): URL to use to request certificates
51-
account_key_file (str): where to store the account key
52-
well_known_resource (twisted.web.IResource): web resource for .well-known.
59+
acme_url: URL to use to request certificates
60+
account_key_file: where to store the account key
61+
well_known_resource: web resource for .well-known.
5362
we will attach a child resource for "acme-challenge".
5463
5564
Returns:
@@ -83,18 +92,20 @@ class ErsatzStore:
8392
A store that only stores in memory.
8493
"""
8594

86-
certs = attr.ib(default=attr.Factory(dict))
95+
certs = attr.ib(type=Dict[bytes, List[bytes]], default=attr.Factory(dict))
8796

88-
def store(self, server_name, pem_objects):
97+
def store(
98+
self, server_name: bytes, pem_objects: Iterable[pem.AbstractPEMObject]
99+
) -> defer.Deferred:
89100
self.certs[server_name] = [o.as_bytes() for o in pem_objects]
90101
return defer.succeed(None)
91102

92103

93-
def load_or_create_client_key(key_file):
104+
def load_or_create_client_key(key_file: str) -> JWKRSA:
94105
"""Load the ACME account key from a file, creating it if it does not exist.
95106
96107
Args:
97-
key_file (str): name of the file to use as the account key
108+
key_file: name of the file to use as the account key
98109
"""
99110
# this is based on txacme.endpoint.load_or_create_client_key, but doesn't
100111
# hardcode the 'client.key' filename

synapse/handlers/groups_local.py

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515
# limitations under the License.
1616

1717
import logging
18+
from typing import TYPE_CHECKING, Dict, Iterable, List, Set
1819

1920
from synapse.api.errors import HttpResponseException, RequestSendFailed, SynapseError
20-
from synapse.types import GroupID, get_domain_from_id
21+
from synapse.types import GroupID, JsonDict, get_domain_from_id
22+
23+
if TYPE_CHECKING:
24+
from synapse.app.homeserver import HomeServer
2125

2226
logger = logging.getLogger(__name__)
2327

@@ -56,7 +60,7 @@ async def f(self, group_id, *args, **kwargs):
5660

5761

5862
class GroupsLocalWorkerHandler:
59-
def __init__(self, hs):
63+
def __init__(self, hs: "HomeServer"):
6064
self.hs = hs
6165
self.store = hs.get_datastore()
6266
self.room_list_handler = hs.get_room_list_handler()
@@ -84,7 +88,9 @@ def __init__(self, hs):
8488
get_group_role = _create_rerouter("get_group_role")
8589
get_group_roles = _create_rerouter("get_group_roles")
8690

87-
async def get_group_summary(self, group_id, requester_user_id):
91+
async def get_group_summary(
92+
self, group_id: str, requester_user_id: str
93+
) -> JsonDict:
8894
"""Get the group summary for a group.
8995
9096
If the group is remote we check that the users have valid attestations.
@@ -137,14 +143,15 @@ async def get_group_summary(self, group_id, requester_user_id):
137143

138144
return res
139145

140-
async def get_users_in_group(self, group_id, requester_user_id):
146+
async def get_users_in_group(
147+
self, group_id: str, requester_user_id: str
148+
) -> JsonDict:
141149
"""Get users in a group
142150
"""
143151
if self.is_mine_id(group_id):
144-
res = await self.groups_server_handler.get_users_in_group(
152+
return await self.groups_server_handler.get_users_in_group(
145153
group_id, requester_user_id
146154
)
147-
return res
148155

149156
group_server_name = get_domain_from_id(group_id)
150157

@@ -178,11 +185,11 @@ async def get_users_in_group(self, group_id, requester_user_id):
178185

179186
return res
180187

181-
async def get_joined_groups(self, user_id):
188+
async def get_joined_groups(self, user_id: str) -> JsonDict:
182189
group_ids = await self.store.get_joined_groups(user_id)
183190
return {"groups": group_ids}
184191

185-
async def get_publicised_groups_for_user(self, user_id):
192+
async def get_publicised_groups_for_user(self, user_id: str) -> JsonDict:
186193
if self.hs.is_mine_id(user_id):
187194
result = await self.store.get_publicised_groups_for_user(user_id)
188195

@@ -206,8 +213,10 @@ async def get_publicised_groups_for_user(self, user_id):
206213
# TODO: Verify attestations
207214
return {"groups": result}
208215

209-
async def bulk_get_publicised_groups(self, user_ids, proxy=True):
210-
destinations = {}
216+
async def bulk_get_publicised_groups(
217+
self, user_ids: Iterable[str], proxy: bool = True
218+
) -> JsonDict:
219+
destinations = {} # type: Dict[str, Set[str]]
211220
local_users = set()
212221

213222
for user_id in user_ids:
@@ -220,7 +229,7 @@ async def bulk_get_publicised_groups(self, user_ids, proxy=True):
220229
raise SynapseError(400, "Some user_ids are not local")
221230

222231
results = {}
223-
failed_results = []
232+
failed_results = [] # type: List[str]
224233
for destination, dest_user_ids in destinations.items():
225234
try:
226235
r = await self.transport_client.bulk_get_publicised_groups(
@@ -242,7 +251,7 @@ async def bulk_get_publicised_groups(self, user_ids, proxy=True):
242251

243252

244253
class GroupsLocalHandler(GroupsLocalWorkerHandler):
245-
def __init__(self, hs):
254+
def __init__(self, hs: "HomeServer"):
246255
super().__init__(hs)
247256

248257
# Ensure attestations get renewed
@@ -271,7 +280,9 @@ def __init__(self, hs):
271280

272281
set_group_join_policy = _create_rerouter("set_group_join_policy")
273282

274-
async def create_group(self, group_id, user_id, content):
283+
async def create_group(
284+
self, group_id: str, user_id: str, content: JsonDict
285+
) -> JsonDict:
275286
"""Create a group
276287
"""
277288

@@ -284,27 +295,7 @@ async def create_group(self, group_id, user_id, content):
284295
local_attestation = None
285296
remote_attestation = None
286297
else:
287-
local_attestation = self.attestations.create_attestation(group_id, user_id)
288-
content["attestation"] = local_attestation
289-
290-
content["user_profile"] = await self.profile_handler.get_profile(user_id)
291-
292-
try:
293-
res = await self.transport_client.create_group(
294-
get_domain_from_id(group_id), group_id, user_id, content
295-
)
296-
except HttpResponseException as e:
297-
raise e.to_synapse_error()
298-
except RequestSendFailed:
299-
raise SynapseError(502, "Failed to contact group server")
300-
301-
remote_attestation = res["attestation"]
302-
await self.attestations.verify_attestation(
303-
remote_attestation,
304-
group_id=group_id,
305-
user_id=user_id,
306-
server_name=get_domain_from_id(group_id),
307-
)
298+
raise SynapseError(400, "Unable to create remote groups")
308299

309300
is_publicised = content.get("publicise", False)
310301
token = await self.store.register_user_group_membership(
@@ -320,7 +311,9 @@ async def create_group(self, group_id, user_id, content):
320311

321312
return res
322313

323-
async def join_group(self, group_id, user_id, content):
314+
async def join_group(
315+
self, group_id: str, user_id: str, content: JsonDict
316+
) -> JsonDict:
324317
"""Request to join a group
325318
"""
326319
if self.is_mine_id(group_id):
@@ -365,7 +358,9 @@ async def join_group(self, group_id, user_id, content):
365358

366359
return {}
367360

368-
async def accept_invite(self, group_id, user_id, content):
361+
async def accept_invite(
362+
self, group_id: str, user_id: str, content: JsonDict
363+
) -> JsonDict:
369364
"""Accept an invite to a group
370365
"""
371366
if self.is_mine_id(group_id):
@@ -410,7 +405,9 @@ async def accept_invite(self, group_id, user_id, content):
410405

411406
return {}
412407

413-
async def invite(self, group_id, user_id, requester_user_id, config):
408+
async def invite(
409+
self, group_id: str, user_id: str, requester_user_id: str, config: JsonDict
410+
) -> JsonDict:
414411
"""Invite a user to a group
415412
"""
416413
content = {"requester_user_id": requester_user_id, "config": config}
@@ -434,7 +431,9 @@ async def invite(self, group_id, user_id, requester_user_id, config):
434431

435432
return res
436433

437-
async def on_invite(self, group_id, user_id, content):
434+
async def on_invite(
435+
self, group_id: str, user_id: str, content: JsonDict
436+
) -> JsonDict:
438437
"""One of our users were invited to a group
439438
"""
440439
# TODO: Support auto join and rejection
@@ -465,8 +464,8 @@ async def on_invite(self, group_id, user_id, content):
465464
return {"state": "invite", "user_profile": user_profile}
466465

467466
async def remove_user_from_group(
468-
self, group_id, user_id, requester_user_id, content
469-
):
467+
self, group_id: str, user_id: str, requester_user_id: str, content: JsonDict
468+
) -> JsonDict:
470469
"""Remove a user from a group
471470
"""
472471
if user_id == requester_user_id:
@@ -499,7 +498,9 @@ async def remove_user_from_group(
499498

500499
return res
501500

502-
async def user_removed_from_group(self, group_id, user_id, content):
501+
async def user_removed_from_group(
502+
self, group_id: str, user_id: str, content: JsonDict
503+
) -> None:
503504
"""One of our users was removed/kicked from a group
504505
"""
505506
# TODO: Check if user in group

0 commit comments

Comments
 (0)