Skip to content

Commit a592849

Browse files
committed
first commit
0 parents  commit a592849

31 files changed

+1169
-0
lines changed

.gitignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
5+
# C extensions
6+
*.so
7+
8+
# Distribution / packaging
9+
.Python
10+
env/
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
*.egg-info/
23+
.installed.cfg
24+
*.egg
25+
26+
# PyInstaller
27+
# Usually these files are written by a python script from a template
28+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
29+
*.manifest
30+
*.spec
31+
32+
# Installer logs
33+
pip-log.txt
34+
pip-delete-this-directory.txt
35+
36+
# Unit test / coverage reports
37+
htmlcov/
38+
.tox/
39+
.coverage
40+
.coverage.*
41+
.cache
42+
nosetests.xml
43+
coverage.xml
44+
*,cover
45+
46+
# Translations
47+
*.pot
48+
49+
# Django stuff:
50+
*.log
51+
52+
# Sphinx documentation
53+
docs/_build/
54+
55+
# PyBuilder
56+
target/
57+
/venv/
58+
/django-test/
59+
*.iml
60+
.idea

.travis.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
language: python
2+
python:
3+
- '2.7'
4+
- '3.4'
5+
- '3.5'
6+
- '3.6'
7+
install:
8+
- pip install tox-travis
9+
- python setup.py -q install
10+
script:
11+
- tox
12+
deploy:
13+
provider: pypi
14+
skip_existing: true
15+
user: kbyte
16+
distributions: sdist bdist_wheel
17+
password:
18+
secure: otCLiaoPb3cxnTNDM2pmz4IrnUukeTOVOlHjZArR91dhluP+86fBPpPfRJmC6vtUCX+uIhRzEAFos8QSiCcuSaOYTARz/9eWBFN/NElvrMUjXdWxN/t5IASAsLGIFFO3z0rSjUUkS3CUNE3pD40cRr+ainpZc+lgw3cS6STAWaj3h6znwFvxijOsEnYv7NwqCEqrQb0sfRUI+fRn++2dDQeS2NY1VFiGL2Q43isaEqGBJsHWwAWrTsfjmj1OiwOdwlBJ+dbZFMzur3bYr6O79oVG98WNnO94f+YYGXa3cQ3X5+leWq/JbVcyk++r6FlkH1lb9zRqzmVn706U9R2Fxpykl5lvD500MwrSibvEEVo7jmZq3WK353YQop9LU7uacPZwqu85QLrrGzV789WNzrq9NJgAxALue9qzWbn4Hk2EkkE8qi0njFpTdkSmSW/1sPMou3HN3n1GE8k9DoUj0RhU1eROC3Th/KoW9y1R60EsLzG6o3yQ82Z+V2giKM0gZ5hiS6JX6jcvtVuzzr2tYWDjSE6o72eRipCYfgiku7TAmMKVfHvOkHv0BXe8HRljEZn6IdwsRp0vI+fXUvNtJCvPRXHq+5+SGuvQtiq12moKky9TJ8EXvr+QRt0V56cdMYWadaHhfDDSw8CGlZHd0FdVfuSUM9bR5Xgk30N8jI8=
19+
on:
20+
tags: true
21+
python: '3.6'

LICENSE

Lines changed: 505 additions & 0 deletions
Large diffs are not rendered by default.

MANIFEST.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
include README.txt
2+
include README.md
3+
include LICENSE
4+
recursive-include snowpenguin/django/recaptcha3/templates *.html
5+
recursive-include snowpenguin/django/recaptcha3/locale *.mo

