Merge pull request #5363 from matrix-org/babolivier/account_validity_send_mail_auth

Don't check whether the user's account is expired on /send_mail requests
pull/5376/head
Brendan Abolivier 2019-06-10 11:57:02 +01:00 committed by GitHub
commit 26b62796c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 3 deletions

1
changelog.d/5363.feature Normal file
View File

@ -0,0 +1 @@
Allow expired user to trigger renewal email sending manually.

View File

@ -184,11 +184,22 @@ class Auth(object):
return event_auth.get_public_keys(invite_event) return event_auth.get_public_keys(invite_event)
@defer.inlineCallbacks @defer.inlineCallbacks
def get_user_by_req(self, request, allow_guest=False, rights="access"): def get_user_by_req(
self,
request,
allow_guest=False,
rights="access",
allow_expired=False,
):
""" Get a registered user's ID. """ Get a registered user's ID.
Args: Args:
request - An HTTP request with an access_token query parameter. request - An HTTP request with an access_token query parameter.
allow_expired - Whether to allow the request through even if the account is
expired. If true, Synapse will still require an access token to be
provided but won't check if the account it belongs to has expired. This
works thanks to /login delivering access tokens regardless of accounts'
expiration.
Returns: Returns:
defer.Deferred: resolves to a ``synapse.types.Requester`` object defer.Deferred: resolves to a ``synapse.types.Requester`` object
Raises: Raises:
@ -229,7 +240,7 @@ class Auth(object):
is_guest = user_info["is_guest"] is_guest = user_info["is_guest"]
# Deny the request if the user account has expired. # Deny the request if the user account has expired.
if self._account_validity.enabled: if self._account_validity.enabled and not allow_expired:
user_id = user.to_string() user_id = user.to_string()
expiration_ts = yield self.store.get_expiration_ts_for_user(user_id) expiration_ts = yield self.store.get_expiration_ts_for_user(user_id)
if expiration_ts is not None and self.clock.time_msec() >= expiration_ts: if expiration_ts is not None and self.clock.time_msec() >= expiration_ts:

View File

@ -79,7 +79,7 @@ class AccountValiditySendMailServlet(RestServlet):
if not self.account_validity.renew_by_email_enabled: if not self.account_validity.renew_by_email_enabled:
raise AuthError(403, "Account renewal via email is disabled on this server.") raise AuthError(403, "Account renewal via email is disabled on this server.")
requester = yield self.auth.get_user_by_req(request) requester = yield self.auth.get_user_by_req(request, allow_expired=True)
user_id = requester.user.to_string() user_id = requester.user.to_string()
yield self.account_activity_handler.send_renewal_email_to_user(user_id) yield self.account_activity_handler.send_renewal_email_to_user(user_id)

View File

@ -427,6 +427,41 @@ class AccountValidityRenewalByEmailTestCase(unittest.HomeserverTestCase):
self.assertEqual(len(self.email_attempts), 1) self.assertEqual(len(self.email_attempts), 1)
def test_manual_email_send_expired_account(self):
user_id = self.register_user("kermit", "monkey")
tok = self.login("kermit", "monkey")
# We need to manually add an email address otherwise the handler will do
# nothing.
now = self.hs.clock.time_msec()
self.get_success(
self.store.user_add_threepid(
user_id=user_id,
medium="email",
address="kermit@example.com",
validated_at=now,
added_at=now,
)
)
# Make the account expire.
self.reactor.advance(datetime.timedelta(days=8).total_seconds())
# Ignore all emails sent by the automatic background task and only focus on the
# ones sent manually.
self.email_attempts = []
# Test that we're still able to manually trigger a mail to be sent.
request, channel = self.make_request(
b"POST",
"/_matrix/client/unstable/account_validity/send_mail",
access_token=tok,
)
self.render(request)
self.assertEquals(channel.result["code"], b"200", channel.result)
self.assertEqual(len(self.email_attempts), 1)
class AccountValidityBackgroundJobTestCase(unittest.HomeserverTestCase): class AccountValidityBackgroundJobTestCase(unittest.HomeserverTestCase):