|
|
|
@ -19,7 +19,7 @@ from twisted.internet import defer |
|
|
|
|
|
|
|
|
|
from synapse.api.auth import has_access_token |
|
|
|
|
from synapse.api.constants import LoginType |
|
|
|
|
from synapse.api.errors import Codes, LoginError, SynapseError |
|
|
|
|
from synapse.api.errors import Codes, SynapseError |
|
|
|
|
from synapse.http.servlet import ( |
|
|
|
|
RestServlet, assert_params_in_request, |
|
|
|
|
parse_json_object_from_request, |
|
|
|
@ -103,44 +103,50 @@ class PasswordRestServlet(RestServlet): |
|
|
|
|
@interactive_auth_handler |
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def on_POST(self, request): |
|
|
|
|
yield run_on_reactor() |
|
|
|
|
|
|
|
|
|
body = parse_json_object_from_request(request) |
|
|
|
|
|
|
|
|
|
result, params, _ = yield self.auth_handler.check_auth([ |
|
|
|
|
[LoginType.PASSWORD], |
|
|
|
|
[LoginType.EMAIL_IDENTITY], |
|
|
|
|
[LoginType.MSISDN], |
|
|
|
|
], body, self.hs.get_ip_from_request(request)) |
|
|
|
|
# there are two possibilities here. Either the user does not have an |
|
|
|
|
# access token, and needs to do a password reset; or they have one and |
|
|
|
|
# need to validate their identity. |
|
|
|
|
# |
|
|
|
|
# In the first case, we offer a couple of means of identifying |
|
|
|
|
# themselves (email and msisdn, though it's unclear if msisdn actually |
|
|
|
|
# works). |
|
|
|
|
# |
|
|
|
|
# In the second case, we require a password to confirm their identity. |
|
|
|
|
|
|
|
|
|
user_id = None |
|
|
|
|
requester = None |
|
|
|
|
|
|
|
|
|
if LoginType.PASSWORD in result: |
|
|
|
|
# if using password, they should also be logged in |
|
|
|
|
if has_access_token(request): |
|
|
|
|
requester = yield self.auth.get_user_by_req(request) |
|
|
|
|
user_id = requester.user.to_string() |
|
|
|
|
if user_id != result[LoginType.PASSWORD]: |
|
|
|
|
raise LoginError(400, "", Codes.UNKNOWN) |
|
|
|
|
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 threepid['medium'] == 'email': |
|
|
|
|
# For emails, transform the address to lowercase. |
|
|
|
|
# We store all email addreses as lowercase in the DB. |
|
|
|
|
# (See add_threepid in synapse/handlers/auth.py) |
|
|
|
|
threepid['address'] = threepid['address'].lower() |
|
|
|
|
# if using email, we must know about the email they're authing with! |
|
|
|
|
threepid_user_id = yield self.datastore.get_user_id_by_threepid( |
|
|
|
|
threepid['medium'], threepid['address'] |
|
|
|
|
params = yield self.auth_handler.validate_user_via_ui_auth( |
|
|
|
|
requester, body, self.hs.get_ip_from_request(request), |
|
|
|
|
) |
|
|
|
|
if not threepid_user_id: |
|
|
|
|
raise SynapseError(404, "Email address not found", Codes.NOT_FOUND) |
|
|
|
|
user_id = threepid_user_id |
|
|
|
|
user_id = requester.user.to_string() |
|
|
|
|
else: |
|
|
|
|
logger.error("Auth succeeded but no known type!", result.keys()) |
|
|
|
|
raise SynapseError(500, "", Codes.UNKNOWN) |
|
|
|
|
requester = None |
|
|
|
|
result, params, _ = yield self.auth_handler.check_auth( |
|
|
|
|
[[LoginType.EMAIL_IDENTITY], [LoginType.MSISDN]], |
|
|
|
|
body, self.hs.get_ip_from_request(request), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if 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 threepid['medium'] == 'email': |
|
|
|
|
# For emails, transform the address to lowercase. |
|
|
|
|
# We store all email addreses as lowercase in the DB. |
|
|
|
|
# (See add_threepid in synapse/handlers/auth.py) |
|
|
|
|
threepid['address'] = threepid['address'].lower() |
|
|
|
|
# if using email, we must know about the email they're authing with! |
|
|
|
|
threepid_user_id = yield self.datastore.get_user_id_by_threepid( |
|
|
|
|
threepid['medium'], threepid['address'] |
|
|
|
|
) |
|
|
|
|
if not threepid_user_id: |
|
|
|
|
raise SynapseError(404, "Email address not found", Codes.NOT_FOUND) |
|
|
|
|
user_id = threepid_user_id |
|
|
|
|
else: |
|
|
|
|
logger.error("Auth succeeded but no known type!", result.keys()) |
|
|
|
|
raise SynapseError(500, "", Codes.UNKNOWN) |
|
|
|
|
|
|
|
|
|
if 'new_password' not in params: |
|
|
|
|
raise SynapseError(400, "", Codes.MISSING_PARAM) |
|
|
|
@ -171,40 +177,21 @@ class DeactivateAccountRestServlet(RestServlet): |
|
|
|
|
def on_POST(self, request): |
|
|
|
|
body = parse_json_object_from_request(request) |
|
|
|
|
|
|
|
|
|
# if the caller provides an access token, it ought to be valid. |
|
|
|
|
requester = None |
|
|
|
|
if has_access_token(request): |
|
|
|
|
requester = yield self.auth.get_user_by_req( |
|
|
|
|
request, |
|
|
|
|
) # type: synapse.types.Requester |
|
|
|
|
requester = yield self.auth.get_user_by_req(request) |
|
|
|
|
|
|
|
|
|
# allow ASes to dectivate their own users |
|
|
|
|
if requester and requester.app_service: |
|
|
|
|
if requester.app_service: |
|
|
|
|
yield self._deactivate_account_handler.deactivate_account( |
|
|
|
|
requester.user.to_string() |
|
|
|
|
) |
|
|
|
|
defer.returnValue((200, {})) |
|
|
|
|
|
|
|
|
|
result, params, _ = yield self.auth_handler.check_auth([ |
|
|
|
|
[LoginType.PASSWORD], |
|
|
|
|
], body, self.hs.get_ip_from_request(request)) |
|
|
|
|
|
|
|
|
|
if LoginType.PASSWORD in result: |
|
|
|
|
user_id = result[LoginType.PASSWORD] |
|
|
|
|
# if using password, they should also be logged in |
|
|
|
|
if requester is None: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Deactivate account requires an access_token", |
|
|
|
|
errcode=Codes.MISSING_TOKEN |
|
|
|
|
) |
|
|
|
|
if requester.user.to_string() != user_id: |
|
|
|
|
raise LoginError(400, "", Codes.UNKNOWN) |
|
|
|
|
else: |
|
|
|
|
logger.error("Auth succeeded but no known type!", result.keys()) |
|
|
|
|
raise SynapseError(500, "", Codes.UNKNOWN) |
|
|
|
|
|
|
|
|
|
yield self._deactivate_account_handler.deactivate_account(user_id) |
|
|
|
|
yield self.auth_handler.validate_user_via_ui_auth( |
|
|
|
|
requester, body, self.hs.get_ip_from_request(request), |
|
|
|
|
) |
|
|
|
|
yield self._deactivate_account_handler.deactivate_account( |
|
|
|
|
requester.user.to_string(), |
|
|
|
|
) |
|
|
|
|
defer.returnValue((200, {})) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|