README.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Django reCaptcha v3 [![Build Status](https://travis-ci.org/kbytesys/django-recaptcha3.svg?branch=master)](https://travis-ci.org/kbytesys/django-recaptcha2)
2+
----
3+
4+
This integration app implements a recaptcha field for <a href="https://developers.google.com/recaptcha/intro">Google reCaptcha v3</a>.
5+
6+
**Warning:** this package is not suitable for production yet (also Google reCaptcha v3 is only in beta at the moment)
7+
8+
**Warning2:** this package is **not** compatible with django-recaptcha2
9+
10+
----
11+
12+
## How to install
13+
14+
Install the required package from pip (or take the source and install it by yourself):
15+
16+
```bash
17+
pip install django-recaptcha3
18+
```
19+
20+
Then add django-recaptcha3 to your installed apps:
21+
22+
```python
23+
INSTALLED_APPS = (
24+
...
25+
'snowpenguin.django.recaptcha3',
26+
...
27+
)
28+
```
29+
30+
And add your reCaptcha private and public key to your django settings.py and the default action name:
31+
32+
```python
33+
RECAPTCHA_PRIVATE_KEY = 'your private key'
34+
RECAPTCHA_PUBLIC_KEY = 'your public key'
35+
RECAPTCHA_DEFAULT_ACTION = 'generic'
36+
37+
```
38+
39+
If you have to create the apikey for the domains managed by your django project, you can visit this <a href="https://www.google.com/recaptcha/admin">website</a>.
40+
41+
## Usage
42+
### Form and Widget
43+
You can simply create a reCaptcha enabled form with the field provided by this app:
44+
45+
```python
46+
from snowpenguin.django.recaptcha2.fields import ReCaptchaField
47+
48+
class ExampleForm(forms.Form):
49+
[...]
50+
captcha = ReCaptchaField()
51+
[...]
52+
```
53+
54+
You can set the private key on the "private_key" argument of the field contructor if you want to override the one inside
55+
your configuration.
56+
57+
### Templating
58+
You can use some template tags to simplify the reCaptcha adoption:
59+
60+
* recaptcha_init: add the script tag for reCaptcha api. You have to put this tag somewhere in your "head" element
61+
* recaptcha_ready: call the execute function when the api script is loaded
62+
* recaptcha_execute: start the reCaptcha check and set the token from the api in your django forms
63+
* recaptcha_key: if you want to use reCaptcha manually in your template, you will need the sitekey (a.k.a. public api key).
64+
This tag returns a string with the configured public key.
65+
66+
You can use the form as usual.
67+
68+
### Samples
69+
#### Simple
70+
71+
Just create a form with the reCaptcha field and follow this template example:
72+
73+
```django
74+
{% load recaptcha3 %}
75+
<html>
76+
<head>
77+
{% recaptcha_init %}
78+
{% recaptcha_ready action_name='homepage' %}
79+
</head>
80+
<body>
81+
<form action="?" method="POST">
82+
{% csrf_token %}
83+
{{ form }}
84+
<input type="submit" value="Submit">
85+
</form>
86+
</body>
87+
</html>
88+
```
89+
90+
#### Custom callback
91+
92+
The callback can be used to allow to use the token received from the api in ajax calls or whatever
93+
94+
```django
95+
{% load recaptcha3 %}
96+
<html>
97+
<head>
98+
<script>
99+
function alertToken(token) {
100+
alert(token);
101+
}
102+
</script>
103+
{% recaptcha_init %}
104+
{% recaptcha_ready action_name='homepage' custom_callback='alertToken' %}
105+
</head>
106+
<body>
107+
<form action="?" method="POST">
108+
{% csrf_token %}
109+
{{ form }}
110+
<input type="submit" value="Submit">
111+
</form>
112+
</body>
113+
</html>
114+
```
115+
116+
#### Multiple render example
117+
118+
You can render multiple reCaptcha without any extra effort:
119+
120+
```django
121+
{% load recaptcha3 %}
122+
<html>
123+
<head>
124+
{% recaptcha_init %}
125+
{% recaptcha_ready action_name='homepage' %}
126+
</head>
127+
<body>
128+
<form action="?" method="POST">
129+
{% csrf_token %}
130+
{{ form1 }}
131+
<input type="submit" value="Submit">
132+
</form>
133+
<form action="?" method="POST">
134+
{% csrf_token %}
135+
{{ form2 }}
136+
<input type="submit" value="Submit">
137+
</form>
138+
</body>
139+
</html>
140+
```
141+
142+
#### Bare metal!
143+
144+
You can use the plain javascript, just remember to set the correct value for the hidden field in the form
145+
146+
```django
147+
<html>
148+
<head>
149+
<script src="https://www.google.com/recaptcha/api.js?render=reCAPTCHA_site_key"></script>
150+
<script>
151+
grecaptcha.ready(function() {
152+
grecaptcha.execute('reCAPTCHA_site_key', {action: 'homepage'}).then(function(token) {
153+
document.querySelectorAll('input.django-recaptcha-hidden-field').forEach(function (value) {
154+
value.value = token;
155+
});
156+
return token;
157+
});
158+
});
159+
</script>
160+
</head>
161+
<body>
162+
<form action="?" method="POST">
163+
{% csrf_token %}
164+
{{ form }}
165+
<input type="submit" value="Submit">
166+
</form>
167+
</body>
168+
</html>
169+
```
170+
171+
## Testing
172+
### Test unit support
173+
You can't simulate api calls in your test, but you can disable the recaptcha field and let your test works.
174+
175+
Just set the RECAPTCHA_DISABLE env variable in your test:
176+
177+
```python
178+
os.environ['RECAPTCHA_DISABLE'] = 'True'
179+
```
180+
181+
Warning: you can use any word in place of "True", the clean function will check only if the variable exists.
182+
183+
### Test unit with recaptcha2 disabled
184+
```python
185+
import os
186+
import unittest
187+
188+
from yourpackage.forms import MyForm
189+
190+
class TestCase(unittest.TestCase):
191+
def setUp(self):
192+
os.environ['RECAPTCHA_DISABLE'] = 'True'
193+
194+
def test_myform(self):
195+
form = MyForm({
196+
'field1': 'field1_value'
197+
})
198+
self.assertTrue(form.is_valid())
199+
200+
def tearDown(self):
201+
del os.environ['RECAPTCHA_DISABLE']
202+
```

README.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This integration app implements a reCAPTCHA support for Google reCAPTCHA v3.

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Django>=1.8
2+
requests

samples/bare_metal_recaptcha.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<html>
2+
<head>
3+
<script src="https://www.google.com/recaptcha/api.js?render=reCAPTCHA_site_key"></script>
4+
<script>
5+
grecaptcha.ready(function() {
6+
grecaptcha.execute('reCAPTCHA_site_key', {action: 'homepage'}).then(function(token) {
7+
document.querySelectorAll('input.django-recaptcha-hidden-field').forEach(function (value) {
8+
value.value = token;
9+
});
10+
return token;
11+
});
12+
});
13+
</script>
14+
</head>
15+
<body>
16+
<form action="?" method="POST">
17+
{% csrf_token %}
18+
{{ form }}
19+
<input type="submit" value="Submit">
20+
</form>
21+
</body>
22+
</html>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{% load recaptcha3 %}
2+
<html>
3+
<head>
4+
<script>
5+
function alertToken(token) {
6+
alert(token);
7+
}
8+
</script>
9+
{% recaptcha_init %}
10+
{% recaptcha_ready action_name='homepage' custom_callback='alertToken' %}
11+
</head>
12+
<body>
13+
<form action="?" method="POST">
14+
{% csrf_token %}
15+
{{ form }}
16+
<input type="submit" value="Submit">
17+
</form>
18+
</body>
19+
</html>

samples/multiple_recaptcha.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{% load recaptcha3 %}
2+
<html>
3+
<head>
4+
{% recaptcha_init %}
5+
{% recaptcha_ready action_name='homepage' %}
6+
</head>
7+
<body>
8+
<form action="?" method="POST">
9+
{% csrf_token %}
10+
{{ form1 }}
11+
<input type="submit" value="Submit">
12+
</form>
13+
<form action="?" method="POST">
14+
{% csrf_token %}
15+
{{ form2 }}
16+
<input type="submit" value="Submit">
17+
</form>
18+
</body>
19+
</html>

0 commit comments

Comments
 (0)