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

Commit 3b07593

Browse files
committed
Move check_user_in_room, check_user_in_room_or_world_readable, and check_can_change_room_list to EventAuthHandler.
1 parent 12ae3d8 commit 3b07593

File tree

11 files changed

+172
-155
lines changed

11 files changed

+172
-155
lines changed

synapse/api/auth.py

Lines changed: 2 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,20 @@
1919

2020
from twisted.web.server import Request
2121

22-
from synapse import event_auth
2322
from synapse.api.auth_blocking import AuthBlocking
24-
from synapse.api.constants import EventTypes, HistoryVisibility, Membership
23+
from synapse.api.constants import EventTypes
2524
from synapse.api.errors import (
2625
AuthError,
2726
Codes,
2827
InvalidClientTokenError,
2928
MissingClientTokenError,
3029
)
3130
from synapse.appservice import ApplicationService
32-
from synapse.events import EventBase
3331
from synapse.http import get_request_user_agent
3432
from synapse.http.site import SynapseRequest
3533
from synapse.logging import opentracing as opentracing
3634
from synapse.storage.databases.main.registration import TokenLookupResult
37-
from synapse.types import Requester, StateMap, UserID, create_requester
35+
from synapse.types import Requester, UserID, create_requester
3836
from synapse.util.caches.lrucache import LruCache
3937
from synapse.util.macaroons import get_value_from_macaroon, satisfy_expiry
4038

@@ -87,56 +85,6 @@ def __init__(self, hs: "HomeServer"):
8785
self._macaroon_secret_key = hs.config.macaroon_secret_key
8886
self._force_tracing_for_users = hs.config.tracing.force_tracing_for_users
8987

90-
async def check_user_in_room(
91-
self,
92-
room_id: str,
93-
user_id: str,
94-
current_state: Optional[StateMap[EventBase]] = None,
95-
allow_departed_users: bool = False,
96-
) -> EventBase:
97-
"""Check if the user is in the room, or was at some point.
98-
Args:
99-
room_id: The room to check.
100-
101-
user_id: The user to check.
102-
103-
current_state: Optional map of the current state of the room.
104-
If provided then that map is used to check whether they are a
105-
member of the room. Otherwise the current membership is
106-
loaded from the database.
107-
108-
allow_departed_users: if True, accept users that were previously
109-
members but have now departed.
110-
111-
Raises:
112-
AuthError if the user is/was not in the room.
113-
Returns:
114-
Membership event for the user if the user was in the
115-
room. This will be the join event if they are currently joined to
116-
the room. This will be the leave event if they have left the room.
117-
"""
118-
if current_state:
119-
member = current_state.get((EventTypes.Member, user_id), None)
120-
else:
121-
member = await self.state.get_current_state(
122-
room_id=room_id, event_type=EventTypes.Member, state_key=user_id
123-
)
124-
125-
if member:
126-
membership = member.membership
127-
128-
if membership == Membership.JOIN:
129-
return member
130-
131-
# XXX this looks totally bogus. Why do we not allow users who have been banned,
132-
# or those who were members previously and have been re-invited?
133-
if allow_departed_users and membership == Membership.LEAVE:
134-
forgot = await self.store.did_forget(user_id, room_id)
135-
if not forgot:
136-
return member
137-
138-
raise AuthError(403, "User %s not in room %s" % (user_id, room_id))
139-
14088
async def get_user_by_req(
14189
self,
14290
request: SynapseRequest,
@@ -467,40 +415,6 @@ async def is_server_admin(self, user: UserID) -> bool:
467415
"""
468416
return await self.store.is_server_admin(user)
469417

470-
async def check_can_change_room_list(self, room_id: str, user: UserID) -> bool:
471-
"""Determine whether the user is allowed to edit the room's entry in the
472-
published room list.
473-
474-
Args:
475-
room_id
476-
user
477-
"""
478-
479-
is_admin = await self.is_server_admin(user)
480-
if is_admin:
481-
return True
482-
483-
user_id = user.to_string()
484-
await self.check_user_in_room(room_id, user_id)
485-
486-
# We currently require the user is a "moderator" in the room. We do this
487-
# by checking if they would (theoretically) be able to change the
488-
# m.room.canonical_alias events
489-
power_level_event = await self.state.get_current_state(
490-
room_id, EventTypes.PowerLevels, ""
491-
)
492-
493-
auth_events = {}
494-
if power_level_event:
495-
auth_events[(EventTypes.PowerLevels, "")] = power_level_event
496-
497-
send_level = event_auth.get_send_level(
498-
EventTypes.CanonicalAlias, "", power_level_event
499-
)
500-
user_level = event_auth.get_user_power_level(user_id, auth_events)
501-
502-
return user_level >= send_level
503-
504418
@staticmethod
505419
def has_access_token(request: Request) -> bool:
506420
"""Checks if the request has an access_token.
@@ -553,49 +467,5 @@ def get_access_token_from_request(request: Request) -> str:
553467

554468
return query_params[0].decode("ascii")
555469

556-
async def check_user_in_room_or_world_readable(
557-
self, room_id: str, user_id: str, allow_departed_users: bool = False
558-
) -> Tuple[str, Optional[str]]:
559-
"""Checks that the user is or was in the room or the room is world
560-
readable. If it isn't then an exception is raised.
561-
562-
Args:
563-
room_id: room to check
564-
user_id: user to check
565-
allow_departed_users: if True, accept users that were previously
566-
members but have now departed
567-
568-
Returns:
569-
Resolves to the current membership of the user in the room and the
570-
membership event ID of the user. If the user is not in the room and
571-
never has been, then `(Membership.JOIN, None)` is returned.
572-
"""
573-
574-
try:
575-
# check_user_in_room will return the most recent membership
576-
# event for the user if:
577-
# * The user is a non-guest user, and was ever in the room
578-
# * The user is a guest user, and has joined the room
579-
# else it will throw.
580-
member_event = await self.check_user_in_room(
581-
room_id, user_id, allow_departed_users=allow_departed_users
582-
)
583-
return member_event.membership, member_event.event_id
584-
except AuthError:
585-
visibility = await self.state.get_current_state(
586-
room_id, EventTypes.RoomHistoryVisibility, ""
587-
)
588-
if (
589-
visibility
590-
and visibility.content.get("history_visibility")
591-
== HistoryVisibility.WORLD_READABLE
592-
):
593-
return Membership.JOIN, None
594-
raise AuthError(
595-
403,
596-
"User %s not in room %s, and room previews are disabled"
597-
% (user_id, room_id),
598-
)
599-
600470
async def check_auth_blocking(self, *args, **kwargs) -> None:
601471
await self._auth_blocking.check_auth_blocking(*args, **kwargs)

synapse/event_auth.py

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

1616
import logging
17-
from typing import Any, Dict, List, Optional, Set, Tuple, Union
17+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Union
1818

1919
from canonicaljson import encode_canonical_json
2020
from signedjson.key import decode_verify_key_bytes
@@ -29,9 +29,11 @@
2929
RoomVersion,
3030
)
3131
from synapse.events import EventBase
32-
from synapse.events.builder import EventBuilder
3332
from synapse.types import StateMap, UserID, get_domain_from_id
3433

