-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
add registrations_require_3pid and allow_local_3pids #2813
Changes from 3 commits
28a6ccb
81d037d
0af58f1
9d332e0
447f4f0
293380b
8fe253f
62d7d66
49fce04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,6 +60,27 @@ def set_timeline_upper_limit(filter_json, filter_timeline_limit): | |
filter_timeline_limit) | ||
|
||
|
||
def check_3pid_allowed(hs, medium, address): | ||
# check whether the HS has whitelisted the given 3PID | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Proper docstring please. |
||
|
||
allow = False | ||
if hs.config.registrations_require_3pid: | ||
for constraint in hs.config.registrations_require_3pid: | ||
logger.debug("Checking 3PID %s (%s) against %s (%s)" % ( | ||
address, medium, constraint['pattern'], constraint['medium'] | ||
)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't do string building, like most logging libraries it does it for you: |
||
if ( | ||
medium == constraint['medium'] and | ||
re.match(constraint['pattern'], address) | ||
): | ||
allow = True | ||
break | ||
else: | ||
allow = True | ||
|
||
return allow | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Normally I'd do the pattern of returning immediately rather than having an allow variable, e.g.: def check_3pid_allowed(hs, medium, address):
if not hs.config.registrations_require_3pid:
return True
for constraint in hs.config.registrations_require_3pid:
if allowed:
return True
return False |
||
|
||
|
||
def interactive_auth_handler(orig): | ||
"""Wraps an on_POST method to handle InteractiveAuthIncompleteErrors | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,9 +27,10 @@ | |
) | ||
from synapse.util.msisdn import phone_number_to_msisdn | ||
|
||
from ._base import client_v2_patterns, interactive_auth_handler | ||
from ._base import client_v2_patterns, interactive_auth_handler, check_3pid_allowed | ||
|
||
import logging | ||
import re | ||
import hmac | ||
from hashlib import sha1 | ||
from synapse.util.async import run_on_reactor | ||
|
@@ -70,6 +71,9 @@ def on_POST(self, request): | |
'id_server', 'client_secret', 'email', 'send_attempt' | ||
]) | ||
|
||
if not check_3pid_allowed(self.hs, "email", body['email']): | ||
raise SynapseError(403, "3PID denied", Codes.THREEPID_DENIED) | ||
|
||
existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( | ||
'email', body['email'] | ||
) | ||
|
@@ -105,6 +109,9 @@ def on_POST(self, request): | |
|
||
msisdn = phone_number_to_msisdn(body['country'], body['phone_number']) | ||
|
||
if not check_3pid_allowed(self.hs, "msisdn", msisdn): | ||
raise SynapseError(403, "3PID denied", Codes.THREEPID_DENIED) | ||
|
||
existingUid = yield self.hs.get_datastore().get_user_id_by_threepid( | ||
'msisdn', msisdn | ||
) | ||
|
@@ -305,31 +312,73 @@ def on_POST(self, request): | |
if 'x_show_msisdn' in body and body['x_show_msisdn']: | ||
show_msisdn = True | ||
|
||
require_email = False | ||
require_msisdn = False | ||
for constraint in self.hs.config.registrations_require_3pid: | ||
if constraint['medium'] == 'email': | ||
require_email = True | ||
elif constraint['medium'] == 'msisdn': | ||
require_msisdn = True | ||
else: | ||
logger.warn( | ||
"Unrecognised 3PID medium %s in registrations_require_3pid" % | ||
constraint['medium'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't do string building. |
||
) | ||
|
||
flows = [] | ||
if self.hs.config.enable_registration_captcha: | ||
flows = [ | ||
[LoginType.RECAPTCHA], | ||
[LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA], | ||
] | ||
if not require_email and not require_msisdn: | ||
flows.extend([[LoginType.RECAPTCHA]]) | ||
if require_email or not require_msisdn: | ||
flows.extend([[LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA]]) | ||
|
||
if show_msisdn: | ||
if not require_email or require_msisdn: | ||
flows.extend([[LoginType.MSISDN, LoginType.RECAPTCHA]]) | ||
flows.extend([ | ||
[LoginType.MSISDN, LoginType.RECAPTCHA], | ||
[LoginType.MSISDN, LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA], | ||
]) | ||
else: | ||
flows = [ | ||
[LoginType.DUMMY], | ||
[LoginType.EMAIL_IDENTITY], | ||
] | ||
if not require_email and not require_msisdn: | ||
flows.extend([[LoginType.DUMMY]]) | ||
if require_email or not require_msisdn: | ||
flows.extend([[LoginType.EMAIL_IDENTITY]]) | ||
|
||
if show_msisdn: | ||
if not require_email or require_msisdn: | ||
flows.extend([[LoginType.MSISDN]]) | ||
flows.extend([ | ||
[LoginType.MSISDN], | ||
[LoginType.MSISDN, LoginType.EMAIL_IDENTITY], | ||
[LoginType.MSISDN, LoginType.EMAIL_IDENTITY] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (See comment where we do this in v1 register) |
||
]) | ||
|
||
auth_result, params, session_id = yield self.auth_handler.check_auth( | ||
flows, body, self.hs.get_ip_from_request(request) | ||
) | ||
|
||
# doublecheck that we're not trying to register an denied 3pid. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a |
||
# the user-facing checks should already have happened when we requested | ||
# a 3PID token to validate them in /register/email/requestToken etc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not necessarily, since there's nothing to mandate that the user had to proxy their |
||
|
||
for constraint in self.hs.config.registrations_require_3pid: | ||
if ( | ||
constraint['medium'] == 'email' and | ||
auth_result and LoginType.EMAIL_IDENTITY in auth_result and | ||
re.match( | ||
constraint['pattern'], | ||
auth_result[LoginType.EMAIL_IDENTITY].threepid.address | ||
) | ||
): | ||
raise SynapseError(403, "3PID denied", Codes.THREEPID_DENIED) | ||
elif ( | ||
constraint['medium'] == 'msisdn' and | ||
auth_result and LoginType.MSISDN in auth_result and | ||
re.match( | ||
constraint['pattern'], | ||
auth_result[LoginType.MSISDN].threepid.address | ||
) | ||
): | ||
raise SynapseError(403, "3PID denied", Codes.THREEPID_DENIED) | ||
|
||
if registered_user_id is not None: | ||
logger.info( | ||
"Already registered user ID %r for this session", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to affect just registrations and could be misleading to some people.
Edit for clarity: I'm talking about the config key name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, i've asked @dbkr to clarify the impact on the other 3PID manipulations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this convo ended up in IRL as dave presumably missed this comment: the impact is: