From b82c0b4dd5f8b6ee8335b8b875807e9be9097dd9 Mon Sep 17 00:00:00 2001 From: Keshav Priyadarshi Date: Thu, 23 Jan 2025 20:51:48 +0530 Subject: [PATCH 1/4] Add configuration for django-recaptcha Signed-off-by: Keshav Priyadarshi --- federatedcode/settings.py | 5 +++++ requirements.txt | 1 + setup.cfg | 3 +++ 3 files changed, 9 insertions(+) diff --git a/federatedcode/settings.py b/federatedcode/settings.py index bc7285b..74e05dd 100644 --- a/federatedcode/settings.py +++ b/federatedcode/settings.py @@ -61,6 +61,10 @@ FEDERATEDCODE_CLIENT_ID = env.str("FEDERATEDCODE_CLIENT_ID") FEDERATEDCODE_CLIENT_SECRET = env.str("FEDERATEDCODE_CLIENT_SECRET") +RECAPTCHA_PUBLIC_KEY = env.str("RECAPTCHA_PUBLIC_KEY") +RECAPTCHA_PRIVATE_KEY = env.str("RECAPTCHA_PRIVATE_KEY") +SILENCED_SYSTEM_CHECKS = ["captcha.recaptcha_test_key_error"] +RECAPTCHA_DOMAIN = env.str("RECAPTCHA_DOMAIN", "www.recaptcha.net") # Application definition @@ -78,6 +82,7 @@ "django.contrib.humanize", # Third-party apps "oauth2_provider", + "django_recaptcha", ] MIDDLEWARE = [ diff --git a/requirements.txt b/requirements.txt index 28cd1cb..e617873 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,7 @@ Django==5.1.2 django-environ==0.11.2 django-ninja==1.3.0 django-oauth-toolkit==3.0.1 +django-recaptcha==4.0.0 djangorestframework==3.15.2 doc8==1.1.2 docutils==0.21.2 diff --git a/setup.cfg b/setup.cfg index 7285ae8..a2368bd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -76,6 +76,9 @@ install_requires = python-dotenv==1.0.1 click==8.1.7 + # Captcha + django-recaptcha==4.0.0 + [options.extras_require] dev = # Validation From 720c48d0dd3cc009f10ea06c17e0fac3b3807dba Mon Sep 17 00:00:00 2001 From: Keshav Priyadarshi Date: Thu, 23 Jan 2025 21:01:01 +0530 Subject: [PATCH 2/4] Add captcha to user signup page Signed-off-by: Keshav Priyadarshi --- fedcode/forms.py | 5 +++++ fedcode/templates/user_sign_up.html | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fedcode/forms.py b/fedcode/forms.py index 98550b9..376d87a 100644 --- a/fedcode/forms.py +++ b/fedcode/forms.py @@ -10,6 +10,8 @@ from django import forms from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User +from django_recaptcha.fields import ReCaptchaField +from django_recaptcha.widgets import ReCaptchaV2Checkbox from .models import Note from .models import Repository @@ -58,6 +60,9 @@ def __init__(self, *args, **kwargs): class PersonSignUpForm(UserCreationForm): + captcha = ReCaptchaField( + error_messages={"required": ("Captcha is required")}, widget=ReCaptchaV2Checkbox + ) email = forms.EmailField(max_length=254) class Meta: diff --git a/fedcode/templates/user_sign_up.html b/fedcode/templates/user_sign_up.html index 601e798..4924ea8 100644 --- a/fedcode/templates/user_sign_up.html +++ b/fedcode/templates/user_sign_up.html @@ -17,7 +17,9 @@

Error

- {{ form.errors }} + {% for error in form.errors.values %} + {{ error }} + {% endfor %}
@@ -61,6 +63,11 @@

User Signup

