Private
Public Access
1
0

some fixes, honeypot registration

This commit is contained in:
2025-08-13 10:31:03 +02:00
parent 909aa2013e
commit 781321eadd
5 changed files with 68 additions and 4 deletions

View File

@@ -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'

View File

@@ -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

View File

@@ -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)

Binary file not shown.

View File

@@ -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']