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.
- django_powcaptcha-0.0.3/LICENSE +28 -0
- django_powcaptcha-0.0.3/MANIFEST.in +3 -0
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/PKG-INFO +8 -8
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/README.md +6 -7
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/__init__.py +1 -1
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/client.py +12 -6
- django_powcaptcha-0.0.3/django_powcaptcha/fields.py +8 -0
- django_powcaptcha-0.0.3/django_powcaptcha/forms.py +22 -0
- django_powcaptcha-0.0.3/django_powcaptcha/templates/django_powcaptcha/widget.html +29 -0
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/widgets.py +2 -9
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/PKG-INFO +8 -8
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/SOURCES.txt +5 -1
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/setup.py +1 -1
- django-powcaptcha-0.0.1/django_powcaptcha/fields.py +0 -42
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha/apps.py +0 -0
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/dependency_links.txt +0 -0
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/not-zip-safe +0 -0
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/requires.txt +0 -0
- {django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/top_level.txt +0 -0
- {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.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-powcaptcha
|
|
3
|
-
Version: 0.0.
|
|
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
|
-
|
|
54
|
+
POWCAPTCHA_API_TOKEN = 'MyPOWCAPTCHAPrivateKey456'
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
## Usage
|
|
57
58
|
|
|
58
|
-
###
|
|
59
|
+
### Form
|
|
59
60
|
|
|
60
61
|
The quickest way to add PowCaptcha to a form is to use the included
|
|
61
|
-
`
|
|
62
|
+
`PowCaptchaForm` class. For example:
|
|
62
63
|
|
|
63
64
|
```python
|
|
64
|
-
from
|
|
65
|
-
from django_powcaptcha.fields import PowCaptchaField
|
|
65
|
+
from django_powcaptcha.forms import PowCaptchaForm
|
|
66
66
|
|
|
67
|
-
class FormWithCaptcha(
|
|
68
|
-
|
|
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
|
-
|
|
25
|
+
POWCAPTCHA_API_TOKEN = 'MyPOWCAPTCHAPrivateKey456'
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Usage
|
|
29
29
|
|
|
30
|
-
###
|
|
30
|
+
### Form
|
|
31
31
|
|
|
32
32
|
The quickest way to add PowCaptcha to a form is to use the included
|
|
33
|
-
`
|
|
33
|
+
`PowCaptchaForm` class. For example:
|
|
34
34
|
|
|
35
35
|
```python
|
|
36
|
-
from
|
|
37
|
-
from django_powcaptcha.fields import PowCaptchaField
|
|
36
|
+
from django_powcaptcha.forms import PowCaptchaForm
|
|
38
37
|
|
|
39
|
-
class FormWithCaptcha(
|
|
40
|
-
|
|
38
|
+
class FormWithCaptcha(PowCaptchaForm):
|
|
39
|
+
...
|
|
41
40
|
```
|
|
@@ -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'
|
|
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
|
-
|
|
35
|
-
response = powcaptcha_request(path, [])
|
|
36
|
-
challenges = json.loads(response.read().decode('utf-8'))
|
|
35
|
+
challenges = cache.get('powcaptcha_challenges')
|
|
37
36
|
|
|
38
|
-
|
|
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
|
-
|
|
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,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
|
|
7
|
+
class PowCaptchaChallengeWidget(widgets.Widget):
|
|
8
8
|
input_type = 'hidden'
|
|
9
|
-
template_name = '
|
|
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.
|
|
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
|
-
|
|
54
|
+
POWCAPTCHA_API_TOKEN = 'MyPOWCAPTCHAPrivateKey456'
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
## Usage
|
|
57
58
|
|
|
58
|
-
###
|
|
59
|
+
### Form
|
|
59
60
|
|
|
60
61
|
The quickest way to add PowCaptcha to a form is to use the included
|
|
61
|
-
`
|
|
62
|
+
`PowCaptchaForm` class. For example:
|
|
62
63
|
|
|
63
64
|
```python
|
|
64
|
-
from
|
|
65
|
-
from django_powcaptcha.fields import PowCaptchaField
|
|
65
|
+
from django_powcaptcha.forms import PowCaptchaForm
|
|
66
66
|
|
|
67
|
-
class FormWithCaptcha(
|
|
68
|
-
|
|
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
|
|
@@ -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
|
-
)
|
|
File without changes
|
{django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django-powcaptcha-0.0.1 → django_powcaptcha-0.0.3}/django_powcaptcha.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|