autocomplete="new-password" required id="id_password2"> +
+
+ {{ form.captcha }} +
+
From c7a2630715e07cae5c070b1c5c544b65ef6ff1f7 Mon Sep 17 00:00:00 2001 From: Keshav Priyadarshi Date: Thu, 23 Jan 2025 21:03:53 +0530 Subject: [PATCH 3/4] Add captcha to user login page Signed-off-by: Keshav Priyadarshi --- fedcode/forms.py | 10 ++++++++++ fedcode/templates/login.html | 11 +++++++++-- fedcode/views.py | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/fedcode/forms.py b/fedcode/forms.py index 376d87a..0a112ce 100644 --- a/fedcode/forms.py +++ b/fedcode/forms.py @@ -8,6 +8,7 @@ # from django import forms +from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django_recaptcha.fields import ReCaptchaField @@ -146,3 +147,12 @@ class SearchRepositoryForm(forms.Form): }, ), ) + + +class UserLoginForm(AuthenticationForm): + captcha = ReCaptchaField( + error_messages={ + "required": ("Captcha is required"), + }, + widget=ReCaptchaV2Checkbox, + ) diff --git a/fedcode/templates/login.html b/fedcode/templates/login.html index 6e3d27a..834312d 100644 --- a/fedcode/templates/login.html +++ b/fedcode/templates/login.html @@ -10,7 +10,10 @@ {% if form.errors %}
- Error! Your username and password didn't match. Please try again. + Error! + {% for error in form.errors.values %} + {{ error }} + {% endfor %}
{% endif %} @@ -32,7 +35,11 @@

User Login

autocomplete="current-password" required id="id_password"> - +
+
+ {{ form.captcha }} +
+
diff --git a/fedcode/views.py b/fedcode/views.py index de95a09..a94217d 100644 --- a/fedcode/views.py +++ b/fedcode/views.py @@ -57,6 +57,7 @@ from fedcode.forms import SearchRepositoryForm from fedcode.forms import SearchReviewForm from fedcode.forms import SubscribePackageForm +from fedcode.forms import UserLoginForm from fedcode.models import Follow from fedcode.models import Note from fedcode.models import Package @@ -277,6 +278,7 @@ def post(self, request, repository_id): class UserLogin(LoginView): template_name = "login.html" next_page = "/" + form_class = UserLoginForm def dispatch(self, request, *args, **kwargs): # If user is already logged in, redirect to the next_page. From b79876a8535593d9d26fb123db01282e16635663 Mon Sep 17 00:00:00 2001 From: Keshav Priyadarshi Date: Thu, 23 Jan 2025 21:10:47 +0530 Subject: [PATCH 4/4] Add captcha challenge on admin login page Signed-off-by: Keshav Priyadarshi --- fedcode/forms.py | 10 +++++ fedcode/templates/admin_login.html | 66 ++++++++++++++++++++++++++++++ fedcode/views.py | 7 +++- federatedcode/settings.py | 4 +- federatedcode/urls.py | 2 + 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 fedcode/templates/admin_login.html diff --git a/fedcode/forms.py b/fedcode/forms.py index 0a112ce..261c384 100644 --- a/fedcode/forms.py +++ b/fedcode/forms.py @@ -8,6 +8,7 @@ # from django import forms +from django.contrib.admin.forms import AdminAuthenticationForm from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User @@ -156,3 +157,12 @@ class UserLoginForm(AuthenticationForm): }, widget=ReCaptchaV2Checkbox, ) + + +class AdminLoginForm(AdminAuthenticationForm): + captcha = ReCaptchaField( + error_messages={ + "required": ("Captcha is required"), + }, + widget=ReCaptchaV2Checkbox(), + ) diff --git a/fedcode/templates/admin_login.html b/fedcode/templates/admin_login.html new file mode 100644 index 0000000..074ca6e --- /dev/null +++ b/fedcode/templates/admin_login.html @@ -0,0 +1,66 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block extrastyle %}{{ block.super }} +{{ form.media }} +{% endblock %} + +{% block bodyclass %}{{ block.super }} login{% endblock %} + +{% block usertools %}{% endblock %} + +{% block nav-global %}{% endblock %} + +{% block nav-sidebar %}{% endblock %} + +{% block content_title %}{% endblock %} + +{% block nav-breadcrumbs %}{% endblock %} + +{% block content %} + +{% if form.errors %} +{% for error in form.errors.values %} +

