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

Add missing type hints to handlers. #9896

Merged
merged 7 commits into from
Apr 29, 2021
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/9896.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correct the type hint for the `user_may_create_room_alias` method of spam checkers. It is provided a `RoomAlias`, not a `str`.
1 change: 1 addition & 0 deletions changelog.d/9896.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add type hints to the `synapse.handlers` module.
5 changes: 4 additions & 1 deletion synapse/events/spamcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from synapse.rest.media.v1._base import FileInfo
from synapse.rest.media.v1.media_storage import ReadableFileWrapper
from synapse.spam_checker_api import RegistrationBehaviour
from synapse.types import RoomAlias
from synapse.util.async_helpers import maybe_awaitable

if TYPE_CHECKING:
Expand Down Expand Up @@ -113,7 +114,9 @@ async def user_may_create_room(self, userid: str) -> bool:

return True

async def user_may_create_room_alias(self, userid: str, room_alias: str) -> bool:
async def user_may_create_room_alias(
self, userid: str, room_alias: RoomAlias
) -> bool:
"""Checks if a given user may create a room alias

If this method returns false, the association request will be rejected.
Expand Down
59 changes: 33 additions & 26 deletions synapse/handlers/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import logging
import string
from typing import Iterable, List, Optional
from typing import TYPE_CHECKING, Iterable, List, Optional

from synapse.api.constants import MAX_ALIAS_LENGTH, EventTypes
from synapse.api.errors import (
Expand All @@ -27,15 +27,19 @@
SynapseError,
)
from synapse.appservice import ApplicationService
from synapse.types import Requester, RoomAlias, UserID, get_domain_from_id
from synapse.storage.databases.main.directory import RoomAliasMapping
from synapse.types import JsonDict, Requester, RoomAlias, UserID, get_domain_from_id

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer

logger = logging.getLogger(__name__)


class DirectoryHandler(BaseHandler):
def __init__(self, hs):
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.state = hs.get_state_handler()
Expand All @@ -60,7 +64,7 @@ async def _create_association(
room_id: str,
servers: Optional[Iterable[str]] = None,
creator: Optional[str] = None,
):
) -> None:
# general association creation for both human users and app services

for wchar in string.whitespace:
Expand Down Expand Up @@ -104,8 +108,9 @@ async def create_association(
"""

user_id = requester.user.to_string()
room_alias_str = room_alias.to_string()

