django-powcaptcha 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ from django.core.exceptions import ImproperlyConfigured
4
4
 
5
5
  SETTINGS_TYPES = {
6
6
  'POWCAPTCHA_API_URL': str,
7
- 'POWCAPTCHA_API_KEY': str,
7
+ 'POWCAPTCHA_API_TOKEN': str,
8
8
  }
9
9
 
10
10
  # Validate settings types.
@@ -1,3 +1,4 @@
1
+ from django.core.cache import cache
1
2
  import json
2
3
  from urllib.error import HTTPError
3
4
  from urllib.request import Request, build_opener
@@ -14,7 +15,7 @@ def powcaptcha_request(path, params):
14
15
  token = getattr(settings, 'POWCAPTCHA_API_TOKEN')
15
16
 
16
17
  request_object = Request(
17
- url=f'https://{domain}/{path}',
18
+ url=f'{domain}/{path}',
18
19
  data=params,
19
20
  headers={
20
21
  'Authorization': f'Bearer {token}',
@@ -31,13 +32,18 @@ def powcaptcha_request(path, params):
31
32
 
32
33
 
33
34
  def get_challenge():
34
- path = 'GetChallenges?difficultyLevel=5'
35
- response = powcaptcha_request(path, [])
36
- challenges = json.loads(response.read().decode('utf-8'))
35
+ challenges = cache.get('powcaptcha_challenges')
37
36
 
38
- # @Todo: implement caching
37
+ if not challenges or len(challenges) == 0:
38
+ path = 'GetChallenges?difficultyLevel=5'
39
+ response = powcaptcha_request(path, [])
40
+ challenges = json.loads(response.read().decode('utf-8'))
39
41
 
40
- return challenges[0]
42
+ challenge = challenges[0]
43
+ challenges.pop(0)
44
+ cache.set('powcaptcha_challenges', challenges, 3600)
45
+
46
+ return challenge
41
47
 
42
48
 
43
49
  def validate_captcha(challenge: str, nonce: str):
@@ -1,42 +1,8 @@
1
- import logging
2
-
3
1
  from django import forms
4
- from django.conf import settings
5
- from django.core.exceptions import ValidationError
6
- from django.utils.translation import gettext_lazy as _
7
-
8
- from django_powcaptcha import client
9
- from django_powcaptcha.client import PowCaptchaValidationException
10
- from django_powcaptcha.widgets import PowCaptchaWidget
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- class PowCaptchaField(forms.CharField):
16
- widget = PowCaptchaWidget
17
- default_error_messages = {
18
- 'captcha_invalid': _('Error verifying reCAPTCHA, please try again.'),
19
- 'captcha_error': _('Error verifying reCAPTCHA, please try again.'),
20
- }
21
-
22
- def __init__(self, api_key=None, api_url=None, *args, **kwargs):
23
- super().__init__(*args, **kwargs)
24
-
25
- self.required = True
26
2
 
27
- # Setup instance variables.
28
- self.api_key = api_key or getattr(settings, 'POWCAPTCHA_API_KEY')
29
- self.api_url = api_url or getattr(settings, 'POWCAPTCHA_API_URL')
3
+ from django_powcaptcha.widgets import PowCaptchaChallengeWidget
30
4
 
31
- def validate(self, value):
32
- super().validate(value)
33
5
 
34
- try:
35
- client.validate_captcha(
36
- challenge='',
37
- nonce='',
38
- )
39
- except PowCaptchaValidationException:
40
- raise ValidationError(
41
- self.error_messages['captcha_error'], code='captcha_error'
42
- )
6
+ class PowCaptchaChallengeField(forms.CharField):
7
+ required = True
8
+ widget = PowCaptchaChallengeWidget
@@ -0,0 +1,22 @@
1
+ from django import forms
2
+
3
+ from django_powcaptcha.client import validate_captcha, PowCaptchaValidationException
4
+ from django_powcaptcha.fields import PowCaptchaChallengeField
5
+
6
+
7
+ class PowCaptchaForm(forms.Form):
8
+ powcaptcha_challenge = PowCaptchaChallengeField()
9
+ powcaptcha_nonce = forms.CharField(widget=forms.HiddenInput(), required=True)
10
+
11
+ def clean(self):
12
+ cleaned_data = super().clean()
13
+
14
+ challenge = cleaned_data.get('powcaptcha_challenge', '')
15
+ nonce = cleaned_data.get('powcaptcha_nonce', '')
16
+
17
+ try:
18
+ validate_captcha(challenge, nonce)
19
+ except PowCaptchaValidationException:
20
+ raise forms.ValidationError('Failed to validate captcha')
21
+
22
+ return cleaned_data
@@ -0,0 +1,29 @@
1
+ <input type="hidden" name="powcaptcha_challenge" value="{{ captcha_challenge }}" />
2
+
3
+ <div
4
+ class="captcha-container"
5
+ data-sqr-captcha-url="{{ captcha_url }}"
6
+ data-sqr-captcha-challenge="{{ captcha_challenge }}"
7
+ data-sqr-captcha-callback="myCaptchaCallback">
8
+ </div>
9
+
10
+ <script src="{{ captcha_url }}/static/captcha.js"></script>
11
+ <script>
12
+ document.addEventListener('DOMContentLoaded', function() {
13
+ if (typeof window.myCaptchaCallback === 'function') {
14
+ return;
15
+ }
16
+
17
+ window.myCaptchaCallback = (nonce) => {
18
+ Array.from(document.querySelectorAll("input[name='powcaptcha_nonce']")).forEach(e => e.value = nonce);
19
+ Array.from(document.querySelectorAll("input[type='submit']")).forEach(e => e.disabled = false);
20
+ Array.from(document.querySelectorAll("button[type='submit']")).forEach(e => e.disabled = false);
21
+ };
22
+ });
23
+ </script>
24
+
25
+ <style>
26
+ .sqr-captcha-hidden {
27
+ display: none !important;
28
+ }
29
+ </style>
@@ -4,9 +4,9 @@ from django.forms import widgets
4
4
  from django_powcaptcha.client import get_challenge
5
5
 
6
6
 
7
- class PowCaptchaWidget(widgets.Widget):
7
+ class PowCaptchaChallengeWidget(widgets.Widget):
8
8
  input_type = 'hidden'
9
- template_name = 'django_recaptcha/widget.html'
9
+ template_name = 'django_powcaptcha/widget.html'
10
10
 
11
11
  def get_context(self, name, value, attrs):
12
12
  context = super().get_context(name, value, attrs)
@@ -18,10 +18,3 @@ class PowCaptchaWidget(widgets.Widget):
18
18
  }
19
19
  )
