Merge pull request #2183 from matrix-org/luke/username-availability
Implement username availability checkerpull/2186/head
commit
6aa423a1a8
|
@ -31,6 +31,7 @@ import logging
|
||||||
import hmac
|
import hmac
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
from synapse.util.async import run_on_reactor
|
from synapse.util.async import run_on_reactor
|
||||||
|
from synapse.util.ratelimitutils import FederationRateLimiter
|
||||||
|
|
||||||
|
|
||||||
# We ought to be using hmac.compare_digest() but on older pythons it doesn't
|
# We ought to be using hmac.compare_digest() but on older pythons it doesn't
|
||||||
|
@ -115,6 +116,45 @@ class MsisdnRegisterRequestTokenRestServlet(RestServlet):
|
||||||
defer.returnValue((200, ret))
|
defer.returnValue((200, ret))
|
||||||
|
|
||||||
|
|
||||||
|
class UsernameAvailabilityRestServlet(RestServlet):
|
||||||
|
PATTERNS = client_v2_patterns("/register/available")
|
||||||
|
|
||||||
|
def __init__(self, hs):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
hs (synapse.server.HomeServer): server
|
||||||
|
"""
|
||||||
|
super(UsernameAvailabilityRestServlet, self).__init__()
|
||||||
|
self.hs = hs
|
||||||
|
self.registration_handler = hs.get_handlers().registration_handler
|
||||||
|
self.ratelimiter = FederationRateLimiter(
|
||||||
|
hs.get_clock(),
|
||||||
|
# Time window of 2s
|
||||||
|
window_size=2000,
|
||||||
|
# Artificially delay requests if rate > sleep_limit/window_size
|
||||||
|
sleep_limit=1,
|
||||||
|
# Amount of artificial delay to apply
|
||||||
|
sleep_msec=1000,
|
||||||
|
# Error with 429 if more than reject_limit requests are queued
|
||||||
|
reject_limit=1,
|
||||||
|
# Allow 1 request at a time
|
||||||
|
concurrent_requests=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def on_GET(self, request):
|
||||||
|
ip = self.hs.get_ip_from_request(request)
|
||||||
|
with self.ratelimiter.ratelimit(ip) as wait_deferred:
|
||||||
|
yield wait_deferred
|
||||||
|
|
||||||
|
body = parse_json_object_from_request(request)
|
||||||
|
assert_params_in_request(body, ['username'])
|
||||||
|
|
||||||
|
yield self.registration_handler.check_username(body['username'])
|
||||||
|
|
||||||
|
defer.returnValue((200, {"available": True}))
|
||||||
|
|
||||||
|
|
||||||
class RegisterRestServlet(RestServlet):
|
class RegisterRestServlet(RestServlet):
|
||||||
PATTERNS = client_v2_patterns("/register$")
|
PATTERNS = client_v2_patterns("/register$")
|
||||||
|
|
||||||
|
@ -555,4 +595,5 @@ class RegisterRestServlet(RestServlet):
|
||||||
def register_servlets(hs, http_server):
|
def register_servlets(hs, http_server):
|
||||||
EmailRegisterRequestTokenRestServlet(hs).register(http_server)
|
EmailRegisterRequestTokenRestServlet(hs).register(http_server)
|
||||||
MsisdnRegisterRequestTokenRestServlet(hs).register(http_server)
|
MsisdnRegisterRequestTokenRestServlet(hs).register(http_server)
|
||||||
|
UsernameAvailabilityRestServlet(hs).register(http_server)
|
||||||
RegisterRestServlet(hs).register(http_server)
|
RegisterRestServlet(hs).register(http_server)
|
||||||
|
|
Loading…
Reference in New Issue