### Install django-formguard Source: https://github.com/dmptrluke/django-formguard/blob/master/README.md Install the library using pip. This is the first step to integrating formguard into your Django project. ```bash pip install django-formguard ``` -------------------------------- ### Add formguard to INSTALLED_APPS Source: https://github.com/dmptrluke/django-formguard/blob/master/README.md After installation, add 'formguard' to your Django project's INSTALLED_APPS setting to enable its features. ```python INSTALLED_APPS = [ ... 'formguard', ] ``` -------------------------------- ### Exclude Default Checks Using `default_checks()` Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/configuration.md Start with default checks and exclude specific ones by using `default_checks()` with the `exclude` argument. This is useful for forms that only need a subset of standard security measures. ```python from formguard.conf import default_checks class LoginForm(GuardedFormMixin, forms.Form): guard_checks = default_checks(exclude=['formguard.checks.InteractionCheck']) username = forms.CharField() password = forms.CharField(widget=forms.PasswordInput) ``` -------------------------------- ### Custom Failure Handling with Formguard Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/function-based-views.md After `is_valid()` returns `False`, check `form.guard_failures` to handle specific guard failures. This example implements a silent reject. ```python def contact_view(request): form = ContactForm(request.POST or None, request=request) if request.method == 'POST': if form.is_valid(): send_email(form.cleaned_data) return redirect('/thanks/') if form.guard_failures: return redirect('/thanks/') # silent reject return render(request, 'contact.html', {'form': form}) ``` -------------------------------- ### Set up a Guarded Form Source: https://github.com/dmptrluke/django-formguard/blob/master/README.md Integrate GuardedFormMixin into your Django forms. Customize the checks used by default or exclude specific ones. ```python from django import forms from formguard.conf import default_checks from formguard.forms import GuardedFormMixin class ContactForm(GuardedFormMixin, forms.Form): guard_checks = default_checks(exclude=['formguard.checks.InteractionCheck']) name = forms.CharField() email = forms.EmailField() message = forms.CharField(widget=forms.Textarea) ``` -------------------------------- ### Include FormGuard Media in Template Source: https://github.com/dmptrluke/django-formguard/blob/master/README.md Ensure {{ form.media }} is included in your template's to load necessary CSS and JS for FormGuard checks. ```html {{ form.media }}
{% csrf_token %} {{ form }}
``` -------------------------------- ### Configure IP Forwarding for Turnstile Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Set FORMGUARD_TURNSTILE_IP_HEADER to the appropriate request.META key to forward the client IP to Cloudflare during verification. ```python # behind Cloudflare proxy FORMGUARD_TURNSTILE_IP_HEADER = 'HTTP_CF_CONNECTING_IP' # behind a standard reverse proxy FORMGUARD_TURNSTILE_IP_HEADER = 'HTTP_X_FORWARDED_FOR' # direct connection FORMGUARD_TURNSTILE_IP_HEADER = 'REMOTE_ADDR' ``` -------------------------------- ### Configure Turnstile Options Per-Form Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Customize Turnstile widget behavior like callback and appearance for a specific form using `guard_check_options`. ```python from formguard.conf import default_checks class SignupForm(GuardedFormMixin, forms.Form): guard_checks = default_checks(include=['formguard.contrib.turnstile.TurnstileCheck']) guard_check_options = { 'formguard.contrib.turnstile.TurnstileCheck': { 'CALLBACK': 'onTurnstileComplete', 'APPEARANCE': 'interaction-only', }, } ... ``` -------------------------------- ### Access Check-Scoped Settings Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/custom-checks.md Define `settings_prefix` and `defaults` for check-specific settings. Use `self.get_setting('NAME')` to read these settings, which fall back to Django settings prefixed with `FORMGUARD_{PREFIX}_`. ```python class MyCheck(BaseCheck): settings_prefix = 'MYCHECK' defaults = { 'THRESHOLD': 5, 'API_KEY': None, # no default -- must be configured } def check(self, form): threshold = self.get_setting('THRESHOLD') # reads FORMGUARD_MYCHECK_THRESHOLD api_key = self.get_setting('API_KEY') # reads FORMGUARD_MYCHECK_API_KEY ... ``` -------------------------------- ### Configure FormGuard Checks Source: https://github.com/dmptrluke/django-formguard/blob/master/README.md Customize FormGuard's behavior by modifying settings. You can add custom checks or tune the built-in ones. ```python # add a custom check alongside the builtins from formguard.conf import BUILTINS FORMGUARD_CHECKS = BUILTINS + [ 'myapp.checks.TurnstileCheck', ] # tune the built-in checks FORMGUARD_FIELD_TRAP_FIELD_NAME = 'website' # default FORMGUARD_TOKEN_MIN_SECONDS = 3 # default FORMGUARD_TOKEN_MAX_SECONDS = 3600 # default ``` -------------------------------- ### Connect to Formguard Signals Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/signals.md Connect custom functions to `guard_failed` and `guard_checked` signals to perform actions based on check outcomes. The `guard_failed` signal is useful for logging specific failure reasons, while `guard_checked` can be used for metrics. ```python from formguard.signals import guard_failed, guard_checked def on_guard_failed(sender, request, form, results, **kwargs): for r in results: if not r.passed: log_failure(r.reason, r.check_name) def on_guard_checked(sender, request, form, results, **kwargs): for r in results: metrics.increment( f'guard.{r.check_name}', tags={'passed': r.passed}, ) guard_failed.connect(on_guard_failed) guard_checked.connect(on_guard_checked) ``` -------------------------------- ### Implementing Custom Check test_data() Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/testing.md For custom checks, implement the `test_data()` method to return valid POST data for the check's fields. `guard_data()` automatically aggregates the `test_data()` from all active checks. ```python class MyCheck(BaseCheck): def get_fields(self): return {'my_field': forms.CharField(required=False)} def test_data(self): return {'my_field': 'valid-value'} def check(self, form): if form.cleaned_data.get('my_field') != 'valid-value': return 'invalid' return None ``` -------------------------------- ### Render All Guard Fields Manually in a Template Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/configuration.md If rendering form fields individually in templates, use `{{ form.guard_fields }}` to display all necessary guard-related fields (honeypot, token, nonce, JS challenge) automatically. ```html
{% csrf_token %} {{ form.guard_fields }} {{ form.name }}
``` -------------------------------- ### Test Form Submission with GuardedFormTestMixin Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Utilize GuardedFormTestMixin to easily test form submissions, including Turnstile verification, by including `self.guard_data()` in your test data. ```python from formguard.test import GuardedFormTestMixin class SignupViewTests(GuardedFormTestMixin, TestCase): def test_valid_signup(self): data = {'username': 'alice', 'email': 'a@b.com', **self.guard_data()} response = self.client.post('/signup/', data) assert response.status_code == 302 ``` -------------------------------- ### Configure Turnstile Site and Secret Keys Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Set your Cloudflare site and secret keys in Django settings to enable Turnstile verification. ```python FORMGUARD_TURNSTILE_SITE_KEY = 'your-site-key' FORMGUARD_TURNSTILE_SECRET_KEY = 'your-secret-key' ``` -------------------------------- ### Silent Redirect with `reject_silently` Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/failure-handling.md Use `reject_silently` to redirect bots to the success URL without showing validation errors. This handler is useful for preventing bots from knowing their checks failed. ```python from formguard.handlers import reject_silently from formguard.views import GuardedFormViewMixin class ContactView(GuardedFormViewMixin, FormView): form_class = ContactForm template_name = 'contact.html' success_url = '/thanks/' guard_on_failure = reject_silently() ``` -------------------------------- ### Basic Formguard Integration in Function-Based View Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/function-based-views.md Pass the request object to the form constructor. Guard checks are automatically performed during `is_valid()`. ```python def contact_view(request): form = ContactForm(request.POST or None, request=request) if request.method == 'POST' and form.is_valid(): send_email(form.cleaned_data) return redirect('/thanks/') return render(request, 'contact.html', {'form': form}) ``` -------------------------------- ### Register Custom Check Globally Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/custom-checks.md Add your custom check's import path to the `FORMGUARD_CHECKS` setting to make it available for all forms. ```python from formguard.conf import BUILTINS FORMGUARD_CHECKS = BUILTINS + [ 'myapp.checks.RateLimitCheck', ] ``` -------------------------------- ### Custom Callable Handler for Failures Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/failure-handling.md Implement a custom callable function to handle guard check failures. This allows for custom logic, such as logging bot activity, before redirecting the user. The callable must return an `HttpResponse` or `None` to fall through to normal error rendering. ```python from django.shortcuts import redirect def log_and_reject(request, form, success_url=None, **kwargs): analytics.track('bot_blocked', ip=request.META['REMOTE_ADDR']) return redirect(success_url) class ContactView(GuardedFormViewMixin, FormView): form_class = ContactForm success_url = '/thanks/' guard_on_failure = log_and_reject ``` -------------------------------- ### Register TurnstileCheck Globally Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Include 'formguard.contrib.turnstile.TurnstileCheck' in your global FORMGUARD_CHECKS setting to apply Turnstile to all guarded forms. ```python from formguard.conf import BUILTINS FORMGUARD_CHECKS = BUILTINS + [ 'formguard.contrib.turnstile.TurnstileCheck', ] ``` -------------------------------- ### Basic GuardedFormTestMixin Usage Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/testing.md Mix `GuardedFormTestMixin` into your test case to access `guard_data()`. This method returns a dictionary containing valid guard fields for all active checks, simplifying test data creation. ```python from django.test import TestCase from formguard.test import GuardedFormTestMixin class TestContactView(GuardedFormTestMixin, TestCase): def test_submission_works(self): data = { 'name': 'Test', 'email': 'test@example.com', 'message': 'Hello', **self.guard_data(), } response = self.client.post('/contact/', data) assert response.status_code == 302 ``` -------------------------------- ### Silent Redirect with Custom Message Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/failure-handling.md You can add a Django success message to the silent redirect by passing a message to `reject_silently`. This provides feedback to the user while still silently handling bot failures. ```python guard_on_failure = reject_silently(message='Your message has been sent.') ``` -------------------------------- ### Handle Async Views with TurnstileCheck Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Wrap form validation with `sync_to_async` when using TurnstileCheck in asynchronous Django views to handle its synchronous HTTP calls. ```python from asgiref.sync import sync_to_async valid = await sync_to_async(form.is_valid)() ``` -------------------------------- ### Create a Custom TurnstileCheck Subclass Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Subclass `TurnstileCheck` to implement custom logic, such as skipping verification for trusted IP addresses, before calling the parent `check` method. ```python from formguard.contrib.turnstile import TurnstileCheck class ConditionalTurnstileCheck(TurnstileCheck): def check(self, form): if is_trusted_ip(form.request): return None return super().check(form) ``` -------------------------------- ### Use Cloudflare Test Keys for Turnstile Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Configure Cloudflare's test site and secret keys in your Django settings for testing Turnstile verification without network access. ```python FORMGUARD_TURNSTILE_SITE_KEY = '1x00000000000000000000AA' FORMGUARD_TURNSTILE_SECRET_KEY = '1x0000000000000000000000000000000AA' ``` -------------------------------- ### Testing Forms with Per-Form Checks Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/testing.md When a form defines its own `guard_checks`, pass the form class to `guard_data()` to ensure the helper generates data specifically for that form's checks. This is useful for forms with custom check configurations. ```python from formguard.conf import default_checks class LoginForm(GuardedFormMixin, forms.Form): guard_checks = default_checks(exclude=['formguard.checks.InteractionCheck']) username = forms.CharField() password = forms.CharField(widget=forms.PasswordInput) class TestLoginView(GuardedFormTestMixin, TestCase): def test_submission_works(self): data = { 'username': 'alice', 'password': 'secret', **self.guard_data(form_class=LoginForm), } response = self.client.post('/login/', data) assert response.status_code == 302 ``` -------------------------------- ### Use GuardedFormViewMixin in Class-Based Views Source: https://github.com/dmptrluke/django-formguard/blob/master/README.md For class-based views, inherit from GuardedFormViewMixin to automatically handle FormGuard checks within the form submission process. ```python from django.views.generic import FormView from formguard.views import GuardedFormViewMixin class ContactView(GuardedFormViewMixin, FormView): form_class = ContactForm template_name = 'contact.html' success_url = '/thanks/' def form_valid(self, form): send_email(form.cleaned_data) return super().form_valid(form) ``` -------------------------------- ### Define a Custom Rate Limit Check Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/custom-checks.md Subclass `BaseCheck` to create a custom check. Implement the `check` method to define validation logic. Access request details via `form.request`. The `message` attribute defines the user-facing error. ```python # myapp/checks.py from formguard.checks import BaseCheck class RateLimitCheck(BaseCheck): message = 'Too many submissions. Please wait and try again.' def check(self, form): ip = form.request.META.get('REMOTE_ADDR') if is_rate_limited(ip): return 'rate limited' return None ``` -------------------------------- ### Register TurnstileCheck Per-Form Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/turnstile.md Use the `guard_checks` attribute on a specific form to include 'formguard.contrib.turnstile.TurnstileCheck' for that form only. ```python from formguard.conf import default_checks class SignupForm(GuardedFormMixin, forms.Form): guard_checks = default_checks(include=['formguard.contrib.turnstile.TurnstileCheck']) ... ``` -------------------------------- ### Pass Form Class to `guard_data()` for Testing Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/configuration.md When testing forms with custom `guard_checks`, ensure `guard_data()` receives the form class to generate appropriate test data for the specific checks configured. ```python data = self.guard_data(form_class=ContactForm) ``` -------------------------------- ### `guard_checked` Signal Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/signals.md This signal is emitted after every check run, regardless of whether the checks passed or failed. It's useful for logging or metric collection. ```APIDOC ## `guard_checked` Signal ### Description Fires after every check run, regardless of outcome. ### Arguments - `sender` (form class): The form class that initiated the check. - `request` (HttpRequest): The current HTTP request object. - `form` (bound form instance): The bound form instance being validated. - `results` (List[GuardResult]): A list of `GuardResult` objects detailing the outcome of each check. ### Example Usage ```python from formguard.signals import guard_checked def on_guard_checked(sender, request, form, results, **kwargs): for r in results: metrics.increment( f'guard.{r.check_name}', tags={'passed': r.passed}, ) guard_checked.connect(on_guard_checked) ``` ``` -------------------------------- ### Define Form Fields for a Custom Check Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/custom-checks.md Implement `get_fields` to declare form fields required by your check. These fields will be automatically aggregated into the main form. ```python from django import forms from formguard.checks import BaseCheck class SecretWordCheck(BaseCheck): settings_prefix = 'SECRET_WORD' defaults = {'ANSWER': 'swordfish'} message = 'Incorrect secret word.' def get_fields(self): return { 'secret_word': forms.CharField(required=False), } def check(self, form): answer = self.get_setting('ANSWER') if form.cleaned_data.get('secret_word', '') != answer: return 'wrong secret word' return None def test_data(self): return {'secret_word': self.get_setting('ANSWER')} ``` -------------------------------- ### Override Check Options on a Specific Form Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/configuration.md Use `guard_check_options` to override settings for specific checks on a form. Keys are dotted check paths, and values are dictionaries of setting overrides, which take precedence over global settings and check defaults. ```python class InterstitialForm(GuardedFormMixin, forms.Form): guard_checks = [ 'formguard.contrib.turnstile.TurnstileCheck', ] guard_check_options = { 'formguard.contrib.turnstile.TurnstileCheck': { 'CALLBACK': 'onTurnstileComplete', }, } ``` -------------------------------- ### Define Per-Form Checks for a Django Form Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/configuration.md Use `guard_checks` on a form class to specify checks different from the global settings. This allows granular control over security for individual forms. ```python class ContactForm(GuardedFormMixin, forms.Form): guard_checks = [ 'formguard.checks.FieldTrapCheck', 'formguard.checks.TokenCheck', ] name = forms.CharField() message = forms.CharField(widget=forms.Textarea) ``` -------------------------------- ### `guard_failed` Signal Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/signals.md This signal fires only when at least one validation check fails. It provides details about the failed checks through the `results` argument. ```APIDOC ## `guard_failed` Signal ### Description Fires only when at least one check fails. ### Arguments - `sender` (form class): The form class that initiated the check. - `request` (HttpRequest): The current HTTP request object. - `form` (bound form instance): The bound form instance being validated. - `results` (List[GuardResult]): A list of `GuardResult` objects detailing the outcome of each check. ### Example Usage ```python from formguard.signals import guard_failed def on_guard_failed(sender, request, form, results, **kwargs): for r in results: if not r.passed: log_failure(r.reason, r.check_name) guard_failed.connect(on_guard_failed) ``` ``` -------------------------------- ### Apply Custom Check to a Specific Form Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/custom-checks.md Use the `guard_checks` attribute on a form class to apply specific checks to that form only. ```python class ContactForm(GuardedFormMixin, forms.Form): guard_checks = [ 'formguard.checks.FieldTrapCheck', 'myapp.checks.RateLimitCheck', ] name = forms.CharField() ``` -------------------------------- ### GuardResult Object Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/signals.md Details about the outcome of an individual validation check. ```APIDOC ## `GuardResult` Object ### Description Represents the outcome of a single check performed by formguard. ### Attributes - `reason` (string or None): The reason string for a failed check (e.g., `'honeypot field filled'`), or `None` if the check passed. - `check` (Check instance): The check instance that produced this result. - `check_name` (string): The class name of the check (e.g., `'FieldTrapCheck'`). - `passed` (boolean): `True` if the check passed, `False` if it was triggered (failed). ### String Representation `str(result)` returns the `reason` for failures or the `check_name` for passes. ``` -------------------------------- ### Override `form_invalid` for Full Control Source: https://github.com/dmptrluke/django-formguard/blob/master/docs/failure-handling.md Override the `form_invalid` method in your Django view for complete control over failure handling. This approach provides access to `self` (the view instance) and allows direct inspection of `form.guard_failures` for custom logic like IP banning. ```python class ContactView(GuardedFormViewMixin, FormView): form_class = ContactForm success_url = '/thanks/' def form_invalid(self, form): if form.guard_failures: ban_ip(self.request.META['REMOTE_ADDR']) return redirect(self.get_success_url()) return super().form_invalid(form) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.