From 385aec401015b12b763f630abf48ad2b8b30649c Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 8 Jul 2016 17:42:48 +0100 Subject: [PATCH 1/6] Implement https://github.com/matrix-org/matrix-doc/pull/346/files --- synapse/api/errors.py | 1 + synapse/rest/client/v2_alpha/account.py | 59 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/synapse/api/errors.py b/synapse/api/errors.py index b219b46a4b..0041646858 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -43,6 +43,7 @@ class Codes(object): EXCLUSIVE = "M_EXCLUSIVE" THREEPID_AUTH_FAILED = "M_THREEPID_AUTH_FAILED" THREEPID_IN_USE = "M_THREEPID_IN_USE" + THREEPID_NOT_FOUND = "M_THREEPID_NOT_FOUND" INVALID_USERNAME = "M_INVALID_USERNAME" SERVER_NOT_TRUSTED = "M_SERVER_NOT_TRUSTED" diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 9a84873a5f..1c37f91312 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -36,11 +36,16 @@ class PasswordRestServlet(RestServlet): self.hs = hs self.auth = hs.get_auth() self.auth_handler = hs.get_auth_handler() + self.identity_handler = hs.get_handlers().identity_handler @defer.inlineCallbacks def on_POST(self, request): yield run_on_reactor() + if '/account/password/email/requestToken' in request.path: + ret = yield self.onPasswordEmailTokenRequest(request) + defer.returnValue(ret) + body = parse_json_object_from_request(request) authed, result, params, _ = yield self.auth_handler.check_auth([ @@ -85,6 +90,29 @@ class PasswordRestServlet(RestServlet): defer.returnValue((200, {})) + @defer.inlineCallbacks + def onPasswordEmailTokenRequest(self, request): + body = parse_json_object_from_request(request) + + required = ['id_server', 'client_secret', 'email', 'send_attempt'] + absent = [] + for k in required: + if k not in body: + absent.append(k) + + if len(absent) > 0: + raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) + + existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( + 'email', body['email'] + ) + + if existingUid is None: + raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND) + + ret = yield self.identity_handler.requestEmailToken(**body) + defer.returnValue((200, ret)) + def on_OPTIONS(self, _): return 200, {} @@ -115,6 +143,10 @@ class ThreepidRestServlet(RestServlet): def on_POST(self, request): yield run_on_reactor() + if '/account/3pid/email/requestToken' in request.path: + ret = yield self.onThreepidEmailTokenRequest(request) + defer.returnValue(ret) + body = parse_json_object_from_request(request) threePidCreds = body.get('threePidCreds') @@ -155,6 +187,33 @@ class ThreepidRestServlet(RestServlet): defer.returnValue((200, {})) + @defer.inlineCallbacks + def onThreepidEmailTokenRequest(self, request): + body = parse_json_object_from_request(request) + + logger.error("hi") + + required = ['id_server', 'client_secret', 'email', 'send_attempt'] + absent = [] + for k in required: + if k not in body: + absent.append(k) + + if len(absent) > 0: + raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) + + existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( + 'email', body['email'] + ) + + logger.error("existing %r", existingUid) + + if existingUid is not None: + raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) + + ret = yield self.identity_handler.requestEmailToken(**body) + defer.returnValue((200, ret)) + def register_servlets(hs, http_server): PasswordRestServlet(hs).register(http_server) From 9c491366c51b2a0ed23e1f3ead80b7ac4307d46f Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 11 Jul 2016 09:07:40 +0100 Subject: [PATCH 2/6] Oops, remove debug logging --- synapse/rest/client/v2_alpha/account.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 1c37f91312..e2bbfc9d93 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -191,8 +191,6 @@ class ThreepidRestServlet(RestServlet): def onThreepidEmailTokenRequest(self, request): body = parse_json_object_from_request(request) - logger.error("hi") - required = ['id_server', 'client_secret', 'email', 'send_attempt'] absent = [] for k in required: @@ -206,8 +204,6 @@ class ThreepidRestServlet(RestServlet): 'email', body['email'] ) - logger.error("existing %r", existingUid) - if existingUid is not None: raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) From a5db0026ede13159e340db8612bf4cafba8f6ab6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 11 Jul 2016 09:57:07 +0100 Subject: [PATCH 3/6] Separate out requestTokens to separate handlers --- synapse/rest/client/v2_alpha/account.py | 93 ++++++++++++++---------- synapse/rest/client/v2_alpha/register.py | 65 ++++++++++------- 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index e2bbfc9d93..8a53617629 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -28,24 +28,54 @@ import logging logger = logging.getLogger(__name__) +class PasswordRequestTokenRestServlet(RestServlet): + PATTERNS = client_v2_patterns("/account/password/email/requestToken$") + + def __init__(self, hs): + super(PasswordRequestTokenRestServlet, self).__init__() + self.hs = hs + self.identity_handler = hs.get_handlers().identity_handler + + @defer.inlineCallbacks + def on_POST(self, request): + body = parse_json_object_from_request(request) + + required = ['id_server', 'client_secret', 'email', 'send_attempt'] + absent = [] + for k in required: + if k not in body: + absent.append(k) + + if len(absent) > 0: + raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) + + existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( + 'email', body['email'] + ) + + if existingUid is None: + raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND) + + ret = yield self.identity_handler.requestEmailToken(**body) + defer.returnValue((200, ret)) + + def on_OPTIONS(self, _): + return 200, {} + + class PasswordRestServlet(RestServlet): - PATTERNS = client_v2_patterns("/account/password") + PATTERNS = client_v2_patterns("/account/password$") def __init__(self, hs): super(PasswordRestServlet, self).__init__() self.hs = hs self.auth = hs.get_auth() self.auth_handler = hs.get_auth_handler() - self.identity_handler = hs.get_handlers().identity_handler @defer.inlineCallbacks def on_POST(self, request): yield run_on_reactor() - if '/account/password/email/requestToken' in request.path: - ret = yield self.onPasswordEmailTokenRequest(request) - defer.returnValue(ret) - body = parse_json_object_from_request(request) authed, result, params, _ = yield self.auth_handler.check_auth([ @@ -90,8 +120,20 @@ class PasswordRestServlet(RestServlet): defer.returnValue((200, {})) + def on_OPTIONS(self, _): + return 200, {} + + +class ThreepidRequestTokenRestServlet(RestServlet): + PATTERNS = client_v2_patterns("/account/3pid/email/requestToken$") + + def __init__(self, hs): + self.hs = hs + super(ThreepidRequestTokenRestServlet, self).__init__() + self.identity_handler = hs.get_handlers().identity_handler + @defer.inlineCallbacks - def onPasswordEmailTokenRequest(self, request): + def on_POST(self, request): body = parse_json_object_from_request(request) required = ['id_server', 'client_secret', 'email', 'send_attempt'] @@ -107,8 +149,10 @@ class PasswordRestServlet(RestServlet): 'email', body['email'] ) - if existingUid is None: - raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND) + logger.error("existing %r", existingUid) + + if existingUid is not None: + raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) ret = yield self.identity_handler.requestEmailToken(**body) defer.returnValue((200, ret)) @@ -118,7 +162,7 @@ class PasswordRestServlet(RestServlet): class ThreepidRestServlet(RestServlet): - PATTERNS = client_v2_patterns("/account/3pid") + PATTERNS = client_v2_patterns("/account/3pid$") def __init__(self, hs): super(ThreepidRestServlet, self).__init__() @@ -143,10 +187,6 @@ class ThreepidRestServlet(RestServlet): def on_POST(self, request): yield run_on_reactor() - if '/account/3pid/email/requestToken' in request.path: - ret = yield self.onThreepidEmailTokenRequest(request) - defer.returnValue(ret) - body = parse_json_object_from_request(request) threePidCreds = body.get('threePidCreds') @@ -187,30 +227,9 @@ class ThreepidRestServlet(RestServlet): defer.returnValue((200, {})) - @defer.inlineCallbacks - def onThreepidEmailTokenRequest(self, request): - body = parse_json_object_from_request(request) - - required = ['id_server', 'client_secret', 'email', 'send_attempt'] - absent = [] - for k in required: - if k not in body: - absent.append(k) - - if len(absent) > 0: - raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) - - existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( - 'email', body['email'] - ) - - if existingUid is not None: - raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) - - ret = yield self.identity_handler.requestEmailToken(**body) - defer.returnValue((200, ret)) - def register_servlets(hs, http_server): + PasswordRequestTokenRestServlet(hs).register(http_server) PasswordRestServlet(hs).register(http_server) + ThreepidRequestTokenRestServlet(hs).register(http_server) ThreepidRestServlet(hs).register(http_server) diff --git a/synapse/rest/client/v2_alpha/register.py b/synapse/rest/client/v2_alpha/register.py index 2088c316d1..e5944b99b1 100644 --- a/synapse/rest/client/v2_alpha/register.py +++ b/synapse/rest/client/v2_alpha/register.py @@ -41,8 +41,43 @@ else: logger = logging.getLogger(__name__) +class RegisterRequestTokenRestServlet(RestServlet): + PATTERNS = client_v2_patterns("/register/email/requestToken$") + + def __init__(self, hs): + super(RegisterRequestTokenRestServlet, self).__init__() + self.hs = hs + self.identity_handler = hs.get_handlers().identity_handler + + @defer.inlineCallbacks + def on_POST(self, request): + body = parse_json_object_from_request(request) + + required = ['id_server', 'client_secret', 'email', 'send_attempt'] + absent = [] + for k in required: + if k not in body: + absent.append(k) + + if len(absent) > 0: + raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) + + existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( + 'email', body['email'] + ) + + if existingUid is not None: + raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) + + ret = yield self.identity_handler.requestEmailToken(**body) + defer.returnValue((200, ret)) + + def on_OPTIONS(self, _): + return 200, {} + + class RegisterRestServlet(RestServlet): - PATTERNS = client_v2_patterns("/register") + PATTERNS = client_v2_patterns("/register$") def __init__(self, hs): super(RegisterRestServlet, self).__init__() @@ -70,10 +105,6 @@ class RegisterRestServlet(RestServlet): "Do not understand membership kind: %s" % (kind,) ) - if '/register/email/requestToken' in request.path: - ret = yield self.onEmailTokenRequest(request) - defer.returnValue(ret) - body = parse_json_object_from_request(request) # we do basic sanity checks here because the auth layer will store these @@ -305,29 +336,6 @@ class RegisterRestServlet(RestServlet): "refresh_token": refresh_token, }) - @defer.inlineCallbacks - def onEmailTokenRequest(self, request): - body = parse_json_object_from_request(request) - - required = ['id_server', 'client_secret', 'email', 'send_attempt'] - absent = [] - for k in required: - if k not in body: - absent.append(k) - - if len(absent) > 0: - raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) - - existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( - 'email', body['email'] - ) - - if existingUid is not None: - raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) - - ret = yield self.identity_handler.requestEmailToken(**body) - defer.returnValue((200, ret)) - @defer.inlineCallbacks def _do_guest_registration(self): if not self.hs.config.allow_guest_access: @@ -345,4 +353,5 @@ class RegisterRestServlet(RestServlet): def register_servlets(hs, http_server): + RegisterRequestTokenRestServlet(hs).register(http_server) RegisterRestServlet(hs).register(http_server) From 75fa7f6b3ceae5cf1eeda8f28149796eecdcd133 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 12 Jul 2016 14:08:57 +0100 Subject: [PATCH 4/6] Remove other debug logging --- synapse/rest/client/v2_alpha/account.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 8a53617629..d85b2d08aa 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -149,8 +149,6 @@ class ThreepidRequestTokenRestServlet(RestServlet): 'email', body['email'] ) - logger.error("existing %r", existingUid) - if existingUid is not None: raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) From aaa9d9f0e1d761655c4976a45a76dfba31f067de Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 12 Jul 2016 14:13:14 +0100 Subject: [PATCH 5/6] on_OPTIONS isn't neccessary --- synapse/rest/client/v2_alpha/account.py | 8 +------- synapse/rest/client/v2_alpha/register.py | 3 --- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index d85b2d08aa..64e9ae0c45 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -46,7 +46,7 @@ class PasswordRequestTokenRestServlet(RestServlet): if k not in body: absent.append(k) - if len(absent) > 0: + if absent: raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( @@ -59,9 +59,6 @@ class PasswordRequestTokenRestServlet(RestServlet): ret = yield self.identity_handler.requestEmailToken(**body) defer.returnValue((200, ret)) - def on_OPTIONS(self, _): - return 200, {} - class PasswordRestServlet(RestServlet): PATTERNS = client_v2_patterns("/account/password$") @@ -155,9 +152,6 @@ class ThreepidRequestTokenRestServlet(RestServlet): ret = yield self.identity_handler.requestEmailToken(**body) defer.returnValue((200, ret)) - def on_OPTIONS(self, _): - return 200, {} - class ThreepidRestServlet(RestServlet): PATTERNS = client_v2_patterns("/account/3pid$") diff --git a/synapse/rest/client/v2_alpha/register.py b/synapse/rest/client/v2_alpha/register.py index e5944b99b1..7c6d2942dc 100644 --- a/synapse/rest/client/v2_alpha/register.py +++ b/synapse/rest/client/v2_alpha/register.py @@ -72,9 +72,6 @@ class RegisterRequestTokenRestServlet(RestServlet): ret = yield self.identity_handler.requestEmailToken(**body) defer.returnValue((200, ret)) - def on_OPTIONS(self, _): - return 200, {} - class RegisterRestServlet(RestServlet): PATTERNS = client_v2_patterns("/register$") From c55ad2e3755487727e8760e7aab2fc21182d5948 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 12 Jul 2016 14:15:10 +0100 Subject: [PATCH 6/6] be more pythonic --- synapse/rest/client/v2_alpha/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 64e9ae0c45..47f78eba8c 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -139,7 +139,7 @@ class ThreepidRequestTokenRestServlet(RestServlet): if k not in body: absent.append(k) - if len(absent) > 0: + if absent: raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) existingUid = yield self.hs.get_datastore().get_user_id_by_threepid(