diff --git a/README.md b/README.md index 88a6f14..efecacf 100755 --- a/README.md +++ b/README.md @@ -67,10 +67,10 @@ python manage.py collectstatic Add the following to your `settings.py`: ```python -CAPTCHA_VERIFY_URL = 'https://your-hoptcha-domain.com/captcha/validate/' -CAPTCHA_GENERATE_URL = 'https://your-hoptcha-domain.com/captcha/' -CAPTCHA_PUBLIC_KEY = 'your-client-key' -CAPTCHA_PRIVATE_KEY = 'your-secret-key' +HOPTCHA_URL = 'https://your-hoptcha-domain.com/captcha/validate/' +HOPTCHA_VERIFY_URL = 'https://your-hoptcha-domain.com/captcha/' +HOPTCHA_CLIENT_ID = 'your-client-key' +HOPTCHA_CLIENT_SECRET = 'your-secret-key' ``` > These credentials are provided by the Hoptcha service when you register your application. @@ -204,17 +204,18 @@ configureHoptcha({ ## 🔧 Customization -| Parameter | Description | Default | -|-------------|--------------------------------------------------------------|---------------| -| `key` | Function or string to identify requestor (IP, user ID, etc.) | `ip` | -| `threshold` | Number of allowed attempts before CAPTCHA is required | `5` | -| `timeout` | Time in seconds to reset attempt count | `300` (5 min) | -| `backoff` | Exponentially increase timeout if repeatedly exceeded | `False` | -| `response` | Optional custom response function on CAPTCHA failure | `None` | -| `exempt_if` | Skip protection for trusted users | For staff | -| `methods` | HTTP methods to track (POST, GET, etc.) | POST | -| `shared` | Share same attempts counter among all endpoints | `False` | -| `type` | Type of CAPTCHA do display (sliding, pointing, random) | `random` | +| Parameter | Description | Default | +|----------------|--------------------------------------------------------------|---------------| +| `key` | Function or string to identify requestor (IP, user ID, etc.) | `ip` | +| `threshold` | Number of allowed attempts before CAPTCHA is required | `5` | +| `timeout` | Time in seconds to reset attempt count | `300` (5 min) | +| `backoff` | Exponentially increase timeout if repeatedly exceeded | `False` | +| `response` | Optional custom response function on CAPTCHA failure | `None` | +| `exempt_if` | Skip protection for trusted users | For staff | +| `methods` | HTTP methods to track (POST, GET, etc.) | POST | +| `shared` | Share same attempts counter among all endpoints | `False` | +| `type` | Type of CAPTCHA do display (sliding, pointing, random) | `random` | +| `debug_ignore` | Do not bypass CAPTCHA if in debug mode | `False` | --- @@ -226,4 +227,4 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file ## 🤝 Contributing -Contributions are welcome! Open issues or pull requests on [GitHub](https://github.com/yourusername/django-hoptcha). +Contributions are welcome! Open issues or pull requests on [Git](https://git.hopsenn.com/hopsenn/django-hoptcha). diff --git a/django_hoptcha/decorators.py b/django_hoptcha/decorators.py index 3ff2d30..9c4b607 100755 --- a/django_hoptcha/decorators.py +++ b/django_hoptcha/decorators.py @@ -32,7 +32,11 @@ from django.core.cache import cache from django.http import JsonResponse from .validators import verify_token -from .settings import GENERATE_URL, PUBLIC_KEY +from .settings import ( + HOPTCHA_URL, + HOPTCHA_CLIENT_ID, + DEBUG +) # Built-in key functions def get_ip(request): @@ -60,6 +64,7 @@ def hoptcha_protected( backoff=False, shared=False, type=None, + debug_ignore=False ): """ Enforces CAPTCHA if request exceeds `threshold`. @@ -73,8 +78,12 @@ def hoptcha_protected( - methods: HTTP methods to track (default: POST). - shared: Share same attempts counter among all endpoints. - type: Type of CAPTCHA do display (sliding, pointing, random) + - debug_ignore: do not bypass CAPTCHA if in debug mode. """ + if DEBUG and not debug_ignore: + return view_func(request, *args, **kwargs) + if isinstance(key, str): key_func = BUILTIN_KEYS.get(key) @@ -122,7 +131,7 @@ def hoptcha_protected( if not token or not verify_token(token): return response(request) if response else JsonResponse({ "captcha": True, - "url": f"{GENERATE_URL}?{urlencode({'client_key': PUBLIC_KEY, 'timestamp': int(time.time() * 1000), 'type': type})}" + "url": f"{HOPTCHA_URL}?{urlencode({'client_key': HOPTCHA_CLIENT_ID, 'timestamp': int(time.time() * 1000), 'type': type})}" }, status=200) else: cache.delete(cache_key) # reset counter if passed diff --git a/django_hoptcha/settings.py b/django_hoptcha/settings.py index 10733bf..a7458aa 100755 --- a/django_hoptcha/settings.py +++ b/django_hoptcha/settings.py @@ -27,7 +27,10 @@ from django.conf import settings def get(key, default=None): return getattr(settings, key, default) -VERIFY_URL = get('CAPTCHA_VERIFY_URL', 'https://hoptcha.com/captcha/validate/') -GENERATE_URL = get('CAPTCHA_GENERATE_URL', 'https://hoptcha.com/captcha/') -PUBLIC_KEY = get('CAPTCHA_PUBLIC_KEY', '') -PRIVATE_KEY = get('CAPTCHA_PRIVATE_KEY', '') +HOPTCHA_URL = get('HOPTCHA_URL', 'https://hoptcha.com/captcha/') +HOPTCHA_VERIFY_URL = get('CAPTCHA_VERIFY_URL', 'https://hoptcha.com/captcha/validate/') + +HOPTCHA_CLIENT_ID = get('HOPTCHA_CLIENT_ID', '') +HOPTCHA_CLIENT_SECRET = get('HOPTCHA_CLIENT_SECRET', '') + +DEBUG = get('DEBUG', False) diff --git a/django_hoptcha/validators.py b/django_hoptcha/validators.py index 17a6fc4..00e22ff 100755 --- a/django_hoptcha/validators.py +++ b/django_hoptcha/validators.py @@ -26,9 +26,9 @@ import json import requests from .settings import ( - VERIFY_URL, - PUBLIC_KEY, - PRIVATE_KEY + HOPTCHA_VERIFY_URL, + HOPTCHA_CLIENT_ID, + HOPTCHA_CLIENT_SECRET ) @@ -36,11 +36,11 @@ def verify_token(token): try: payload = { "token": token, - "client_key": PUBLIC_KEY, - "client_secret": PRIVATE_KEY, + "client_key": HOPTCHA_CLIENT_ID, + "client_secret": HOPTCHA_CLIENT_SECRET, } headers = {"Content-Type": "application/json"} - response = requests.post(VERIFY_URL, data=json.dumps(payload), headers=headers, timeout=5) + response = requests.post(HOPTCHA_VERIFY_URL, data=json.dumps(payload), headers=headers, timeout=5) if response.status_code == 200: return response.json().get("success", False)