20
20
  return context
21
-
22
- # def build_attrs(self, base_attrs, extra_attrs=None):
23
- # attrs = super().build_attrs(base_attrs, extra_attrs)
24
- # attrs['data-sqr-captcha-url'] = settings.POWCAPTCHA_API_URL
25
- # attrs['data-sqr-captcha-challenge'] = self.get_challenge()
26
- # attrs['data-sqr-captcha-callback'] = 'myCaptchaCallback'
27
- # return attrs
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023, Jean-Philippe Bidegain
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-powcaptcha
3
- Version: 0.0.1
3
+ Version: 0.0.3
4
4
  Summary: Django PowCaptcha form field/widget app.
5
5
  Home-page: https://github.com/aeyoll/django-powcaptcha
6
6
  Author: Jean-Philippe Bidegain
@@ -24,6 +24,7 @@ Classifier: Programming Language :: Python :: 3.9
24
24
  Classifier: Programming Language :: Python :: 3.10
25
25
  Classifier: Programming Language :: Python :: 3.11
26
26
  Description-Content-Type: text/markdown
27
+ License-File: LICENSE
27
28
  Requires-Dist: django
28
29
 
29
30
  # Django PowCaptcha
@@ -50,20 +51,19 @@ For example:
50
51
 
51
52
  ```python
52
53
  POWCAPTCHA_API_URL = 'https://captcha.yourdomain.com'
53
- POWCAPTCHA_API_KEY = 'MyPOWCAPTCHAPrivateKey456'
54
+ POWCAPTCHA_API_TOKEN = 'MyPOWCAPTCHAPrivateKey456'
54
55
  ```
