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

Commit 8d60943

Browse files
authored
Move methods involving event authentication to EventAuthHandler. (#10268)
Instead of mixing them with user authentication methods.
1 parent 0aab50c commit 8d60943

File tree

11 files changed

+112
-106
lines changed

11 files changed

+112
-106
lines changed

changelog.d/10268.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Move event authentication methods from `Auth` to `EventAuthHandler`.

synapse/api/auth.py

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import logging
15-
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
15+
from typing import TYPE_CHECKING, Optional, Tuple
1616

1717
import pymacaroons
1818
from netaddr import IPAddress
@@ -28,34 +28,22 @@
2828
InvalidClientTokenError,
2929
MissingClientTokenError,
3030
)
31-
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
3231
from synapse.appservice import ApplicationService
3332
from synapse.events import EventBase
34-
from synapse.events.builder import EventBuilder
3533
from synapse.http import get_request_user_agent
3634
from synapse.http.site import SynapseRequest
3735
from synapse.logging import opentracing as opentracing
3836
from synapse.storage.databases.main.registration import TokenLookupResult
3937
from synapse.types import Requester, StateMap, UserID, create_requester
4038
from synapse.util.caches.lrucache import LruCache
4139
from synapse.util.macaroons import get_value_from_macaroon, satisfy_expiry
42-
from synapse.util.metrics import Measure
4340

4441
if TYPE_CHECKING:
4542
from synapse.server import HomeServer
4643

4744
logger = logging.getLogger(__name__)
4845

4946

50-
AuthEventTypes = (
51-
EventTypes.Create,
52-
EventTypes.Member,
53-
EventTypes.PowerLevels,
54-
EventTypes.JoinRules,
55-
EventTypes.RoomHistoryVisibility,
56-
EventTypes.ThirdPartyInvite,
57-
)
58-
5947
# guests always get this device id.
6048
GUEST_DEVICE_ID = "guest_device"
6149

@@ -66,9 +54,7 @@ class _InvalidMacaroonException(Exception):
6654

6755
class Auth:
6856
"""
69-
FIXME: This class contains a mix of functions for authenticating users
70-
of our client-server API and authenticating events added to room graphs.
71-
The latter should be moved to synapse.handlers.event_auth.EventAuthHandler.
57+
This class contains functions for authenticating users of our client-server API.
7258
"""
7359

7460
def __init__(self, hs: "HomeServer"):
@@ -90,18 +76,6 @@ def __init__(self, hs: "HomeServer"):
9076
self._macaroon_secret_key = hs.config.macaroon_secret_key
9177
self._force_tracing_for_users = hs.config.tracing.force_tracing_for_users
9278

