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 ._base import BaseHandler
|
||||||
from synapse.api.errors import LoginError, Codes
|
from synapse.api.errors import LoginError, Codes
|
||||||
|
from synapse.http.client import PlainHttpClient
|
||||||
|
|
||||||
import bcrypt
|
import bcrypt
|
||||||
import logging
|
import logging
|
||||||
|
import urllib
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -63,3 +65,28 @@ class LoginHandler(BaseHandler):
|
||||||
else:
|
else:
|
||||||
logger.warn("Failed password login for user %s", user)
|
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, {})
|
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):
|
def _parse_json(request):
|
||||||
try:
|
try:
|
||||||
content = json.loads(request.content.read())
|
content = json.loads(request.content.read())
|
||||||
|
@ -85,3 +106,4 @@ def _parse_json(request):
|
||||||
|
|
||||||
def register_servlets(hs, http_server):
|
def register_servlets(hs, http_server):
|
||||||
LoginRestServlet(hs).register(http_server)
|
LoginRestServlet(hs).register(http_server)
|
||||||
|
PasswordResetRestServlet(hs).register(http_server)
|
||||||
|
|
Loading…
Reference in New Issue