1
0

Move utility methods from login handler to auth handler

This commit is contained in:
Andrew Morgan
2020-06-12 12:06:19 +01:00
parent a3fbc23c39
commit b674bb8500
2 changed files with 88 additions and 39 deletions
+81
View File
@@ -45,12 +45,93 @@ from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.module_api import ModuleApi
from synapse.push.mailer import load_jinja2_templates
from synapse.types import Requester, UserID
from synapse.util.msisdn import phone_number_to_msisdn
from ._base import BaseHandler
logger = logging.getLogger(__name__)
def client_dict_convert_legacy_fields_to_identifier(
submission: Dict[str, Union[str, Dict]]
):
"""Take a legacy-formatted login submission or User-Interactive Authentication dict and
updates it to feature an identifier dict instead.
Providing user-identifying information at the top-level of a login or UIA submission is
now deprecated and replaced with identifiers:
https://matrix.org/docs/spec/client_server/r0.6.1#identifier-types
Args:
submission: The client dict to convert. Passed by reference and modified
Raises:
SynapseError: if the dict contains a "medium" parameter that is anything other than
"email"
"""
if "user" in submission:
submission["identifier"] = {"type": "m.id.user", "user": submission["user"]}
del submission["user"]
if "medium" in submission and "address" in submission:
submission["identifier"] = {
"type": "m.id.thirdparty",
"medium": submission["medium"],
"address": submission["address"],
}
del submission["medium"]
del submission["address"]
# We've converted valid, legacy login submissions to an identifier. If the
# dict still doesn't have an identifier, it's invalid
if "identifier" not in submission:
raise SynapseError(
400,
"Missing 'identifier' parameter in login submission",
errcode=Codes.MISSING_PARAM,
)
# Ensure the identifier has a type
if "type" not in submission["identifier"]:
raise SynapseError(
400, "'identifier' dict has no key 'type'", errcode=Codes.MISSING_PARAM,
)
def login_id_phone_to_thirdparty(identifier: Dict[str, str]):
"""Convert a phone login identifier type to a generic threepid identifier. Modifies
the identifier dict in place
Args:
identifier: Login identifier dict of type 'm.id.phone'
"""
if "type" not in identifier:
raise SynapseError(
400, "Invalid phone-type identifier", errcode=Codes.MISSING_PARAM
)
if "country" not in identifier or (
# XXX: We used to require `number` instead of `phone`. The spec
# defines `phone`. So accept both
"phone" not in identifier
and "number" not in identifier
):
raise SynapseError(
400, "Invalid phone-type identifier", errcode=Codes.INVALID_PARAM
)
# Accept both "phone" and "number" as valid keys in m.id.phone
phone_number = identifier.get("phone", identifier.get("number"))
# Convert user-provided phone number to a consistent representation
msisdn = phone_number_to_msisdn(identifier["country"], phone_number)
# Modify the passed dictionary by reference
del identifier["country"]
identifier.pop("number", None)
identifier.pop("phone", None)
identifier["type"] = "m.id.thirdparty"
identifier["medium"] = "msisdn"
identifier["address"] = msisdn
class AuthHandler(BaseHandler):
SESSION_EXPIRE_MS = 48 * 60 * 60 * 1000
+7 -39
View File
@@ -17,6 +17,10 @@ import logging
from synapse.api.errors import Codes, LoginError, SynapseError
from synapse.api.ratelimiting import Ratelimiter
from synapse.handlers.auth import (
client_dict_convert_legacy_fields_to_identifier,
login_id_phone_to_thirdparty,
)
from synapse.http.server import finish_request
from synapse.http.servlet import (
RestServlet,
@@ -27,47 +31,10 @@ from synapse.http.site import SynapseRequest
from synapse.rest.client.v2_alpha._base import client_patterns
from synapse.rest.well_known import WellKnownBuilder
from synapse.types import UserID
from synapse.util.msisdn import phone_number_to_msisdn
logger = logging.getLogger(__name__)
def login_submission_legacy_convert(submission):
"""
If the input login submission is an old style object
(ie. with top-level user / medium / address) convert it
to a typed object.
"""
if "user" in submission:
submission["identifier"] = {"type": "m.id.user", "user": submission["user"]}
del submission["user"]
if "medium" in submission and "address" in submission:
submission["identifier"] = {
"type": "m.id.thirdparty",
"medium": submission["medium"],
"address": submission["address"],
}
del submission["medium"]
del submission["address"]
def login_id_thirdparty_from_phone(identifier):
"""
Convert a phone login identifier type to a generic threepid identifier
Args:
identifier(dict): Login identifier dict of type 'm.id.phone'
Returns: Login identifier dict of type 'm.id.threepid'
"""
if "country" not in identifier or "number" not in identifier:
raise SynapseError(400, "Invalid phone-type identifier")
msisdn = phone_number_to_msisdn(identifier["country"], identifier["number"])
return {"type": "m.id.thirdparty", "medium": "msisdn", "address": msisdn}
class LoginRestServlet(RestServlet):
PATTERNS = client_patterns("/login$", v1=True)
CAS_TYPE = "m.login.cas"
@@ -174,7 +141,8 @@ class LoginRestServlet(RestServlet):
login_submission.get("address"),
login_submission.get("user"),
)
login_submission_legacy_convert(login_submission)
# Convert deprecated authdict formats to the current scheme
client_dict_convert_legacy_fields_to_identifier(login_submission)
if "identifier" not in login_submission:
raise SynapseError(400, "Missing param: identifier")
@@ -185,7 +153,7 @@ class LoginRestServlet(RestServlet):
# convert phone type identifiers to generic threepids
if identifier["type"] == "m.id.phone":
identifier = login_id_thirdparty_from_phone(identifier)
identifier = login_id_phone_to_thirdparty(identifier)
# convert threepid identifiers to user IDs
if identifier["type"] == "m.id.thirdparty":