|
42 | 42 | from synapse.logging.context import defer_to_thread |
43 | 43 | from synapse.metrics.background_process_metrics import run_as_background_process |
44 | 44 | from synapse.module_api import ModuleApi |
45 | | -from synapse.types import Requester, UserID |
| 45 | +from synapse.types import JsonDict, Requester, UserID |
46 | 46 | from synapse.util import stringutils as stringutils |
| 47 | +from synapse.util.msisdn import phone_number_to_msisdn |
47 | 48 | from synapse.util.threepids import canonicalise_email |
48 | 49 |
|
49 | 50 | from ._base import BaseHandler |
50 | 51 |
|
51 | 52 | logger = logging.getLogger(__name__) |
52 | 53 |
|
53 | 54 |
|
| 55 | +def convert_client_dict_legacy_fields_to_identifier( |
| 56 | + submission: JsonDict, |
| 57 | +) -> Dict[str, str]: |
| 58 | + """ |
| 59 | + Convert a legacy-formatted login submission to an identifier dict. |
| 60 | +
|
| 61 | + Legacy login submissions (used in both login and user-interactive authentication) |
| 62 | + provide user-identifying information at the top-level instead. |
| 63 | +
|
| 64 | + These are now deprecated and replaced with identifiers: |
| 65 | + https://matrix.org/docs/spec/client_server/r0.6.1#identifier-types |
| 66 | +
|
| 67 | + Args: |
| 68 | + submission: The client dict to convert |
| 69 | +
|
| 70 | + Returns: |
| 71 | + The matching identifier dict |
| 72 | +
|
| 73 | + Raises: |
| 74 | + SynapseError: If the format of the client dict is invalid |
| 75 | + """ |
| 76 | + identifier = submission.get("identifier", {}) |
| 77 | + |
| 78 | + # Generate an m.id.user identifier if "user" parameter is present |
| 79 | + user = submission.get("user") |
| 80 | + if user: |
| 81 | + identifier = {"type": "m.id.user", "user": user} |
| 82 | + |
| 83 | + # Generate an m.id.thirdparty identifier if "medium" and "address" parameters are present |
| 84 | + medium = submission.get("medium") |
| 85 | + address = submission.get("address") |
| 86 | + if medium and address: |
| 87 | + identifier = { |
| 88 | + "type": "m.id.thirdparty", |
| 89 | + "medium": medium, |
| 90 | + "address": address, |
| 91 | + } |
| 92 | + |
| 93 | + # We've converted valid, legacy login submissions to an identifier. If the |
| 94 | + # submission still doesn't have an identifier, it's invalid |
| 95 | + if not identifier: |
| 96 | + raise SynapseError(400, "Invalid login submission", Codes.INVALID_PARAM) |
| 97 | + |
| 98 | + # Ensure the identifier has a type |
| 99 | + if "type" not in identifier: |
| 100 | + raise SynapseError( |
| 101 | + 400, "'identifier' dict has no key 'type'", errcode=Codes.MISSING_PARAM, |
| 102 | + ) |
| 103 | + |
| 104 | + return identifier |
| 105 | + |
| 106 | + |
| 107 | +def login_id_phone_to_thirdparty(identifier: JsonDict) -> Dict[str, str]: |
| 108 | + """ |
| 109 | + Convert a phone login identifier type to a generic threepid identifier. |
| 110 | +
|
| 111 | + Args: |
| 112 | + identifier: Login identifier dict of type 'm.id.phone' |
| 113 | +
|
| 114 | + Returns: |
| 115 | + An equivalent m.id.thirdparty identifier dict |
| 116 | + """ |
| 117 | + if "country" not in identifier or ( |
| 118 | + # The specification requires a "phone" field, while Synapse used to require a "number" |
| 119 | + # field. Accept both for backwards compatibility. |
| 120 | + "phone" not in identifier |
| 121 | + and "number" not in identifier |
| 122 | + ): |
| 123 | + raise SynapseError( |
| 124 | + 400, "Invalid phone-type identifier", errcode=Codes.INVALID_PARAM |
| 125 | + ) |
| 126 | + |
| 127 | + # Accept both "phone" and "number" as valid keys in m.id.phone |
| 128 | + phone_number = identifier.get("phone", identifier["number"]) |
| 129 | + |
| 130 | + # Convert user-provided phone number to a consistent representation |
| 131 | + msisdn = phone_number_to_msisdn(identifier["country"], phone_number) |
| 132 | + |
| 133 | + return { |
| 134 | + "type": "m.id.thirdparty", |
| 135 | + "medium": "msisdn", |
| 136 | + "address": msisdn, |
| 137 | + } |
| 138 | + |
| 139 | + |
54 | 140 | class AuthHandler(BaseHandler): |
55 | 141 | SESSION_EXPIRE_MS = 48 * 60 * 60 * 1000 |
56 | 142 |
|
|
0 commit comments