93-
async def check_from_context(
94-
self, room_version: str, event, context, do_sig_check=True
95-
) -> None:
96-
auth_event_ids = event.auth_event_ids()
97-
auth_events_by_id = await self.store.get_events(auth_event_ids)
98-
auth_events = {(e.type, e.state_key): e for e in auth_events_by_id.values()}
99-
100-
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
101-
event_auth.check(
102-
room_version_obj, event, auth_events=auth_events, do_sig_check=do_sig_check
103-
)
104-
10579
async def check_user_in_room(
10680
self,
10781
room_id: str,
@@ -152,13 +126,6 @@ async def check_user_in_room(
152126

153127
raise AuthError(403, "User %s not in room %s" % (user_id, room_id))
154128

155-
async def check_host_in_room(self, room_id: str, host: str) -> bool:
156-
with Measure(self.clock, "check_host_in_room"):
157-
return await self.store.is_host_joined(room_id, host)
158-
159-
def get_public_keys(self, invite_event: EventBase) -> List[Dict[str, Any]]:
160-
return event_auth.get_public_keys(invite_event)
161-
162129
async def get_user_by_req(
163130
self,
164131
request: SynapseRequest,
@@ -489,44 +456,6 @@ async def is_server_admin(self, user: UserID) -> bool:
489456
"""
490457
return await self.store.is_server_admin(user)
491458

492-
def compute_auth_events(
493-
self,
494-
event: Union[EventBase, EventBuilder],
495-
current_state_ids: StateMap[str],
496-
for_verification: bool = False,
497-
) -> List[str]:
498-
"""Given an event and current state return the list of event IDs used
499-
to auth an event.
500-
501-
If `for_verification` is False then only return auth events that
502-
should be added to the event's `auth_events`.
503-
504-
Returns:
505-
List of event IDs.
506-
"""
507-
508-
if event.type == EventTypes.Create:
509-
return []
510-
511-
# Currently we ignore the `for_verification` flag even though there are
512-
# some situations where we can drop particular auth events when adding
513-
# to the event's `auth_events` (e.g. joins pointing to previous joins
514-
# when room is publicly joinable). Dropping event IDs has the
515-
# advantage that the auth chain for the room grows slower, but we use
516-
# the auth chain in state resolution v2 to order events, which means
517-
# care must be taken if dropping events to ensure that it doesn't
518-
# introduce undesirable "state reset" behaviour.
519-
#
520-
# All of which sounds a bit tricky so we don't bother for now.
521-
522-
auth_ids = []
523-
for etype, state_key in event_auth.auth_types_for_event(event):
524-
auth_ev_id = current_state_ids.get((etype, state_key))
525-
if auth_ev_id:
526-
auth_ids.append(auth_ev_id)
527-
528-
return auth_ids
529-
530459
async def check_can_change_room_list(self, room_id: str, user: UserID) -> bool:
531460
"""Determine whether the user is allowed to edit the room's entry in the
532461
published room list.

synapse/events/builder.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from synapse.util.stringutils import random_string
3535

3636
if TYPE_CHECKING:
37-
from synapse.api.auth import Auth
37+
from synapse.handlers.event_auth import EventAuthHandler
3838
from synapse.server import HomeServer
3939

4040
logger = logging.getLogger(__name__)
@@ -66,7 +66,7 @@ class EventBuilder:
6666
"""
6767

6868
_state: StateHandler
69-
_auth: "Auth"
69+
_event_auth_handler: "EventAuthHandler"
7070
_store: DataStore
7171
_clock: Clock
7272
_hostname: str
@@ -125,7 +125,9 @@ async def build(
125125
state_ids = await self._state.get_current_state_ids(
126126
self.room_id, prev_event_ids
127127
)
128-
auth_event_ids = self._auth.compute_auth_events(self, state_ids)
128+
auth_event_ids = self._event_auth_handler.compute_auth_events(
129+
self, state_ids
130+
)
129131

130132
format_version = self.room_version.event_format
131133
if format_version == EventFormatVersions.V1:
@@ -193,7 +195,7 @@ def __init__(self, hs: "HomeServer"):
193195

194196
self.store = hs.get_datastore()
195197
self.state = hs.get_state_handler()
196-
self.auth = hs.get_auth()
198+
self._event_auth_handler = hs.get_event_auth_handler()
197199

198200
def new(self, room_version: str, key_values: dict) -> EventBuilder:
199201
"""Generate an event builder appropriate for the given room version
@@ -229,7 +231,7 @@ def for_room_version(
229231
return EventBuilder(
230232
store=self.store,
231233
state=self.state,
232-
auth=self.auth,
234+
event_auth_handler=self._event_auth_handler,
233235
clock=self.clock,
234236
hostname=self.hostname,
235237
signing_key=self.signing_key,

synapse/federation/federation_server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ class FederationServer(FederationBase):
108108
def __init__(self, hs: "HomeServer"):
109109
super().__init__(hs)
110110

111-
self.auth = hs.get_auth()
112111
self.handler = hs.get_federation_handler()
113112
self.state = hs.get_state_handler()
113+
self._event_auth_handler = hs.get_event_auth_handler()
114114

115115
self.device_handler = hs.get_device_handler()
116116

@@ -420,7 +420,7 @@ async def on_room_state_request(
420420
origin_host, _ = parse_server_name(origin)
421421
await self.check_server_matches_acl(origin_host, room_id)
422422

423-
in_room = await self.auth.check_host_in_room(room_id, origin)
423+
in_room = await self._event_auth_handler.check_host_in_room(room_id, origin)
424424
if not in_room:
425425
raise AuthError(403, "Host not in room.")
426426

@@ -453,7 +453,7 @@ async def on_state_ids_request(
453453
origin_host, _ = parse_server_name(origin)
454454
await self.check_server_matches_acl(origin_host, room_id)
455455

456-
in_room = await self.auth.check_host_in_room(room_id, origin)
456+
in_room = await self._event_auth_handler.check_host_in_room(room_id, origin)
457457
if not in_room:
458458
raise AuthError(403, "Host not in room.")
459459

synapse/handlers/event_auth.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from typing import TYPE_CHECKING, Collection, Optional
14+
from typing import TYPE_CHECKING, Collection, List, Optional, Union
1515

16+
from synapse import event_auth
1617
from synapse.api.constants import (
1718
EventTypes,
1819
JoinRules,
1920
Membership,
2021
RestrictedJoinRuleTypes,
2122
)
2223
from synapse.api.errors import AuthError
23-
from synapse.api.room_versions import RoomVersion
24+
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersion
2425
from synapse.events import EventBase
26+
from synapse.events.builder import EventBuilder
2527
from synapse.types import StateMap
28+
from synapse.util.metrics import Measure
2629

2730
if TYPE_CHECKING:
2831
from synapse.server import HomeServer
@@ -34,8 +37,63 @@ class EventAuthHandler:
3437
"""
3538

3639
def __init__(self, hs: "HomeServer"):
40+
self._clock = hs.get_clock()
3741
self._store = hs.get_datastore()
3842

43+
async def check_from_context(
44+
self, room_version: str, event, context, do_sig_check=True
45+
) -> None:
46+
auth_event_ids = event.auth_event_ids()
47+
auth_events_by_id = await self._store.get_events(auth_event_ids)
48+
auth_events = {(e.type, e.state_key): e for e in auth_events_by_id.values()}
49+
50+
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
51+
event_auth.check(
52+
room_version_obj, event, auth_events=auth_events, do_sig_check=do_sig_check
53+
)
54+
55+
def compute_auth_events(
56+
self,
57+
event: Union[EventBase, EventBuilder],
58+
current_state_ids: StateMap[str],
59+
for_verification: bool = False,
60+
) -> List[str]:
61+
"""Given an event and current state return the list of event IDs used
62+
to auth an event.
63+
64+
If `for_verification` is False then only return auth events that
65+
should be added to the event's `auth_events`.
66+
67+
Returns:
68+
List of event IDs.
69+
"""
70+
71+
if event.type == EventTypes.Create:
72+
return []
73+
74+
# Currently we ignore the `for_verification` flag even though there are
75+
# some situations where we can drop particular auth events when adding
76+
# to the event's `auth_events` (e.g. joins pointing to previous joins
77+
# when room is publicly joinable). Dropping event IDs has the
78+
# advantage that the auth chain for the room grows slower, but we use
79+
# the auth chain in state resolution v2 to order events, which means
80+
# care must be taken if dropping events to ensure that it doesn't
81+
# introduce undesirable "state reset" behaviour.
82+
#
83+
# All of which sounds a bit tricky so we don't bother for now.
84+
85+
auth_ids = []
86+
for etype, state_key in event_auth.auth_types_for_event(event):
87+
auth_ev_id = current_state_ids.get((etype, state_key))
88+
if auth_ev_id:
89+
auth_ids.append(auth_ev_id)
90+
91+
return auth_ids
92+
93+
async def check_host_in_room(self, room_id: str, host: str) -> bool:
94+
with Measure(self._clock, "check_host_in_room"):
95+
return await self._store.is_host_joined(room_id, host)
96+
3997
async def check_restricted_join_rules(
4098
self,
4199
state_ids: StateMap[str],

0 commit comments

Comments
 (0)