55
56
 
56
57
  ## Usage
57
58
 
58
- ### Fields
59
+ ### Form
59
60
 
60
61
  The quickest way to add PowCaptcha to a form is to use the included
61
- `PowCaptchaField` field class. For example:
62
+ `PowCaptchaForm` class. For example:
62
63
 
63
64
  ```python
64
- from django import forms
65
- from django_powcaptcha.fields import PowCaptchaField
65
+ from django_powcaptcha.forms import PowCaptchaForm
66
66
 
67
- class FormWithCaptcha(forms.Form):
68
- captcha = PowCaptchaField()
67
+ class FormWithCaptcha(PowCaptchaForm):
68
+ ...
69
69
  ```
@@ -0,0 +1,12 @@
1
+ django_powcaptcha/__init__.py,sha256=KQ6rfGAMJvwKobMVAn2s_EsL5JpPoMkzoNZg4mT_esk,597
2
+ django_powcaptcha/apps.py,sha256=ShxcNSD7Dl2bnnzb6DCnJ4UcsxxVbXlmCGf9aFKUVz4,146
3
+ django_powcaptcha/client.py,sha256=AWYE82MUR-DLK7gtGx5Q-MZ4VTBQoMeRt_fr3SdCt_s,1334
4
+ django_powcaptcha/fields.py,sha256=4Kx9RN-oCsoBVzYdenM73UgZqvqo6pISh17mIAMB7rs,200
5
+ django_powcaptcha/forms.py,sha256=gcTDVPdmyXGvkwQjR63wbczF9-nQKWlwsM_WsFWbe8Y,735
6
+ django_powcaptcha/widgets.py,sha256=SqGcmraMRQdbzVav5Hm3CF-6KdA-wiEZI_B0tXayEOk,609
7
+ django_powcaptcha/templates/django_powcaptcha/widget.html,sha256=9H_c66_0kid6qxHhNw-3e3M454hpF9wzJT65QU4hRNs,947
8
+ django_powcaptcha-0.0.3.dist-info/LICENSE,sha256=EaUvjNHHdVXQTD7w9zcrkLZbRcLEnQ6Q0IekrbN3QUg,1509
9
+ django_powcaptcha-0.0.3.dist-info/METADATA,sha256=YL9N7r4L92DICjpqhXXz--1Rhfhx9hzHuQgc1HnEo2s,1846
10
+ django_powcaptcha-0.0.3.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
11
+ django_powcaptcha-0.0.3.dist-info/top_level.txt,sha256=aEMCJ3_ll_timVB-47n6gL3LGDhHHPkdkv3lnvaJBNQ,18
12
+ django_powcaptcha-0.0.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- django_powcaptcha/__init__.py,sha256=NL4ZCraIf4jIHz9kezy_N7qDJWeuUyy00B666kCRoCY,595
2
- django_powcaptcha/apps.py,sha256=ShxcNSD7Dl2bnnzb6DCnJ4UcsxxVbXlmCGf9aFKUVz4,146
3
- django_powcaptcha/client.py,sha256=aD3LW4jRrhSorNHuj5qYN0HSx_2O2oTdIy2OLW73nFQ,1120
4
- django_powcaptcha/fields.py,sha256=jeFFiT9Eqe-CWUCRsOqjo1QbalrtpliOMPrZXFfkfBo,1323
5
- django_powcaptcha/widgets.py,sha256=WzInlPFlZgQ8yM2tfn6e4zf0jiliSy0fMklXJtsB1Sc,951
6
- django_powcaptcha-0.0.1.dist-info/METADATA,sha256=VMAKqNc9ClY3bwzlRQJKjf0NPxSJvDm_TUrSoher8DE,1878
7
- django_powcaptcha-0.0.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
8
- django_powcaptcha-0.0.1.dist-info/top_level.txt,sha256=aEMCJ3_ll_timVB-47n6gL3LGDhHHPkdkv3lnvaJBNQ,18
9
- django_powcaptcha-0.0.1.dist-info/RECORD,,