diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py
index 1f927e67ad..7b0ab4829b 100644
--- a/synapse/handlers/auth.py
+++ b/synapse/handlers/auth.py
@@ -195,12 +195,18 @@ class AuthHandler(BaseHandler):
def _check_email_identity(self, authdict, _):
yield run_on_reactor()
+ if 'threepidCreds' not in authdict:
+ raise LoginError(400, "Missing threepidCreds", Codes.MISSING_PARAM)
+
threepidCreds = authdict['threepidCreds']
identity_handler = self.hs.get_handlers().identity_handler
- logger.debug("Getting validated threepid. threepidcreds: %r" % (threepidCreds,))
+ logger.info("Getting validated threepid. threepidcreds: %r" % (threepidCreds,))
threepid = yield identity_handler.threepid_from_creds(threepidCreds)
+ if not threepid:
+ raise LoginError(401, "", errcode=Codes.UNAUTHORIZED)
+
threepid['threepidCreds'] = authdict['threepidCreds']
defer.returnValue(threepid)
diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py
index 5ac3ac0f71..e33607b799 100644
--- a/synapse/rest/client/v2_alpha/account.py
+++ b/synapse/rest/client/v2_alpha/account.py
@@ -45,31 +45,42 @@ class PasswordRestServlet(RestServlet):
body = parse_json_dict_from_request(request)
authed, result, params = yield self.auth_handler.check_auth([
- [LoginType.PASSWORD]
+ [LoginType.PASSWORD],
+ [LoginType.EMAIL_IDENTITY]
], body)
if not authed:
defer.returnValue((401, result))
- auth_user = None
+ user_id = None
if LoginType.PASSWORD in result:
# if using password, they should also be logged in
auth_user, client = yield self.auth.get_user_by_req(request)
if auth_user.to_string() != result[LoginType.PASSWORD]:
raise LoginError(400, "", Codes.UNKNOWN)
+ user_id = auth_user.to_string()
+ elif LoginType.EMAIL_IDENTITY in result:
+ threepid = result[LoginType.EMAIL_IDENTITY]
+ if 'medium' not in threepid or 'address' not in threepid:
+ raise SynapseError(500, "Malformed threepid")
+ # if using email, we must know about the email they're authing with!
+ threepid_user = yield self.hs.get_datastore().get_user_by_threepid(
+ threepid['medium'], threepid['address']
+ )
+ if not threepid_user:
+ raise SynapseError(404, "Email address not found", Codes.NOT_FOUND)
+ user_id = threepid_user
else:
logger.error("Auth succeeded but no known type!", result.keys())
raise SynapseError(500, "", Codes.UNKNOWN)
- user_id = auth_user.to_string()
-
if 'new_password' not in params:
raise SynapseError(400, "", Codes.MISSING_PARAM)
new_password = params['new_password']
yield self.login_handler.set_password(
- user_id, new_password, client.token_id
+ user_id, new_password, None
)
defer.returnValue((200, {}))
diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py
index 08d60f0817..ab43856023 100644
--- a/synapse/storage/registration.py
+++ b/synapse/storage/registration.py
@@ -196,4 +196,18 @@ class RegistrationStore(SQLBaseStore):
['medium', 'address', 'validated_at', 'added_at'],
'user_get_threepids'
)
- defer.returnValue(ret)
\ No newline at end of file
+ defer.returnValue(ret)
+
+ @defer.inlineCallbacks
+ def get_user_by_threepid(self, medium, address):
+ ret = yield self._simple_select_one(
+ "user_threepids",
+ {
+ "medium": medium,
+ "address": address
+ },
+ ['user'], True, 'get_user_by_threepid'
+ )
+ if ret:
+ defer.returnValue(ret['user'])
+ defer.returnValue(None)
\ No newline at end of file
|