Skip to content

Commit baa5c5f

Browse files
committed
revert regex change, add tests, add urlsplit
1 parent 9d2a552 commit baa5c5f

3 files changed

Lines changed: 59 additions & 30 deletions

File tree

osf/models/user.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,10 @@ def save(self, *args, **kwargs):
10681068
dirty_fields = self.get_dirty_fields(check_relationship=True)
10691069
ret = super().save(*args, **kwargs) # must save BEFORE spam check, as user needs guid.
10701070

1071-
if has_domain and not was_creating:
1071+
if has_domain and self.is_hammy:
1072+
self.flag_spam()
1073+
1074+
if has_domain and not was_creating and not self.is_hammy:
10721075
self.confirm_spam()
10731076

10741077
if set(self.SPAM_USER_PROFILE_FIELDS.keys()).intersection(dirty_fields):
@@ -1482,7 +1485,8 @@ def confirm_email(self, token, merge=False):
14821485
return True
14831486

14841487
def confirm_spam(self, domains=None, save=True, train_spam_services=False, skip_resources_spam=False):
1485-
self.deactivate_account()
1488+
if not self.is_hammy:
1489+
self.deactivate_account()
14861490
super().confirm_spam(domains=domains, save=save, train_spam_services=train_spam_services)
14871491

14881492
if skip_resources_spam:

osf/models/validators.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import re
2+
from urllib.parse import urlsplit
23
import waffle
34

45
from jsonschema import ValidationError as JsonSchemaValidationError, SchemaError, Draft7Validator, validate, validators
@@ -115,19 +116,17 @@ def validate_email(value):
115116

116117
def has_domain_in_user_fields_for_names(user):
117118
name_content = ' '.join(getattr(user, field) or '' for field in user.DOMAIN_VALIDATION_FIELDS).strip()
118-
119-
if not name_content:
120-
return False
121-
122-
text = name_content.lower()
123-
if any(suffix in text for suffix in ['m.sc.', 'msc.', 'phd.', 'ph.d.', 'msc.pt', 'pt.', 'prof.', 'dr.', 'md.', 'jd.', 'esq.']):
124-
return False
125-
126-
if re.search(r'\b[a-z]\.[a-z0-9-]+\b', text):
127-
return False
128-
129-
return True if DOMAIN_REGEX.search(name_content) else False
130-
119+
for match in DOMAIN_REGEX.finditer(name_content):
120+
candidate = match.group(0).strip()
121+
if looks_like_url(candidate):
122+
return True
123+
return False
124+
125+
def looks_like_url(candidate):
126+
if candidate.startswith('www.'):
127+
candidate = f'https://{candidate}'
128+
parsed = urlsplit(candidate)
129+
return bool(parsed.scheme and parsed.netloc)
131130

132131
def validate_subject_hierarchy_length(parent):
133132
from osf.models import Subject

osf_tests/test_validators.py

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import pytest
22
from osf.exceptions import ValidationValueError
33

4-
from osf.models import validators
4+
from types import SimpleNamespace
5+
from osf.models import validators, OSFUser
56
from osf.models.validators import has_domain_in_user_fields_for_names
6-
from osf_tests.factories import SubjectFactory, AuthUserFactory
7+
from osf_tests.factories import SubjectFactory
78

89

910
# Ported from tests/framework/test_mongo.py
1011

11-
@pytest.fixture()
12-
def user(user_data):
13-
return AuthUserFactory(**user_data)
14-
12+
def mock_user(user_data):
13+
user = SimpleNamespace()
14+
user.DOMAIN_VALIDATION_FIELDS = OSFUser.DOMAIN_VALIDATION_FIELDS
15+
for field in user.DOMAIN_VALIDATION_FIELDS:
16+
setattr(user, field, user_data.get(field, ''))
17+
return user
1518

1619
def test_string_required_passes_with_string():
1720
assert validators.string_required('Hi!') is True
@@ -155,13 +158,36 @@ def test_validate_expand_subject_hierarchy():
155158
}
156159
]
157160
)
158-
def test_has_domain_in_user_fields_for_names_returns_false(user, user_data):
159-
user.DOMAIN_VALIDATION_FIELDS = [
160-
'fullname',
161-
'given_name',
162-
'middle_names',
163-
'family_name',
164-
'suffix',
165-
]
166-
161+
def test_has_domain_in_user_fields(user_data):
162+
user = mock_user(user_data)
167163
assert has_domain_in_user_fields_for_names(user) is False
164+
165+
166+
@pytest.mark.parametrize(
167+
'user_data',
168+
[
169+
{
170+
'fullname': 'Judith Sarah',
171+
'given_name': 'Judith',
172+
'family_name': 'Preuss',
173+
'middle_names': 'https://www.google.com',
174+
'suffix': 'M.Sc.',
175+
},
176+
{
177+
'fullname': 'J.H. van Hateren',
178+
'given_name': 'J.H.',
179+
'family_name': 'https://google.com',
180+
'middle_names': '',
181+
},
182+
{
183+
'fullname': 'Judith Sarah',
184+
'given_name': 'Judith',
185+
'family_name': 'Preuss',
186+
'middle_names': 'www.google.com',
187+
'suffix': 'M.Sc.',
188+
},
189+
]
190+
)
191+
def test_has_domain_in_user_fields_fail(user_data):
192+
user = mock_user(user_data)
193+
assert has_domain_in_user_fields_for_names(user) is True

0 commit comments

Comments
 (0)