Added PasswordResetRestServlet. Hit the IS to confirm the email/user. Need to send email.
							parent
							
								
									faee41c303
								
							
						
					
					
						commit
						5f30a69a9e
					
				|  | @ -17,9 +17,11 @@ from twisted.internet import defer | |||
| 
 | ||||
| from ._base import BaseHandler | ||||
| from synapse.api.errors import LoginError, Codes | ||||
| from synapse.http.client import PlainHttpClient | ||||
| 
 | ||||
| import bcrypt | ||||
| import logging | ||||
| import urllib | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
|  | @ -62,4 +64,29 @@ class LoginHandler(BaseHandler): | |||
|             defer.returnValue(token) | ||||
|         else: | ||||
|             logger.warn("Failed password login for user %s", user) | ||||
|             raise LoginError(403, "", errcode=Codes.FORBIDDEN) | ||||
|             raise LoginError(403, "", errcode=Codes.FORBIDDEN) | ||||
| 
 | ||||
|     @defer.inlineCallbacks | ||||
|     def reset_password(self, user_id, email): | ||||
|         is_valid = yield self._check_valid_association(user_id, email) | ||||
|         logger.info("reset_password user=%s email=%s valid=%s", user_id, email, | ||||
|                     is_valid) | ||||
| 
 | ||||
|     @defer.inlineCallbacks | ||||
|     def _check_valid_association(self, user_id, email): | ||||
|         identity = yield self._query_email(email) | ||||
|         if identity and "mxid" in identity: | ||||
|             if identity["mxid"] == user_id: | ||||
|                 defer.returnValue(True) | ||||
|                 return | ||||
|         defer.returnValue(False) | ||||
| 
 | ||||
|     @defer.inlineCallbacks | ||||
|     def _query_email(self, email): | ||||
|         httpCli = PlainHttpClient(self.hs) | ||||
|         data = yield httpCli.get_json( | ||||
|             'matrix.org:8090',  # TODO FIXME This should be configurable. | ||||
|             "/_matrix/identity/api/v1/lookup?medium=email&address=" + | ||||
|             "%s" % urllib.quote(email) | ||||
|         ) | ||||
|         defer.returnValue(data) | ||||
|  | @ -73,6 +73,27 @@ class LoginFallbackRestServlet(RestServlet): | |||
|         return (200, {}) | ||||
| 
 | ||||
| 
 | ||||
| class PasswordResetRestServlet(RestServlet): | ||||
|     PATTERN = client_path_pattern("/login/reset") | ||||
| 
 | ||||
|     @defer.inlineCallbacks | ||||
|     def on_POST(self, request): | ||||
|         reset_info = _parse_json(request) | ||||
|         try: | ||||
|             email = reset_info["email"] | ||||
|             user_id = reset_info["user_id"] | ||||
|             handler = self.handlers.login_handler | ||||
|             yield handler.reset_password(user_id, email) | ||||
|             # purposefully give no feedback to avoid people hammering different | ||||
|             # combinations. | ||||
|             defer.returnValue((200, {})) | ||||
|         except KeyError: | ||||
|             raise SynapseError( | ||||
|                 400, | ||||
|                 "Missing keys. Requires 'email' and 'user_id'." | ||||
|             ) | ||||
| 
 | ||||
| 
 | ||||
| def _parse_json(request): | ||||
|     try: | ||||
|         content = json.loads(request.content.read()) | ||||
|  | @ -85,3 +106,4 @@ def _parse_json(request): | |||
| 
 | ||||
| def register_servlets(hs, http_server): | ||||
|     LoginRestServlet(hs).register(http_server) | ||||
|     PasswordResetRestServlet(hs).register(http_server) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Kegan Dougal
						Kegan Dougal