15
15
import email .mime .multipart
16
16
import email .utils
17
17
import logging
18
- from typing import TYPE_CHECKING , Awaitable , Callable , List , Optional , Tuple
19
-
20
- from twisted .web .http import Request
18
+ from typing import TYPE_CHECKING , List , Optional , Tuple
21
19
22
20
from synapse .api .errors import AuthError , StoreError , SynapseError
23
21
from synapse .metrics .background_process_metrics import wrap_as_background_process
30
28
31
29
logger = logging .getLogger (__name__ )
32
30
33
- # Types for callbacks to be registered via the module api
34
- IS_USER_EXPIRED_CALLBACK = Callable [[str ], Awaitable [Optional [bool ]]]
35
- ON_USER_REGISTRATION_CALLBACK = Callable [[str ], Awaitable ]
36
- # Temporary hooks to allow for a transition from `/_matrix/client` endpoints
37
- # to `/_synapse/client/account_validity`. See `register_account_validity_callbacks`.
38
- ON_LEGACY_SEND_MAIL_CALLBACK = Callable [[str ], Awaitable ]
39
- ON_LEGACY_RENEW_CALLBACK = Callable [[str ], Awaitable [Tuple [bool , bool , int ]]]
40
- ON_LEGACY_ADMIN_REQUEST = Callable [[Request ], Awaitable ]
41
-
42
31
43
32
class AccountValidityHandler :
44
33
def __init__ (self , hs : "HomeServer" ):
45
34
self .hs = hs
46
35
self .config = hs .config
47
- self .store = self . hs .get_datastores ().main
48
- self .send_email_handler = self . hs .get_send_email_handler ()
49
- self .clock = self . hs .get_clock ()
36
+ self .store = hs .get_datastores ().main
37
+ self .send_email_handler = hs .get_send_email_handler ()
38
+ self .clock = hs .get_clock ()
50
39
51
- self ._app_name = self .hs .config .email .email_app_name
40
+ self ._app_name = hs .config .email .email_app_name
41
+ self ._module_api_callbacks = hs .get_module_api_callbacks ().account_validity
52
42
53
43
self ._account_validity_enabled = (
54
44
hs .config .account_validity .account_validity_enabled
@@ -78,69 +68,6 @@ def __init__(self, hs: "HomeServer"):
78
68
if hs .config .worker .run_background_tasks :
79
69
self .clock .looping_call (self ._send_renewal_emails , 30 * 60 * 1000 )
80
70
81
- self ._is_user_expired_callbacks : List [IS_USER_EXPIRED_CALLBACK ] = []
82
- self ._on_user_registration_callbacks : List [ON_USER_REGISTRATION_CALLBACK ] = []
83
- self ._on_legacy_send_mail_callback : Optional [
84
- ON_LEGACY_SEND_MAIL_CALLBACK
85
- ] = None
86
- self ._on_legacy_renew_callback : Optional [ON_LEGACY_RENEW_CALLBACK ] = None
87
-
88
- # The legacy admin requests callback isn't a protected attribute because we need
89
- # to access it from the admin servlet, which is outside of this handler.
90
- self .on_legacy_admin_request_callback : Optional [ON_LEGACY_ADMIN_REQUEST ] = None
91
-
92
- def register_account_validity_callbacks (
93
- self ,
94
- is_user_expired : Optional [IS_USER_EXPIRED_CALLBACK ] = None ,
95
- on_user_registration : Optional [ON_USER_REGISTRATION_CALLBACK ] = None ,
96
- on_legacy_send_mail : Optional [ON_LEGACY_SEND_MAIL_CALLBACK ] = None ,
97
- on_legacy_renew : Optional [ON_LEGACY_RENEW_CALLBACK ] = None ,
98
- on_legacy_admin_request : Optional [ON_LEGACY_ADMIN_REQUEST ] = None ,
99
- ) -> None :
100
- """Register callbacks from module for each hook."""
101
- if is_user_expired is not None :
102
- self ._is_user_expired_callbacks .append (is_user_expired )
103
-
104
- if on_user_registration is not None :
105
- self ._on_user_registration_callbacks .append (on_user_registration )
106
-
107
- # The builtin account validity feature exposes 3 endpoints (send_mail, renew, and
108
- # an admin one). As part of moving the feature into a module, we need to change
109
- # the path from /_matrix/client/unstable/account_validity/... to
110
- # /_synapse/client/account_validity, because:
111
- #
112
- # * the feature isn't part of the Matrix spec thus shouldn't live under /_matrix
113
- # * the way we register servlets means that modules can't register resources
114
- # under /_matrix/client
115
- #
116
- # We need to allow for a transition period between the old and new endpoints
117
- # in order to allow for clients to update (and for emails to be processed).
118
- #
119
- # Once the email-account-validity module is loaded, it will take control of account
120
- # validity by moving the rows from our `account_validity` table into its own table.
121
- #
122
- # Therefore, we need to allow modules (in practice just the one implementing the
123
- # email-based account validity) to temporarily hook into the legacy endpoints so we
124
- # can route the traffic coming into the old endpoints into the module, which is
125
- # why we have the following three temporary hooks.
126
- if on_legacy_send_mail is not None :
127
- if self ._on_legacy_send_mail_callback is not None :
128
- raise RuntimeError ("Tried to register on_legacy_send_mail twice" )
129
-
130
- self ._on_legacy_send_mail_callback = on_legacy_send_mail
131
-
132
- if on_legacy_renew is not None :
133
- if self ._on_legacy_renew_callback is not None :
134
- raise RuntimeError ("Tried to register on_legacy_renew twice" )
135
-
136
- self ._on_legacy_renew_callback = on_legacy_renew
137
-
138
- if on_legacy_admin_request is not None :
139
- if self .on_legacy_admin_request_callback is not None :
140
- raise RuntimeError ("Tried to register on_legacy_admin_request twice" )
141
-
142
- self .on_legacy_admin_request_callback = on_legacy_admin_request
143
-
144
71
async def is_user_expired (self , user_id : str ) -> bool :
145
72
"""Checks if a user has expired against third-party modules.
146
73
@@ -150,7 +77,7 @@ async def is_user_expired(self, user_id: str) -> bool:
150
77
Returns:
151
78
Whether the user has expired.
152
79
"""
153
- for callback in self ._is_user_expired_callbacks :
80
+ for callback in self ._module_api_callbacks . is_user_expired_callbacks :
154
81
expired = await delay_cancellation (callback (user_id ))
155
82
if expired is not None :
156
83
return expired
@@ -168,7 +95,7 @@ async def on_user_registration(self, user_id: str) -> None:
168
95
Args:
169
96
user_id: The ID of the newly registered user.
170
97
"""
171
- for callback in self ._on_user_registration_callbacks :
98
+ for callback in self ._module_api_callbacks . on_user_registration_callbacks :
172
99
await callback (user_id )
173
100
174
101
@wrap_as_background_process ("send_renewals" )
@@ -198,8 +125,8 @@ async def send_renewal_email_to_user(self, user_id: str) -> None:
198
125
"""
199
126
# If a module supports sending a renewal email from here, do that, otherwise do
200
127
# the legacy dance.
201
- if self ._on_legacy_send_mail_callback is not None :
202
- await self ._on_legacy_send_mail_callback (user_id )
128
+ if self ._module_api_callbacks . on_legacy_send_mail_callback is not None :
129
+ await self ._module_api_callbacks . on_legacy_send_mail_callback (user_id )
203
130
return
204
131
205
132
if not self ._account_validity_renew_by_email_enabled :
@@ -336,8 +263,10 @@ async def renew_account(self, renewal_token: str) -> Tuple[bool, bool, int]:
336
263
"""
337
264
# If a module supports triggering a renew from here, do that, otherwise do the
338
265
# legacy dance.
339
- if self ._on_legacy_renew_callback is not None :
340
- return await self ._on_legacy_renew_callback (renewal_token )
266
+ if self ._module_api_callbacks .on_legacy_renew_callback is not None :
267
+ return await self ._module_api_callbacks .on_legacy_renew_callback (
268
+ renewal_token
269
+ )
341
270
342
271
try :
343
272
(
0 commit comments