Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #6011 from matrix-org/anoa/fix_3pid_validation
Browse files Browse the repository at this point in the history
  • Loading branch information
anoadragon453 committed Feb 25, 2020
2 parents e75de41 + 5e9b05d commit b36ecd4
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 41 deletions.
1 change: 1 addition & 0 deletions changelog.d/6011.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use account_threepid_delegate.email and account_threepid_delegate.msisdn for validating threepid sessions.
11 changes: 10 additions & 1 deletion synapse/handlers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,16 @@ def _check_threepid(self, medium, authdict, **kwargs):

logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
if self.hs.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
threepid = yield identity_handler.threepid_from_creds(threepid_creds)
if medium == "email":
threepid = yield identity_handler.threepid_from_creds(
self.hs.config.account_threepid_delegate_email, threepid_creds
)
elif medium == "msisdn":
threepid = yield identity_handler.threepid_from_creds(
self.hs.config.account_threepid_delegate_msisdn, threepid_creds
)
else:
raise SynapseError(400, "Unrecognized threepid medium: %s" % (medium,))
elif self.hs.config.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
row = yield self.store.get_threepid_validation_session(
medium,
Expand Down
72 changes: 33 additions & 39 deletions synapse/handlers/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,63 +87,57 @@ def _extract_items_from_creds_dict(self, creds):
return client_secret, id_server, id_access_token

@defer.inlineCallbacks
def threepid_from_creds(self, creds, use_v2=True):
def threepid_from_creds(self, id_server, creds):
"""
Retrieve and validate a threepid identitier from a "credentials" dictionary
Retrieve and validate a threepid identifier from a "credentials" dictionary against a
given identity server
Args:
creds (dict[str, str]): Dictionary of credentials that contain the following keys:
id_server (str|None): The identity server to validate 3PIDs against. If None,
we will attempt to extract id_server creds
creds (dict[str, str]): Dictionary containing the following keys:
* id_server|idServer: An optional domain name of an identity server
* client_secret|clientSecret: A unique secret str provided by the client
* id_server|idServer: the domain of the identity server to query
* id_access_token: The access token to authenticate to the identity
server with. Required if use_v2 is true
use_v2 (bool): Whether to use v2 Identity Service API endpoints
* sid: The ID of the validation session
Returns:
Deferred[dict[str,str|int]|None]: A dictionary consisting of response params to
the /getValidated3pid endpoint of the Identity Service API, or None if the
threepid was not found
"""
client_secret, id_server, id_access_token = self._extract_items_from_creds_dict(
creds
)

# If an id_access_token is not supplied, force usage of v1
if id_access_token is None:
use_v2 = False

query_params = {"sid": creds["sid"], "client_secret": client_secret}

# Decide which API endpoint URLs and query parameters to use
if use_v2:
url = "https://%s%s" % (
id_server,
"/_matrix/identity/v2/3pid/getValidated3pid",
client_secret = creds.get("client_secret") or creds.get("clientSecret")
if not client_secret:
raise SynapseError(
400, "Missing param client_secret in creds", errcode=Codes.MISSING_PARAM
)
query_params["id_access_token"] = id_access_token
else:
url = "https://%s%s" % (
id_server,
"/_matrix/identity/api/v1/3pid/getValidated3pid",
session_id = creds.get("sid")
if not session_id:
raise SynapseError(
400, "Missing param session_id in creds", errcode=Codes.MISSING_PARAM
)
if not id_server:
# Attempt to get the id_server from the creds dict
id_server = creds.get("id_server") or creds.get("idServer")
if not id_server:
raise SynapseError(
400, "Missing param id_server in creds", errcode=Codes.MISSING_PARAM
)

query_params = {"sid": session_id, "client_secret": client_secret}

# if we have a rewrite rule set for the identity server,
# apply it now.
if id_server in self.rewrite_identity_server_urls:
id_server = self.rewrite_identity_server_urls[id_server]
try:
data = yield self.http_client.get_json(url, query_params)
return data if "medium" in data else None
except HttpResponseException as e:
if e.code != 404 or not use_v2:
# Generic failure
logger.info("getValidated3pid failed with Matrix error: %r", e)
raise e.to_synapse_error()

# This identity server is too old to understand Identity Service API v2
# Attempt v1 endpoint
logger.info("Got 404 when POSTing JSON %s, falling back to v1 URL", url)
return (yield self.threepid_from_creds(creds, use_v2=False))
url = "https://%s%s" % (
id_server,
"/_matrix/identity/api/v1/3pid/getValidated3pid",
)

data = yield self.http_client.get_json(url, query_params)
return data if "medium" in data else None

@defer.inlineCallbacks
def bind_threepid(self, creds, mxid, use_v2=True):
Expand Down
3 changes: 2 additions & 1 deletion synapse/rest/client/v2_alpha/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,8 @@ def on_POST(self, request):
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)
# Specify None as the identity server to retrieve it from the request body instead
threepid = yield self.identity_handler.threepid_from_creds(None, threepid_creds)

if not threepid:
raise SynapseError(
Expand Down

0 comments on commit b36ecd4

Please sign in to comment.