some fixes, honeypot registration
This commit is contained in:
@@ -419,7 +419,10 @@ def createcourse(
|
||||
longitude = point['longitude']
|
||||
g = geocoder.arcgis([latitude, longitude], method='reverse')
|
||||
if g.ok:
|
||||
country = g.json['country']
|
||||
try:
|
||||
country = g.json['country']
|
||||
except KeyError: # pragma: no cover
|
||||
country = 'unknown'
|
||||
else: # pragma: no cover
|
||||
country = 'unknown'
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ from django.contrib.admin.widgets import AdminDateWidget
|
||||
from django.forms.widgets import SelectDateWidget, HiddenInput
|
||||
from django_recaptcha.fields import ReCaptchaField
|
||||
from django_recaptcha.widgets import ReCaptchaV3
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from django.utils import timezone, translation
|
||||
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.")
|
||||
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):
|
||||
sexcategories = (
|
||||
@@ -1037,7 +1057,9 @@ class RegistrationFormSex(RegistrationFormUniqueEmail):
|
||||
initial=datetime.date(year=1970,
|
||||
month=4,
|
||||
day=15))
|
||||
|
||||
|
||||
url = HoneypotField(label="URL")
|
||||
|
||||
def clean_birthdate(self):
|
||||
dob = self.cleaned_data['birthdate']
|
||||
age = (timezone.now() - dob).days/365
|
||||
|
||||
@@ -30,6 +30,7 @@ class NewUserRegistrationTest(TestCase):
|
||||
'username':'janderoeiert',
|
||||
'password1':'Aapindewei2',
|
||||
'password2':'Aapindewei2',
|
||||
'url': '',
|
||||
'tos':True,
|
||||
'weightcategory':'hwt',
|
||||
'adaptiveclass': 'None',
|
||||
@@ -38,7 +39,7 @@ class NewUserRegistrationTest(TestCase):
|
||||
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
||||
}
|
||||
|
||||
form = RegistrationFormUniqueEmail(form_data)
|
||||
form = RegistrationFormSex(form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post('/rowers/register/', form_data, follow=True)
|
||||
@@ -117,6 +118,7 @@ class NewUserRegistrationTest(TestCase):
|
||||
'password1':'aapindewei2',
|
||||
'password2':'aapindewei2',
|
||||
'tos':True,
|
||||
'url': '',
|
||||
'weightcategory':'hwt',
|
||||
'adaptiveclass': 'None',
|
||||
'sex':'male',
|
||||
@@ -124,5 +126,34 @@ class NewUserRegistrationTest(TestCase):
|
||||
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
||||
}
|
||||
|
||||
form = RegistrationFormUniqueEmail(form_data)
|
||||
form = RegistrationFormSex(form_data)
|
||||
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/'
|
||||
|
||||
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)
|
||||
if form.is_valid():
|
||||
first_name = form.cleaned_data['first_name']
|
||||
|
||||
Reference in New Issue
Block a user