some fixes, honeypot registration
This commit is contained in:
@@ -419,7 +419,10 @@ def createcourse(
|
|||||||
longitude = point['longitude']
|
longitude = point['longitude']
|
||||||
g = geocoder.arcgis([latitude, longitude], method='reverse')
|
g = geocoder.arcgis([latitude, longitude], method='reverse')
|
||||||
if g.ok:
|
if g.ok:
|
||||||
|
try:
|
||||||
country = g.json['country']
|
country = g.json['country']
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
country = 'unknown'
|
||||||
else: # pragma: no cover
|
else: # pragma: no cover
|
||||||
country = 'unknown'
|
country = 'unknown'
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from django.contrib.admin.widgets import AdminDateWidget
|
|||||||
from django.forms.widgets import SelectDateWidget, HiddenInput
|
from django.forms.widgets import SelectDateWidget, HiddenInput
|
||||||
from django_recaptcha.fields import ReCaptchaField
|
from django_recaptcha.fields import ReCaptchaField
|
||||||
from django_recaptcha.widgets import ReCaptchaV3
|
from django_recaptcha.widgets import ReCaptchaV3
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
from django.utils import timezone, translation
|
from django.utils import timezone, translation
|
||||||
from django.forms import ModelForm, Select
|
from django.forms import ModelForm, Select
|
||||||
@@ -1015,6 +1016,25 @@ class RegistrationFormUniqueEmail(RegistrationFormTermsOfService):
|
|||||||
"This email address is already in use. Please supply a different email address.")
|
"This email address is already in use. Please supply a different email address.")
|
||||||
return self.cleaned_data['email']
|
return self.cleaned_data['email']
|
||||||
|
|
||||||
|
class HoneypotField(forms.CharField):
|
||||||
|
"""
|
||||||
|
A honeypot field that should be left empty by humans
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs.setdefault('required', False)
|
||||||
|
kwargs.setdefault('widget', forms.TextInput(attrs={
|
||||||
|
'style': 'display:none !important',
|
||||||
|
'tabindex': '-1',
|
||||||
|
'autocomplete': 'off',
|
||||||
|
'aria-hidden': 'true',
|
||||||
|
}))
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
if value:
|
||||||
|
# If the field has a value, it's likely a bot
|
||||||
|
raise ValidationError("Please leave this field empty.")
|
||||||
|
return value
|
||||||
|
|
||||||
class RegistrationFormSex(RegistrationFormUniqueEmail):
|
class RegistrationFormSex(RegistrationFormUniqueEmail):
|
||||||
sexcategories = (
|
sexcategories = (
|
||||||
@@ -1038,6 +1058,8 @@ class RegistrationFormSex(RegistrationFormUniqueEmail):
|
|||||||
month=4,
|
month=4,
|
||||||
day=15))
|
day=15))
|
||||||
|
|
||||||
|
url = HoneypotField(label="URL")
|
||||||
|
|
||||||
def clean_birthdate(self):
|
def clean_birthdate(self):
|
||||||
dob = self.cleaned_data['birthdate']
|
dob = self.cleaned_data['birthdate']
|
||||||
age = (timezone.now() - dob).days/365
|
age = (timezone.now() - dob).days/365
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class NewUserRegistrationTest(TestCase):
|
|||||||
'username':'janderoeiert',
|
'username':'janderoeiert',
|
||||||
'password1':'Aapindewei2',
|
'password1':'Aapindewei2',
|
||||||
'password2':'Aapindewei2',
|
'password2':'Aapindewei2',
|
||||||
|
'url': '',
|
||||||
'tos':True,
|
'tos':True,
|
||||||
'weightcategory':'hwt',
|
'weightcategory':'hwt',
|
||||||
'adaptiveclass': 'None',
|
'adaptiveclass': 'None',
|
||||||
@@ -38,7 +39,7 @@ class NewUserRegistrationTest(TestCase):
|
|||||||
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
||||||
}
|
}
|
||||||
|
|
||||||
form = RegistrationFormUniqueEmail(form_data)
|
form = RegistrationFormSex(form_data)
|
||||||
self.assertTrue(form.is_valid())
|
self.assertTrue(form.is_valid())
|
||||||
|
|
||||||
response = self.c.post('/rowers/register/', form_data, follow=True)
|
response = self.c.post('/rowers/register/', form_data, follow=True)
|
||||||
@@ -117,6 +118,7 @@ class NewUserRegistrationTest(TestCase):
|
|||||||
'password1':'aapindewei2',
|
'password1':'aapindewei2',
|
||||||
'password2':'aapindewei2',
|
'password2':'aapindewei2',
|
||||||
'tos':True,
|
'tos':True,
|
||||||
|
'url': '',
|
||||||
'weightcategory':'hwt',
|
'weightcategory':'hwt',
|
||||||
'adaptiveclass': 'None',
|
'adaptiveclass': 'None',
|
||||||
'sex':'male',
|
'sex':'male',
|
||||||
@@ -124,5 +126,34 @@ class NewUserRegistrationTest(TestCase):
|
|||||||
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
||||||
}
|
}
|
||||||
|
|
||||||
form = RegistrationFormUniqueEmail(form_data)
|
form = RegistrationFormSex(form_data)
|
||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
|
|
||||||
|
@patch('rowers.dataprep.workout_summary_to_df',side_effect=mock_workout_summaries)
|
||||||
|
def test_newuser_honeypot(self,mock_workout_summaries):
|
||||||
|
form_data = {
|
||||||
|
'first_name':'Jan',
|
||||||
|
'last_name':'Roeiert',
|
||||||
|
'email':'jan@loop.nl',
|
||||||
|
'username':'janderoeiert',
|
||||||
|
'password1':'Aapindewei2',
|
||||||
|
'password2':'Aapindewei2',
|
||||||
|
'url': 'http://example.com',
|
||||||
|
'tos':True,
|
||||||
|
'weightcategory':'hwt',
|
||||||
|
'adaptiveclass': 'None',
|
||||||
|
'sex':'male',
|
||||||
|
'next':'/rowers/list-workouts',
|
||||||
|
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
||||||
|
}
|
||||||
|
|
||||||
|
form = RegistrationFormSex(form_data)
|
||||||
|
self.assertFalse(form.is_valid())
|
||||||
|
|
||||||
|
# still post it, should redirect to the registration page
|
||||||
|
response = self.c.post('/rowers/register/', form_data, follow=True)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
self.assertRedirects(response,
|
||||||
|
expected_url='/rowers/register/',
|
||||||
|
status_code=302,target_status_code=200)
|
||||||
|
|
||||||
|
|||||||
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
Binary file not shown.
@@ -895,6 +895,14 @@ def rower_register_view(request):
|
|||||||
nextpage = '/rowers/list-workouts/'
|
nextpage = '/rowers/list-workouts/'
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
# Check if honeypot was triggered (optional logging)
|
||||||
|
honeypot_value = request.POST.get('url', '')
|
||||||
|
if honeypot_value:
|
||||||
|
# bot user, do not register
|
||||||
|
messages.error(request, "Registration failed. Please try again.")
|
||||||
|
url = reverse('rower_register_view')
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
form = RegistrationFormSex(request.POST)
|
form = RegistrationFormSex(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
first_name = form.cleaned_data['first_name']
|
first_name = form.cleaned_data['first_name']
|
||||||
|
|||||||
Reference in New Issue
Block a user