prune_captcha 1.11.0__tar.gz → 1.12.1__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.
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/PKG-INFO +11 -38
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/README.md +10 -37
- prune_captcha-1.11.0/captcha_prune/views.py → prune_captcha-1.12.1/captcha_prune/utils.py +2 -21
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/prune_captcha.egg-info/PKG-INFO +11 -38
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/prune_captcha.egg-info/SOURCES.txt +1 -3
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/pyproject.toml +1 -1
- prune_captcha-1.11.0/captcha_prune/urls.py +0 -10
- prune_captcha-1.11.0/commons/decorators.py +0 -41
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/__init__.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/apps.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/asgi.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/migrations/0001_initial.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/migrations/0002_remove_captcha_created_at_remove_captcha_pos_x_and_more.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/migrations/0003_captcha_created_at_captcha_updated_at.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/migrations/__init__.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/models.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/payloads.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/settings.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/captcha_prune/wsgi.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/commons/base_model.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/prune_captcha.egg-info/dependency_links.txt +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/prune_captcha.egg-info/requires.txt +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/prune_captcha.egg-info/top_level.txt +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/setup.cfg +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/tests/__init__.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/tests/captcha_prune/__init__.py +0 -0
- {prune_captcha-1.11.0 → prune_captcha-1.12.1}/tests/captcha_prune/test_views.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: prune_captcha
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.12.1
|
4
4
|
Summary: A tool to protect formulaire from spam.
|
5
5
|
Author-email: Arnout <bastien@prune.sh>
|
6
6
|
Project-URL: Made_by, https://prune.sh/
|
@@ -61,21 +61,21 @@ Don't hesitate to regularly run `poetry update`, as the captcha evolves with tim
|
|
61
61
|
In `settings.py`, set the path to the images used for the puzzle:
|
62
62
|
|
63
63
|
```python
|
64
|
-
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
|
64
|
+
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/puzzles/"
|
65
65
|
```
|
66
66
|
|
67
67
|
### Utilisation
|
68
68
|
|
69
69
|
- GET request (form display)
|
70
70
|
|
71
|
-
- Use
|
71
|
+
- Use create_and_get_captcha to generate the captcha data:
|
72
72
|
|
73
73
|
```python
|
74
|
-
from captcha_prune.
|
74
|
+
from captcha_prune.utils import create_and_get_captcha
|
75
75
|
```
|
76
76
|
|
77
77
|
```python
|
78
|
-
puzzle =
|
78
|
+
puzzle = create_and_get_captcha(request)
|
79
79
|
```
|
80
80
|
|
81
81
|
- Passes the data into the context under the puzzle variable:
|
@@ -96,53 +96,26 @@ PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
|
|
96
96
|
|
97
97
|
- POST request (form submission)
|
98
98
|
|
99
|
-
- Use
|
99
|
+
- Use verify_captcha to validate the captcha:
|
100
100
|
|
101
101
|
```python
|
102
|
-
from captcha_prune.
|
102
|
+
from captcha_prune.utils import verify_captcha
|
103
103
|
```
|
104
104
|
|
105
105
|
```python
|
106
|
-
response =
|
106
|
+
response = verify_captcha(request)
|
107
107
|
```
|
108
108
|
|
109
109
|
- True if the captcha is correct, else False.
|
110
110
|
|
111
|
-
- Redirects in case of
|
112
|
-
|
113
|
-
```python
|
114
|
-
if response is False:
|
115
|
-
return redirect("website:contact-page")
|
116
|
-
```
|
117
|
-
|
118
|
-
### Example
|
119
|
-
|
120
|
-
```python
|
121
|
-
def contact_view(request):
|
122
|
-
if request.method == "POST":
|
123
|
-
form = ContactForm(request.POST)
|
124
|
-
if form.is_valid():
|
125
|
-
response = verify_captcha_view(request)
|
126
|
-
if response is False:
|
127
|
-
return redirect("website:contact-page")
|
128
|
-
messages.success(request, "Formulaire soumis avec succès.")
|
129
|
-
return redirect("/")
|
130
|
-
else:
|
131
|
-
puzzle = create_captcha_view(request)
|
132
|
-
else:
|
133
|
-
form = ContactForm()
|
134
|
-
puzzle = create_captcha_view(request)
|
135
|
-
return render(
|
136
|
-
request,
|
137
|
-
"website/pages/contact/page.html",
|
138
|
-
{"form": form, "puzzle": puzzle},
|
139
|
-
)
|
140
|
-
```
|
111
|
+
- Redirects in case of incorrect captcha.
|
141
112
|
|
142
113
|
# Available Versions
|
143
114
|
|
144
115
|
| Version | Date | Notes |
|
145
116
|
| ------- | ---------- | ---------------------------------- |
|
117
|
+
| 1.12.1 | 2025-05-21 | doc fixed |
|
118
|
+
| 1.12.0 | 2025-05-21 | removed views, added utils, ... |
|
146
119
|
| 1.11.0 | 2025-05-21 | removed utils |
|
147
120
|
| 1.10.0 | 2025-05-20 | fix documentation, removed ... |
|
148
121
|
| 1.9.0 | 2025-05-20 | puzzle images path fixed |
|
@@ -43,21 +43,21 @@ Don't hesitate to regularly run `poetry update`, as the captcha evolves with tim
|
|
43
43
|
In `settings.py`, set the path to the images used for the puzzle:
|
44
44
|
|
45
45
|
```python
|
46
|
-
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
|
46
|
+
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/puzzles/"
|
47
47
|
```
|
48
48
|
|
49
49
|
### Utilisation
|
50
50
|
|
51
51
|
- GET request (form display)
|
52
52
|
|
53
|
-
- Use
|
53
|
+
- Use create_and_get_captcha to generate the captcha data:
|
54
54
|
|
55
55
|
```python
|
56
|
-
from captcha_prune.
|
56
|
+
from captcha_prune.utils import create_and_get_captcha
|
57
57
|
```
|
58
58
|
|
59
59
|
```python
|
60
|
-
puzzle =
|
60
|
+
puzzle = create_and_get_captcha(request)
|
61
61
|
```
|
62
62
|
|
63
63
|
- Passes the data into the context under the puzzle variable:
|
@@ -78,53 +78,26 @@ PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
|
|
78
78
|
|
79
79
|
- POST request (form submission)
|
80
80
|
|
81
|
-
- Use
|
81
|
+
- Use verify_captcha to validate the captcha:
|
82
82
|
|
83
83
|
```python
|
84
|
-
from captcha_prune.
|
84
|
+
from captcha_prune.utils import verify_captcha
|
85
85
|
```
|
86
86
|
|
87
87
|
```python
|
88
|
-
response =
|
88
|
+
response = verify_captcha(request)
|
89
89
|
```
|
90
90
|
|
91
91
|
- True if the captcha is correct, else False.
|
92
92
|
|
93
|
-
- Redirects in case of
|
94
|
-
|
95
|
-
```python
|
96
|
-
if response is False:
|
97
|
-
return redirect("website:contact-page")
|
98
|
-
```
|
99
|
-
|
100
|
-
### Example
|
101
|
-
|
102
|
-
```python
|
103
|
-
def contact_view(request):
|
104
|
-
if request.method == "POST":
|
105
|
-
form = ContactForm(request.POST)
|
106
|
-
if form.is_valid():
|
107
|
-
response = verify_captcha_view(request)
|
108
|
-
if response is False:
|
109
|
-
return redirect("website:contact-page")
|
110
|
-
messages.success(request, "Formulaire soumis avec succès.")
|
111
|
-
return redirect("/")
|
112
|
-
else:
|
113
|
-
puzzle = create_captcha_view(request)
|
114
|
-
else:
|
115
|
-
form = ContactForm()
|
116
|
-
puzzle = create_captcha_view(request)
|
117
|
-
return render(
|
118
|
-
request,
|
119
|
-
"website/pages/contact/page.html",
|
120
|
-
{"form": form, "puzzle": puzzle},
|
121
|
-
)
|
122
|
-
```
|
93
|
+
- Redirects in case of incorrect captcha.
|
123
94
|
|
124
95
|
# Available Versions
|
125
96
|
|
126
97
|
| Version | Date | Notes |
|
127
98
|
| ------- | ---------- | ---------------------------------- |
|
99
|
+
| 1.12.1 | 2025-05-21 | doc fixed |
|
100
|
+
| 1.12.0 | 2025-05-21 | removed views, added utils, ... |
|
128
101
|
| 1.11.0 | 2025-05-21 | removed utils |
|
129
102
|
| 1.10.0 | 2025-05-20 | fix documentation, removed ... |
|
130
103
|
| 1.9.0 | 2025-05-20 | puzzle images path fixed |
|
@@ -2,22 +2,13 @@ import os
|
|
2
2
|
import random
|
3
3
|
|
4
4
|
from django.conf import settings
|
5
|
-
from django.contrib import messages
|
6
|
-
from django.http import HttpRequest
|
7
5
|
from django.shortcuts import get_object_or_404
|
8
|
-
from django.views.decorators.csrf import csrf_exempt
|
9
|
-
from django.views.decorators.http import require_GET, require_POST
|
10
6
|
|
11
7
|
from captcha_prune.models import Captcha
|
12
|
-
from captcha_prune.payloads import PuzzleAnswerPayload
|
13
|
-
from commons.decorators import use_payload
|
14
8
|
|
15
9
|
|
16
|
-
|
17
|
-
@csrf_exempt
|
18
|
-
def create_captcha_view(request: HttpRequest) -> dict:
|
10
|
+
def create_and_get_captcha() -> dict:
|
19
11
|
captcha = Captcha.objects.create()
|
20
|
-
request.session["puzzle_uuid"] = captcha.uuid
|
21
12
|
|
22
13
|
_, _, puzzle_images_path = settings.PUZZLE_IMAGE_STATIC_PATH.rpartition("static/")
|
23
14
|
puzzle_images = [
|
@@ -41,16 +32,7 @@ def create_captcha_view(request: HttpRequest) -> dict:
|
|
41
32
|
}
|
42
33
|
|
43
34
|
|
44
|
-
|
45
|
-
@use_payload(PuzzleAnswerPayload)
|
46
|
-
def verify_captcha_view(request: HttpRequest, payload: PuzzleAnswerPayload) -> bool:
|
47
|
-
pos_x_answer = payload.pos_x_answer
|
48
|
-
pos_y_answer = payload.pos_y_answer
|
49
|
-
|
50
|
-
puzzle_uuid = request.session.get("puzzle_uuid")
|
51
|
-
if not puzzle_uuid:
|
52
|
-
messages.error(request, "La session a expiré.")
|
53
|
-
return False
|
35
|
+
def verify_captcha(puzzle_uuid: str, pos_x_answer: int, pos_y_answer: int) -> bool:
|
54
36
|
captcha = get_object_or_404(Captcha, uuid=puzzle_uuid)
|
55
37
|
|
56
38
|
if (
|
@@ -59,5 +41,4 @@ def verify_captcha_view(request: HttpRequest, payload: PuzzleAnswerPayload) -> b
|
|
59
41
|
):
|
60
42
|
return True
|
61
43
|
else:
|
62
|
-
messages.error(request, "Captcha incorrect. Veuillez réessayer.")
|
63
44
|
return False
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: prune_captcha
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.12.1
|
4
4
|
Summary: A tool to protect formulaire from spam.
|
5
5
|
Author-email: Arnout <bastien@prune.sh>
|
6
6
|
Project-URL: Made_by, https://prune.sh/
|
@@ -61,21 +61,21 @@ Don't hesitate to regularly run `poetry update`, as the captcha evolves with tim
|
|
61
61
|
In `settings.py`, set the path to the images used for the puzzle:
|
62
62
|
|
63
63
|
```python
|
64
|
-
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
|
64
|
+
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/puzzles/"
|
65
65
|
```
|
66
66
|
|
67
67
|
### Utilisation
|
68
68
|
|
69
69
|
- GET request (form display)
|
70
70
|
|
71
|
-
- Use
|
71
|
+
- Use create_and_get_captcha to generate the captcha data:
|
72
72
|
|
73
73
|
```python
|
74
|
-
from captcha_prune.
|
74
|
+
from captcha_prune.utils import create_and_get_captcha
|
75
75
|
```
|
76
76
|
|
77
77
|
```python
|
78
|
-
puzzle =
|
78
|
+
puzzle = create_and_get_captcha(request)
|
79
79
|
```
|
80
80
|
|
81
81
|
- Passes the data into the context under the puzzle variable:
|
@@ -96,53 +96,26 @@ PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
|
|
96
96
|
|
97
97
|
- POST request (form submission)
|
98
98
|
|
99
|
-
- Use
|
99
|
+
- Use verify_captcha to validate the captcha:
|
100
100
|
|
101
101
|
```python
|
102
|
-
from captcha_prune.
|
102
|
+
from captcha_prune.utils import verify_captcha
|
103
103
|
```
|
104
104
|
|
105
105
|
```python
|
106
|
-
response =
|
106
|
+
response = verify_captcha(request)
|
107
107
|
```
|
108
108
|
|
109
109
|
- True if the captcha is correct, else False.
|
110
110
|
|
111
|
-
- Redirects in case of
|
112
|
-
|
113
|
-
```python
|
114
|
-
if response is False:
|
115
|
-
return redirect("website:contact-page")
|
116
|
-
```
|
117
|
-
|
118
|
-
### Example
|
119
|
-
|
120
|
-
```python
|
121
|
-
def contact_view(request):
|
122
|
-
if request.method == "POST":
|
123
|
-
form = ContactForm(request.POST)
|
124
|
-
if form.is_valid():
|
125
|
-
response = verify_captcha_view(request)
|
126
|
-
if response is False:
|
127
|
-
return redirect("website:contact-page")
|
128
|
-
messages.success(request, "Formulaire soumis avec succès.")
|
129
|
-
return redirect("/")
|
130
|
-
else:
|
131
|
-
puzzle = create_captcha_view(request)
|
132
|
-
else:
|
133
|
-
form = ContactForm()
|
134
|
-
puzzle = create_captcha_view(request)
|
135
|
-
return render(
|
136
|
-
request,
|
137
|
-
"website/pages/contact/page.html",
|
138
|
-
{"form": form, "puzzle": puzzle},
|
139
|
-
)
|
140
|
-
```
|
111
|
+
- Redirects in case of incorrect captcha.
|
141
112
|
|
142
113
|
# Available Versions
|
143
114
|
|
144
115
|
| Version | Date | Notes |
|
145
116
|
| ------- | ---------- | ---------------------------------- |
|
117
|
+
| 1.12.1 | 2025-05-21 | doc fixed |
|
118
|
+
| 1.12.0 | 2025-05-21 | removed views, added utils, ... |
|
146
119
|
| 1.11.0 | 2025-05-21 | removed utils |
|
147
120
|
| 1.10.0 | 2025-05-20 | fix documentation, removed ... |
|
148
121
|
| 1.9.0 | 2025-05-20 | puzzle images path fixed |
|
@@ -6,15 +6,13 @@ captcha_prune/asgi.py
|
|
6
6
|
captcha_prune/models.py
|
7
7
|
captcha_prune/payloads.py
|
8
8
|
captcha_prune/settings.py
|
9
|
-
captcha_prune/
|
10
|
-
captcha_prune/views.py
|
9
|
+
captcha_prune/utils.py
|
11
10
|
captcha_prune/wsgi.py
|
12
11
|
captcha_prune/migrations/0001_initial.py
|
13
12
|
captcha_prune/migrations/0002_remove_captcha_created_at_remove_captcha_pos_x_and_more.py
|
14
13
|
captcha_prune/migrations/0003_captcha_created_at_captcha_updated_at.py
|
15
14
|
captcha_prune/migrations/__init__.py
|
16
15
|
commons/base_model.py
|
17
|
-
commons/decorators.py
|
18
16
|
prune_captcha.egg-info/PKG-INFO
|
19
17
|
prune_captcha.egg-info/SOURCES.txt
|
20
18
|
prune_captcha.egg-info/dependency_links.txt
|
@@ -20,7 +20,7 @@ classifiers = [
|
|
20
20
|
keywords = ["captcha", "django", "code-quality"]
|
21
21
|
urls = {Made_by = "https://prune.sh/"}
|
22
22
|
name = "prune_captcha"
|
23
|
-
version = "1.
|
23
|
+
version = "1.12.1"
|
24
24
|
description = "A tool to protect formulaire from spam."
|
25
25
|
readme = "README.md"
|
26
26
|
dependencies = [
|
@@ -1,10 +0,0 @@
|
|
1
|
-
from django.urls import path
|
2
|
-
|
3
|
-
from captcha_prune.views import create_captcha_view, verify_captcha_view
|
4
|
-
|
5
|
-
app_name = "captcha"
|
6
|
-
|
7
|
-
urlpatterns = [
|
8
|
-
path("create/", create_captcha_view, name="create-captcha"),
|
9
|
-
path("verify/", verify_captcha_view, name="verify-captcha"),
|
10
|
-
]
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import functools
|
2
|
-
from typing import get_origin
|
3
|
-
|
4
|
-
from django.http import HttpResponse
|
5
|
-
from pydantic import ValidationError
|
6
|
-
|
7
|
-
|
8
|
-
def use_payload(payload_class):
|
9
|
-
def decorator(func):
|
10
|
-
@functools.wraps(func)
|
11
|
-
def wrapper(request, *args, **kwargs):
|
12
|
-
data = {}
|
13
|
-
|
14
|
-
if request.method == "POST":
|
15
|
-
body = request.POST
|
16
|
-
elif request.method == "GET":
|
17
|
-
body = request.GET
|
18
|
-
else:
|
19
|
-
raise NotImplementedError
|
20
|
-
|
21
|
-
for field_name, field in payload_class.model_fields.items():
|
22
|
-
url_name = field.alias if field.alias else field_name
|
23
|
-
is_list_field = get_origin(field.annotation) is list
|
24
|
-
url_value = (
|
25
|
-
body.getlist(url_name) if is_list_field else body.get(url_name)
|
26
|
-
)
|
27
|
-
if url_value is not None:
|
28
|
-
data[url_name] = url_value
|
29
|
-
|
30
|
-
try:
|
31
|
-
payload = payload_class.model_validate(data)
|
32
|
-
except ValidationError as e:
|
33
|
-
return HttpResponse(
|
34
|
-
e.json(), headers={"content_type": "application/json"}, status=400
|
35
|
-
)
|
36
|
-
|
37
|
-
return func(request, *args, payload=payload, **kwargs)
|
38
|
-
|
39
|
-
return wrapper
|
40
|
-
|
41
|
-
return decorator
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|