if len(room_alias.to_string()) > MAX_ALIAS_LENGTH:
if len(room_alias_str) > MAX_ALIAS_LENGTH:
raise SynapseError(
400,
"Can't create aliases longer than %s characters" % MAX_ALIAS_LENGTH,
Expand All @@ -114,7 +119,7 @@ async def create_association(

service = requester.app_service
if service:
if not service.is_interested_in_alias(room_alias.to_string()):
if not service.is_interested_in_alias(room_alias_str):
raise SynapseError(
400,
"This application service has not reserved this kind of alias.",
Expand All @@ -138,7 +143,7 @@ async def create_association(
raise AuthError(403, "This user is not permitted to create this alias")

if not self.config.is_alias_creation_allowed(
user_id, room_id, room_alias.to_string()
user_id, room_id, room_alias_str
):
# Lets just return a generic message, as there may be all sorts of
# reasons why we said no. TODO: Allow configurable error messages
Expand Down Expand Up @@ -211,7 +216,7 @@ async def delete_association(

async def delete_appservice_association(
self, service: ApplicationService, room_alias: RoomAlias
):
) -> None:
if not service.is_interested_in_alias(room_alias.to_string()):
raise SynapseError(
400,
Expand All @@ -220,25 +225,27 @@ async def delete_appservice_association(
)
await self._delete_association(room_alias)

async def _delete_association(self, room_alias: RoomAlias):
async def _delete_association(self, room_alias: RoomAlias) -> str:
if not self.hs.is_mine(room_alias):
raise SynapseError(400, "Room alias must be local")

room_id = await self.store.delete_room_alias(room_alias)

return room_id

async def get_association(self, room_alias: RoomAlias):
async def get_association(self, room_alias: RoomAlias) -> JsonDict:
room_id = None
if self.hs.is_mine(room_alias):
result = await self.get_association_from_room_alias(room_alias)
result = await self.get_association_from_room_alias(
room_alias
) # type: Optional[RoomAliasMapping]

if result:
room_id = result.room_id
servers = result.servers
else:
try:
result = await self.federation.make_query(
fed_result = await self.federation.make_query(
destination=room_alias.domain,
query_type="directory",
args={"room_alias": room_alias.to_string()},
Expand All @@ -248,13 +255,13 @@ async def get_association(self, room_alias: RoomAlias):
except CodeMessageException as e:
logging.warning("Error retrieving alias")
if e.code == 404:
result = None
fed_result = None
else:
raise

if result and "room_id" in result and "servers" in result:
room_id = result["room_id"]
servers = result["servers"]
if fed_result and "room_id" in fed_result and "servers" in fed_result:
room_id = fed_result["room_id"]
servers = fed_result["servers"]

if not room_id:
raise SynapseError(
Expand All @@ -275,7 +282,7 @@ async def get_association(self, room_alias: RoomAlias):

return {"room_id": room_id, "servers": servers}

async def on_directory_query(self, args):
async def on_directory_query(self, args: JsonDict) -> JsonDict:
room_alias = RoomAlias.from_string(args["room_alias"])
if not self.hs.is_mine(room_alias):
raise SynapseError(400, "Room Alias is not hosted on this homeserver")
Expand All @@ -293,7 +300,7 @@ async def on_directory_query(self, args):

async def _update_canonical_alias(
self, requester: Requester, user_id: str, room_id: str, room_alias: RoomAlias
):
) -> None:
"""
Send an updated canonical alias event if the removed alias was set as
the canonical alias or listed in the alt_aliases field.
Expand Down Expand Up @@ -344,7 +351,9 @@ async def _update_canonical_alias(
ratelimit=False,
)

async def get_association_from_room_alias(self, room_alias: RoomAlias):
async def get_association_from_room_alias(
self, room_alias: RoomAlias
) -> Optional[RoomAliasMapping]:
result = await self.store.get_association_from_room_alias(room_alias)
if not result:
# Query AS to see if it exists
Expand Down Expand Up @@ -372,7 +381,7 @@ def can_modify_alias(self, alias: RoomAlias, user_id: Optional[str] = None) -> b
# either no interested services, or no service with an exclusive lock
return True

async def _user_can_delete_alias(self, alias: RoomAlias, user_id: str):
async def _user_can_delete_alias(self, alias: RoomAlias, user_id: str) -> bool:
"""Determine whether a user can delete an alias.

One of the following must be true:
Expand All @@ -394,14 +403,13 @@ async def _user_can_delete_alias(self, alias: RoomAlias, user_id: str):
if not room_id:
return False

res = await self.auth.check_can_change_room_list(
return await self.auth.check_can_change_room_list(
room_id, UserID.from_string(user_id)
)
return res

async def edit_published_room_list(
self, requester: Requester, room_id: str, visibility: str
):
) -> None:
"""Edit the entry of the room in the published room list.

requester
Expand Down Expand Up @@ -469,7 +477,7 @@ async def edit_published_room_list(

async def edit_published_appservice_room_list(
self, appservice_id: str, network_id: str, room_id: str, visibility: str
):
) -> None:
"""Add or remove a room from the appservice/network specific public
room list.

Expand Down Expand Up @@ -499,5 +507,4 @@ async def get_aliases_for_room(
room_id, requester.user.to_string()
)

aliases = await self.store.get_aliases_for_room(room_id)
return aliases
return await self.store.get_aliases_for_room(room_id)
9 changes: 6 additions & 3 deletions synapse/handlers/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""Utilities for interacting with Identity Servers"""
import logging
import urllib.parse
from typing import Awaitable, Callable, Dict, List, Optional, Tuple
from typing import TYPE_CHECKING, Awaitable, Callable, Dict, List, Optional, Tuple

from synapse.api.errors import (
CodeMessageException,
Expand All @@ -41,13 +41,16 @@

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer

logger = logging.getLogger(__name__)

id_server_scheme = "https://"


class IdentityHandler(BaseHandler):
def __init__(self, hs):
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

# An HTTP client for contacting trusted URLs.
Expand Down Expand Up @@ -80,7 +83,7 @@ async def ratelimit_request_token_requests(
request: SynapseRequest,
medium: str,
address: str,
):
) -> None:
"""Used to ratelimit requests to `/requestToken` by IP and address.

Args:
Expand Down
24 changes: 17 additions & 7 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# limitations under the License.
import logging
import random
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple

from canonicaljson import encode_canonical_json

Expand Down Expand Up @@ -66,7 +66,7 @@
class MessageHandler:
"""Contains some read only APIs to get state about a room"""

def __init__(self, hs):
def __init__(self, hs: "HomeServer"):
self.auth = hs.get_auth()
self.clock = hs.get_clock()
self.state = hs.get_state_handler()
Expand All @@ -91,7 +91,7 @@ async def get_room_data(
room_id: str,
event_type: str,
state_key: str,
) -> dict:
) -> Optional[EventBase]:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to return EventBase, and the caller calls methods on it that don't exist on dict. 🤷

"""Get data from a room.

Args:
Expand All @@ -115,6 +115,10 @@ async def get_room_data(
data = await self.state.get_current_state(room_id, event_type, state_key)
elif membership == Membership.LEAVE:
key = (event_type, state_key)
# If the membership is not JOIN, then the event ID should exist.
assert (
membership_event_id is not None
), "check_user_in_room_or_world_readable returned invalid data"
room_state = await self.state_store.get_state_for_events(
[membership_event_id], StateFilter.from_types([key])
)
Expand Down Expand Up @@ -186,10 +190,12 @@ async def get_state_events(

event = last_events[0]
if visible_events:
room_state = await self.state_store.get_state_for_events(
room_state_events = await self.state_store.get_state_for_events(
[event.event_id], state_filter=state_filter
)
room_state = room_state[event.event_id]
room_state = room_state_events[
event.event_id
] # type: Mapping[Any, EventBase]
else:
raise AuthError(
403,
Expand All @@ -210,10 +216,14 @@ async def get_state_events(
)
room_state = await self.store.get_events(state_ids.values())
elif membership == Membership.LEAVE:
room_state = await self.state_store.get_state_for_events(
# If the membership is not JOIN, then the event ID should exist.
assert (
membership_event_id is not None
), "check_user_in_room_or_world_readable returned invalid data"
room_state_events = await self.state_store.get_state_for_events(
[membership_event_id], state_filter=state_filter
)
room_state = room_state[membership_event_id]
room_state = room_state_events[membership_event_id]

now = self.clock.time_msec()
events = await self._event_serializer.serialize_events(
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ async def _is_server_notice_room(self, room_id: str) -> bool:


class RoomMemberMasterHandler(RoomMemberHandler):
def __init__(self, hs):
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.distributor = hs.get_distributor()
Expand Down
Loading