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

Commit

Permalink
Add endpoint for manual account expiry
Browse files Browse the repository at this point in the history
  • Loading branch information
babolivier committed Apr 17, 2019
1 parent 9496969 commit 0650483
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 17 deletions.
21 changes: 21 additions & 0 deletions synapse/handlers/account_validity.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ def renew_account_for_user(self, user_id):
Args:
renewal_token (str): Token sent with the renewal request.
Returns:
defer.Deferred[int]: New expiration date for this account, as a timestamp
in milliseconds since epoch.
"""
new_expiration_date = self.clock.time_msec() + self._account_validity.period

Expand All @@ -241,3 +245,20 @@ def renew_account_for_user(self, user_id):
expiration_ts=new_expiration_date,
email_sent=False,
)

defer.returnValue(new_expiration_date)

@defer.inlineCallbacks
def expire_account(self, user_id):
"""Expire user account by setting its expiration date to the current time,
and disabling email sending, as well as invalidating its existing renewal token,
if any.
Args:
user_id (str): ID of the account to expire.
"""
yield self.store.set_account_validity_for_user(
user_id=user_id,
expiration_ts=self.clock.time_msec(),
email_sent=True,
)
26 changes: 24 additions & 2 deletions synapse/rest/client/v1/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ def on_GET(self, request, target_user_id):


class AccountValidityRenewServlet(ClientV1RestServlet):
PATTERNS = client_path_patterns("/admin/account_validity/renew$")
PATTERNS = client_path_patterns("/admin/account_validity/validity$")

def __init__(self, hs):
"""
Expand All @@ -813,7 +813,29 @@ def on_POST(self, request):
if "user_id" not in body:
raise SynapseError(400, "Missing property 'user_id' in the request body")

yield self.account_activity_handler.renew_account_for_user(body["user_id"])
expiration_ts = yield self.account_activity_handler.renew_account_for_user(
body["user_id"],
)

res = {
"expiration_ts": expiration_ts,
}
defer.returnValue((200, res))

@defer.inlineCallbacks
def on_DELETE(self, request):
requester = yield self.auth.get_user_by_req(request)
is_admin = yield self.auth.is_server_admin(requester.user)

if not is_admin:
raise AuthError(403, "You are not a server admin")

body = parse_json_object_from_request(request)

if "user_id" not in body:
raise SynapseError(400, "Missing property 'user_id' in the request body")

yield self.account_activity_handler.expire_account(body["user_id"])

defer.returnValue((200, {}))

Expand Down
43 changes: 28 additions & 15 deletions tests/rest/client/v2_alpha/test_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,25 @@ def test_manual_renewal(self):
user_id = self.register_user("kermit", "monkey")
tok = self.login("kermit", "monkey")

self.reactor.advance(datetime.timedelta(weeks=1).total_seconds())

# If we register the admin user at the beginning of the test, it will
# expire at the same time as the normal user and the renewal request
# will be denied.
self.register_user("admin", "adminpassword", admin=True)
admin_tok = self.login("admin", "adminpassword")

url = "/_matrix/client/unstable/admin/account_validity/validity"
params = {
"user_id": user_id,
}
request_data = json.dumps(params)
request, channel = self.make_request(
b"POST", url, request_data, access_token=admin_tok,
)
self.render(request)
self.assertEquals(channel.result["code"], b"200", channel.result)

# The specific endpoint doesn't matter, all we need is an authenticated
# endpoint.
request, channel = self.make_request(
Expand All @@ -251,21 +270,20 @@ def test_manual_renewal(self):
self.render(request)
self.assertEquals(channel.result["code"], b"200", channel.result)

self.reactor.advance(datetime.timedelta(weeks=1).total_seconds())
def test_manual_expire(self):
user_id = self.register_user("kermit", "monkey")
tok = self.login("kermit", "monkey")

# If we register the admin user at the beginning of the test, it will
# expire at the same time as the normal user and the renewal request
# will be denied.
self.register_user("admin", "adminpassword", admin=True)
admin_tok = self.login("admin", "adminpassword")

url = "/_matrix/client/unstable/account_validity/renew"
url = "/_matrix/client/unstable/admin/account_validity/validity"
params = {
"user_id": user_id,
}
request_data = json.dumps(params)
request, channel = self.make_request(
b"POST", url, request_data, access_token=admin_tok,
b"DELETE", url, request_data, access_token=admin_tok,
)
self.render(request)
self.assertEquals(channel.result["code"], b"200", channel.result)
Expand All @@ -276,7 +294,10 @@ def test_manual_renewal(self):
b"GET", "/sync", access_token=tok,
)
self.render(request)
self.assertEquals(channel.result["code"], b"200", channel.result)
self.assertEquals(channel.result["code"], b"403", channel.result)
self.assertEquals(
channel.json_body["errcode"], Codes.EXPIRED_ACCOUNT, channel.result,
)


class AccountValidityRenewalByEmailTestCase(unittest.HomeserverTestCase):
Expand Down Expand Up @@ -339,14 +360,6 @@ def test_renewal_email(self):
validated_at=now, added_at=now,
))

# The specific endpoint doesn't matter, all we need is an authenticated
# endpoint.
request, channel = self.make_request(
b"GET", "/sync", access_token=tok,
)
self.render(request)
self.assertEquals(channel.result["code"], b"200", channel.result)

# Move 6 days forward. This should trigger a renewal email to be sent.
self.reactor.advance(datetime.timedelta(days=6).total_seconds())
self.assertEqual(len(self.email_attempts), 1)
Expand Down

0 comments on commit 0650483

Please sign in to comment.