django-powcaptcha 0.0.1__tar.gz → 0.0.3__tar.gz

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.
Files changed (20) hide show
  1. django_powcaptcha-0.0.3/LICENSE +28 -0
  2. django_powcaptcha-0.0.3/MANIFEST.in +3 -0
  3. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/PKG-INFO +8 -8
  4. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/README.md +6 -7
  5. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/__init__.py +1 -1
  6. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/client.py +12 -6
  7. django_powcaptcha-0.0.3/django_powcaptcha/fields.py +8 -0
  8. django_powcaptcha-0.0.3/django_powcaptcha/forms.py +22 -0
  9. django_powcaptcha-0.0.3/django_powcaptcha/templates/django_powcaptcha/widget.html +29 -0
  10. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/widgets.py +2 -9
  11. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/PKG-INFO +8 -8
  12. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/SOURCES.txt +5 -1
  13. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/setup.py +1 -1
  14. django-powcaptcha-0.0.1/django_powcaptcha/fields.py +0 -42
  15. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/apps.py +0 -0
  16. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/dependency_links.txt +0 -0
  17. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/not-zip-safe +0 -0
  18. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/requires.txt +0 -0
  19. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/top_level.txt +0 -0
  20. {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/setup.cfg +0 -0
@@ -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.
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include README.md
3
+ recursive-include django_powcaptcha/templates *
@@ -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
  ```
@@ -22,20 +22,19 @@ For example:
22
22
 
23
23
  ```python
24
24
  POWCAPTCHA_API_URL = 'https://captcha.yourdomain.com'
25
- POWCAPTCHA_API_KEY = 'MyPOWCAPTCHAPrivateKey456'
25
+ POWCAPTCHA_API_TOKEN = 'MyPOWCAPTCHAPrivateKey456'
26
26
  ```
27
27
 
28
28
  ## Usage
29
29
 
30
- ### Fields
30
+ ### Form
31
31
 
32
32
  The quickest way to add PowCaptcha to a form is to use the included
33
- `PowCaptchaField` field class. For example:
33
+ `PowCaptchaForm` class. For example:
34
34
 
35
35
  ```python
36
- from django import forms
37
- from django_powcaptcha.fields import PowCaptchaField
36
+ from django_powcaptcha.forms import PowCaptchaForm
38
37
 
39
- class FormWithCaptcha(forms.Form):
40
- captcha = PowCaptchaField()
38
+ class FormWithCaptcha(PowCaptchaForm):
39
+ ...
41
40
  ```
@@ -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):
@@ -0,0 +1,8 @@
1
+ from django import forms
2
+
3
+ from django_powcaptcha.widgets import PowCaptchaChallengeWidget
4
+
5
+
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
@@ -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
  ```
@@ -1,3 +1,5 @@
1
+ LICENSE
2
+ MANIFEST.in
1
3
  README.md
2
4
  setup.cfg
3
5
  setup.py
@@ -5,10 +7,12 @@ django_powcaptcha/__init__.py
5
7
  django_powcaptcha/apps.py
6
8
  django_powcaptcha/client.py
7
9
  django_powcaptcha/fields.py
10
+ django_powcaptcha/forms.py
8
11
  django_powcaptcha/widgets.py
9
12
  django_powcaptcha.egg-info/PKG-INFO
10
13
  django_powcaptcha.egg-info/SOURCES.txt
11
14
  django_powcaptcha.egg-info/dependency_links.txt
12
15
  django_powcaptcha.egg-info/not-zip-safe
13
16
  django_powcaptcha.egg-info/requires.txt
14
- django_powcaptcha.egg-info/top_level.txt
17
+ django_powcaptcha.egg-info/top_level.txt
18
+ django_powcaptcha/templates/django_powcaptcha/widget.html
@@ -4,7 +4,7 @@ long_desc = open("README.md").read()
4
4
 
5
5
  setup(
6
6
  name="django-powcaptcha",
7
- version="0.0.1",
7
+ version="0.0.3",
8
8
  description="Django PowCaptcha form field/widget app.",
9
9
  long_description=long_desc,
10
10
  long_description_content_type="text/markdown",
@@ -1,42 +0,0 @@
1
- import logging
2
-
3
- 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
-
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')
30
-
31
- def validate(self, value):
32
- super().validate(value)
33
-
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
- )