34+
if TYPE_CHECKING:
35+
from synapse.events.builder import EventBuilder
36+
3537
logger = logging.getLogger(__name__)
3638

3739

@@ -725,7 +727,9 @@ def get_public_keys(invite_event: EventBase) -> List[Dict[str, Any]]:
725727
return public_keys
726728

727729

728-
def auth_types_for_event(event: Union[EventBase, EventBuilder]) -> Set[Tuple[str, str]]:
730+
def auth_types_for_event(
731+
event: Union[EventBase, "EventBuilder"]
732+
) -> Set[Tuple[str, str]]:
729733
"""Given an event, return a list of (EventType, StateKey) that may be
730734
needed to auth the event. The returned list may be a superset of what
731735
would actually be required depending on the full state of the room.

synapse/handlers/directory.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def __init__(self, hs: "HomeServer"):
4545
self.state = hs.get_state_handler()
4646
self.appservice_handler = hs.get_application_service_handler()
4747
self.event_creation_handler = hs.get_event_creation_handler()
48+
self._event_auth_handler = hs.get_event_auth_handler()
4849
self.store = hs.get_datastore()
4950
self.config = hs.config
5051
self.enable_room_list_search = hs.config.enable_room_list_search
@@ -403,7 +404,7 @@ async def _user_can_delete_alias(self, alias: RoomAlias, user_id: str) -> bool:
403404
if not room_id:
404405
return False
405406

406-
return await self.auth.check_can_change_room_list(
407+
return await self._event_auth_handler.check_can_change_room_list(
407408
room_id, UserID.from_string(user_id)
408409
)
409410

@@ -439,8 +440,10 @@ async def edit_published_room_list(
439440
if room is None:
440441
raise SynapseError(400, "Unknown room")
441442

442-
can_change_room_list = await self.auth.check_can_change_room_list(
443-
room_id, requester.user
443+
can_change_room_list = (
444+
await self._event_auth_handler.check_can_change_room_list(
445+
room_id, requester.user
446+
)
444447
)
445448
if not can_change_room_list:
446449
raise AuthError(
@@ -503,7 +506,7 @@ async def get_aliases_for_room(
503506
# allow access to server admins and current members of the room
504507
is_admin = await self.auth.is_server_admin(requester.user)
505508
if not is_admin:
506-
await self.auth.check_user_in_room_or_world_readable(
509+
await self._event_auth_handler.check_user_in_room_or_world_readable(
507510
room_id, requester.user.to_string()
508511
)
509512

0 commit comments

Comments
 (0)