1
0

Compare commits

...

5 Commits

Author SHA1 Message Date
Andrew Morgan
ccbd9dc5ac clearer logic 2019-09-09 17:03:31 +01:00
Andrew Morgan
dac83b714f lint 2019-09-09 15:41:10 +01:00
Andrew Morgan
2f9d8dc5b9 Address review comments 2019-09-09 15:39:52 +01:00
Andrew Morgan
d29e4a31f4 Add changelog 2019-09-06 14:09:33 +01:00
Andrew Morgan
3b666c1493 Implement MSC2229 - allow homeservers to rebind 3pids 2019-09-06 14:07:47 +01:00
2 changed files with 55 additions and 7 deletions

1
changelog.d/5996.feature Normal file
View File

@@ -0,0 +1 @@
Allow users to rebind 3pids they own (MSC2229).

View File

@@ -21,7 +21,13 @@ from six.moves import http_client
from twisted.internet import defer
from synapse.api.constants import LoginType
from synapse.api.errors import Codes, SynapseError, ThreepidValidationError
from synapse.api.errors import (
AuthError,
Codes,
InvalidClientCredentialsError,
SynapseError,
ThreepidValidationError,
)
from synapse.config.emailconfig import ThreepidBehaviour
from synapse.http.server import finish_request
from synapse.http.servlet import (
@@ -412,6 +418,7 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
def __init__(self, hs):
super(EmailThreepidRequestTokenRestServlet, self).__init__()
self.hs = hs
self.auth = hs.get_auth()
self.config = hs.config
self.identity_handler = hs.get_handlers().identity_handler
self.store = self.hs.get_datastore()
@@ -435,12 +442,26 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
Codes.THREEPID_DENIED,
)
requester = None
try:
requester = yield self.auth.get_user_by_req(request)
except (AuthError, InvalidClientCredentialsError):
# No authentication provided, ignore
pass
existing_user_id = yield self.store.get_user_id_by_threepid(
"email", body["email"]
)
if existing_user_id is not None:
raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE)
# If the request is authenticated, allow this MSISDN to be rebound if the requester
# owns it.
# Otherwise, deny the request if the 3PID exists
if existing_user_id:
if (
requester is None or
(requester and existing_user_id != requester.user.to_string)
):
raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE)
ret = yield self.identity_handler.requestEmailToken(
id_server, email, client_secret, send_attempt, next_link
@@ -452,8 +473,9 @@ class MsisdnThreepidRequestTokenRestServlet(RestServlet):
PATTERNS = client_patterns("/account/3pid/msisdn/requestToken$")
def __init__(self, hs):
self.hs = hs
super(MsisdnThreepidRequestTokenRestServlet, self).__init__()
self.hs = hs
self.auth = hs.get_auth()
self.store = self.hs.get_datastore()
self.identity_handler = hs.get_handlers().identity_handler
@@ -480,10 +502,24 @@ class MsisdnThreepidRequestTokenRestServlet(RestServlet):
Codes.THREEPID_DENIED,
)
requester = None
try:
requester = yield self.auth.get_user_by_req(request)
except (AuthError, InvalidClientCredentialsError):
# No authentication provided, ignore
pass
existing_user_id = yield self.store.get_user_id_by_threepid("msisdn", msisdn)
if existing_user_id is not None:
raise SynapseError(400, "MSISDN is already in use", Codes.THREEPID_IN_USE)
# If the request is authenticated, allow this MSISDN to be rebound if the requester
# owns it.
# Otherwise, deny the request if the 3PID exists
if existing_user_id:
if (
requester is None or
(requester and existing_user_id != requester.user.to_string)
):
raise SynapseError(400, "MSISDN is already in use", Codes.THREEPID_IN_USE)
ret = yield self.identity_handler.requestMsisdnToken(
id_server, country, phone_number, client_secret, send_attempt, next_link
@@ -522,7 +558,6 @@ class ThreepidRestServlet(RestServlet):
requester = yield self.auth.get_user_by_req(request)
user_id = requester.user.to_string()
threepid = yield self.identity_handler.threepid_from_creds(threepid_creds)
if not threepid:
@@ -533,6 +568,18 @@ class ThreepidRestServlet(RestServlet):
logger.warn("Couldn't add 3pid: invalid response from ID server")
raise SynapseError(500, "Invalid response from ID Server")
existing_user_id = yield self.datastore.get_user_id_by_threepid(
threepid["medium"], threepid["address"]
)
# Check that the user is not trying to add an email that's already bound to another
# user
if existing_user_id and existing_user_id != requester.user.to_string():
raise SynapseError(
400, "This 3PID is already in use by %s" % (existing_user_id,),
Codes.THREEPID_IN_USE,
)
yield self.auth_handler.add_threepid(
user_id, threepid["medium"], threepid["address"], threepid["validated_at"]
)