{{ error }}

+{% endfor %} +{% endif %} + + +
+ + {% if user.is_authenticated %} +

+ {% blocktranslate trimmed %} + You are authenticated as {{ username }}, but are not authorized to + access this page. Would you like to login to a different account? + {% endblocktranslate %} +

+ {% endif %} + +
{% csrf_token %} +
+ {{ form.username.errors }} + {{ form.username.label_tag }} {{ form.username }} +
+
+ {{ form.password.errors }} + {{ form.password.label_tag }} {{ form.password }} + +
+ {% url 'admin_password_reset' as password_reset_url %} + {% if password_reset_url %} + + {% endif %} +
+
+ {{ form.captcha }} +
+
+
+ +
+
+
+{% endblock %} diff --git a/fedcode/views.py b/fedcode/views.py index a94217d..de129b6 100644 --- a/fedcode/views.py +++ b/fedcode/views.py @@ -10,7 +10,6 @@ import json import logging import os.path -from urllib.parse import urlparse import requests from django.contrib import messages @@ -47,6 +46,7 @@ from fedcode.activitypub import AP_CONTEXT from fedcode.activitypub import create_activity_obj from fedcode.activitypub import has_valid_header +from fedcode.forms import AdminLoginForm from fedcode.forms import CreateGitRepoForm from fedcode.forms import CreateNoteForm from fedcode.forms import CreateReviewForm @@ -889,3 +889,8 @@ def revoke_token(request): }, ) return JsonResponse(json.loads(r.content), status=r.status_code, content_type=AP_CONTENT_TYPE) + + +class AdminLoginView(LoginView): + template_name = "admin_login.html" + authentication_form = AdminLoginForm diff --git a/federatedcode/settings.py b/federatedcode/settings.py index 74e05dd..07d36e5 100644 --- a/federatedcode/settings.py +++ b/federatedcode/settings.py @@ -61,8 +61,8 @@ FEDERATEDCODE_CLIENT_ID = env.str("FEDERATEDCODE_CLIENT_ID") FEDERATEDCODE_CLIENT_SECRET = env.str("FEDERATEDCODE_CLIENT_SECRET") -RECAPTCHA_PUBLIC_KEY = env.str("RECAPTCHA_PUBLIC_KEY") -RECAPTCHA_PRIVATE_KEY = env.str("RECAPTCHA_PRIVATE_KEY") +RECAPTCHA_PUBLIC_KEY = env.str("RECAPTCHA_PUBLIC_KEY", "") +RECAPTCHA_PRIVATE_KEY = env.str("RECAPTCHA_PRIVATE_KEY", "") SILENCED_SYSTEM_CHECKS = ["captcha.recaptcha_test_key_error"] RECAPTCHA_DOMAIN = env.str("RECAPTCHA_DOMAIN", "www.recaptcha.net") diff --git a/federatedcode/urls.py b/federatedcode/urls.py index 5457cd9..934528b 100644 --- a/federatedcode/urls.py +++ b/federatedcode/urls.py @@ -13,6 +13,7 @@ from django.urls import path from fedcode import views +from fedcode.views import AdminLoginView from fedcode.views import CreateReview from fedcode.views import CreateSync from fedcode.views import CreatGitView @@ -45,6 +46,7 @@ from fedcode.views import redirect_vulnerability urlpatterns = [ + path("admin/login/", AdminLoginView.as_view(), name="admin-login"), path("admin/", admin.site.urls), path(".well-known/webfinger", WebfingerView.as_view(), name="web-finger"), path("", HomeView.as_view(), name="home-page"),