prune_captcha 1.9.0__tar.gz → 1.11.0__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 (30) hide show
  1. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/PKG-INFO +40 -32
  2. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/README.md +39 -31
  3. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/urls.py +2 -2
  4. prune_captcha-1.11.0/captcha_prune/views.py +63 -0
  5. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/prune_captcha.egg-info/PKG-INFO +40 -32
  6. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/prune_captcha.egg-info/SOURCES.txt +0 -2
  7. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/pyproject.toml +1 -1
  8. prune_captcha-1.9.0/captcha_prune/context_processors.py +0 -12
  9. prune_captcha-1.9.0/captcha_prune/utils.py +0 -68
  10. prune_captcha-1.9.0/captcha_prune/views.py +0 -45
  11. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/__init__.py +0 -0
  12. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/apps.py +0 -0
  13. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/asgi.py +0 -0
  14. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/migrations/0001_initial.py +0 -0
  15. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/migrations/0002_remove_captcha_created_at_remove_captcha_pos_x_and_more.py +0 -0
  16. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/migrations/0003_captcha_created_at_captcha_updated_at.py +0 -0
  17. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/migrations/__init__.py +0 -0
  18. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/models.py +0 -0
  19. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/payloads.py +0 -0
  20. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/settings.py +0 -0
  21. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/captcha_prune/wsgi.py +0 -0
  22. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/commons/base_model.py +0 -0
  23. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/commons/decorators.py +0 -0
  24. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/prune_captcha.egg-info/dependency_links.txt +0 -0
  25. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/prune_captcha.egg-info/requires.txt +0 -0
  26. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/prune_captcha.egg-info/top_level.txt +0 -0
  27. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/setup.cfg +0 -0
  28. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/tests/__init__.py +0 -0
  29. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/tests/captcha_prune/__init__.py +0 -0
  30. {prune_captcha-1.9.0 → prune_captcha-1.11.0}/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.9.0
3
+ Version: 1.11.0
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,81 +61,90 @@ 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/images/"
64
+ PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
65
65
  ```
66
66
 
67
67
  ### Utilisation
68
68
 
69
69
  - GET request (form display)
70
70
 
71
- - Use create_and_get_puzzle to generate the captcha data.
71
+ - Use create_captcha_view to generate the captcha data:
72
72
 
73
- - Passes the data into the context under the puzzle variable.
73
+ ```python
74
+ from captcha_prune.views import create_captcha_view
75
+ ```
74
76
 
75
- - Include the component in your template:
77
+ ```python
78
+ puzzle = create_captcha_view(request)
79
+ ```
80
+
81
+ - Passes the data into the context under the puzzle variable:
76
82
 
77
83
  ```python
78
- from captcha_prune.utils import create_and_get_puzzle
84
+ return render(
85
+ request,
86
+ "website/pages/contact/page.html",
87
+ {"form": form, "puzzle": puzzle},
88
+ )
79
89
  ```
80
90
 
91
+ - Include the component in your template:
92
+
81
93
  ```
82
94
  {% include "captcha_prune/captcha.html" %}
83
95
  ```
84
96
 
85
97
  - POST request (form submission)
86
98
 
87
- - Use verify_captcha to validate the captcha.
99
+ - Use verify_captcha_view to validate the captcha:
88
100
 
89
101
  ```python
90
- from captcha_prune.utils import verify_captcha
102
+ from captcha_prune.views import verify_captcha_view
91
103
  ```
92
104
 
93
105
  ```python
94
- verify_captcha(request, redirect("/"), redirect("website:contact-page"), form)
106
+ response = verify_captcha_view(request)
95
107
  ```
96
108
 
97
- - No feedback if the captcha is correct.
109
+ - True if the captcha is correct, else False.
98
110
 
99
- - Redirects in case of expired session or incorrect captcha.
111
+ - Redirects in case of expired session or incorrect captcha:
112
+
113
+ ```python
114
+ if response is False:
115
+ return redirect("website:contact-page")
116
+ ```
100
117
 
101
118
  ### Example
102
119
 
103
120
  ```python
104
- from django.shortcuts import render, redirect
105
-
106
- from django.contrib import messages
107
- from captcha_prune.utils import create_and_get_puzzle, verify_captcha
108
- from .forms import ContactForm
109
-
110
121
  def contact_view(request):
111
122
  if request.method == "POST":
112
123
  form = ContactForm(request.POST)
113
124
  if form.is_valid():
114
- verify_captcha(
115
- request,
116
- redirect("/"),
117
- redirect("website:contact-page"),
118
- form
119
- )
120
- messages.success(request, "Formulaire soumis avec succès.")
121
- return redirect("/")
122
- else:
123
- puzzle = create_and_get_puzzle(request)
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("/")
124
130
  else:
125
- form = ContactForm()
126
- puzzle = create_and_get_puzzle(request)
131
+ puzzle = create_captcha_view(request)
132
+ else:
133
+ form = ContactForm()
134
+ puzzle = create_captcha_view(request)
127
135
  return render(
128
136
  request,
129
137
  "website/pages/contact/page.html",
130
138
  {"form": form, "puzzle": puzzle},
131
139
  )
132
-
133
- ```
140
+ ```
134
141
 
135
142
  # Available Versions
136
143
 
137
144
  | Version | Date | Notes |
138
145
  | ------- | ---------- | ---------------------------------- |
146
+ | 1.11.0 | 2025-05-21 | removed utils |
147
+ | 1.10.0 | 2025-05-20 | fix documentation, removed ... |
139
148
  | 1.9.0 | 2025-05-20 | puzzle images path fixed |
140
149
  | 1.8.0 | 2025-05-20 | added migrations |
141
150
  | 1.7.0 | 2025-05-20 | PUZZLE_IMAGE_STATIC_PATH ... |
@@ -146,4 +155,3 @@ PUZZLE_IMAGE_STATIC_PATH = "website/images/"
146
155
  | 1.2.0 | 2025-04-30 | fixed prune_captcha command, ... |
147
156
  | 1.1.0 | 2025-04-30 | start_server was not a module, ... |
148
157
  | 1.0.0 | 2025-04-29 | First version of the `captcha` ... |
149
- ```
@@ -43,81 +43,90 @@ 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/images/"
46
+ PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
47
47
  ```
48
48
 
49
49
  ### Utilisation
50
50
 
51
51
  - GET request (form display)
52
52
 
53
- - Use create_and_get_puzzle to generate the captcha data.
53
+ - Use create_captcha_view to generate the captcha data:
54
54
 
55
- - Passes the data into the context under the puzzle variable.
55
+ ```python
56
+ from captcha_prune.views import create_captcha_view
57
+ ```
56
58
 
57
- - Include the component in your template:
59
+ ```python
60
+ puzzle = create_captcha_view(request)
61
+ ```
62
+
63
+ - Passes the data into the context under the puzzle variable:
58
64
 
59
65
  ```python
60
- from captcha_prune.utils import create_and_get_puzzle
66
+ return render(
67
+ request,
68
+ "website/pages/contact/page.html",
69
+ {"form": form, "puzzle": puzzle},
70
+ )
61
71
  ```
62
72
 
73
+ - Include the component in your template:
74
+
63
75
  ```
64
76
  {% include "captcha_prune/captcha.html" %}
65
77
  ```
66
78
 
67
79
  - POST request (form submission)
68
80
 
69
- - Use verify_captcha to validate the captcha.
81
+ - Use verify_captcha_view to validate the captcha:
70
82
 
71
83
  ```python
72
- from captcha_prune.utils import verify_captcha
84
+ from captcha_prune.views import verify_captcha_view
73
85
  ```
74
86
 
75
87
  ```python
76
- verify_captcha(request, redirect("/"), redirect("website:contact-page"), form)
88
+ response = verify_captcha_view(request)
77
89
  ```
78
90
 
79
- - No feedback if the captcha is correct.
91
+ - True if the captcha is correct, else False.
80
92
 
81
- - Redirects in case of expired session or incorrect captcha.
93
+ - Redirects in case of expired session or incorrect captcha:
94
+
95
+ ```python
96
+ if response is False:
97
+ return redirect("website:contact-page")
98
+ ```
82
99
 
83
100
  ### Example
84
101
 
85
102
  ```python
86
- from django.shortcuts import render, redirect
87
-
88
- from django.contrib import messages
89
- from captcha_prune.utils import create_and_get_puzzle, verify_captcha
90
- from .forms import ContactForm
91
-
92
103
  def contact_view(request):
93
104
  if request.method == "POST":
94
105
  form = ContactForm(request.POST)
95
106
  if form.is_valid():
96
- verify_captcha(
97
- request,
98
- redirect("/"),
99
- redirect("website:contact-page"),
100
- form
101
- )
102
- messages.success(request, "Formulaire soumis avec succès.")
103
- return redirect("/")
104
- else:
105
- puzzle = create_and_get_puzzle(request)
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("/")
106
112
  else:
107
- form = ContactForm()
108
- puzzle = create_and_get_puzzle(request)
113
+ puzzle = create_captcha_view(request)
114
+ else:
115
+ form = ContactForm()
116
+ puzzle = create_captcha_view(request)
109
117
  return render(
110
118
  request,
111
119
  "website/pages/contact/page.html",
112
120
  {"form": form, "puzzle": puzzle},
113
121
  )
114
-
115
- ```
122
+ ```
116
123
 
117
124
  # Available Versions
118
125
 
119
126
  | Version | Date | Notes |
120
127
  | ------- | ---------- | ---------------------------------- |
128
+ | 1.11.0 | 2025-05-21 | removed utils |
129
+ | 1.10.0 | 2025-05-20 | fix documentation, removed ... |
121
130
  | 1.9.0 | 2025-05-20 | puzzle images path fixed |
122
131
  | 1.8.0 | 2025-05-20 | added migrations |
123
132
  | 1.7.0 | 2025-05-20 | PUZZLE_IMAGE_STATIC_PATH ... |
@@ -128,4 +137,3 @@ PUZZLE_IMAGE_STATIC_PATH = "website/images/"
128
137
  | 1.2.0 | 2025-04-30 | fixed prune_captcha command, ... |
129
138
  | 1.1.0 | 2025-04-30 | start_server was not a module, ... |
130
139
  | 1.0.0 | 2025-04-29 | First version of the `captcha` ... |
131
- ```
@@ -5,6 +5,6 @@ from captcha_prune.views import create_captcha_view, verify_captcha_view
5
5
  app_name = "captcha"
6
6
 
7
7
  urlpatterns = [
8
- path("", create_captcha_view, name="create-captcha"),
9
- path("<str:uuid>/", verify_captcha_view, name="verify-captcha"),
8
+ path("create/", create_captcha_view, name="create-captcha"),
9
+ path("verify/", verify_captcha_view, name="verify-captcha"),
10
10
  ]
@@ -0,0 +1,63 @@
1
+ import os
2
+ import random
3
+
4
+ from django.conf import settings
5
+ from django.contrib import messages
6
+ from django.http import HttpRequest
7
+ 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
+
11
+ from captcha_prune.models import Captcha
12
+ from captcha_prune.payloads import PuzzleAnswerPayload
13
+ from commons.decorators import use_payload
14
+
15
+
16
+ @require_POST
17
+ @csrf_exempt
18
+ def create_captcha_view(request: HttpRequest) -> dict:
19
+ captcha = Captcha.objects.create()
20
+ request.session["puzzle_uuid"] = captcha.uuid
21
+
22
+ _, _, puzzle_images_path = settings.PUZZLE_IMAGE_STATIC_PATH.rpartition("static/")
23
+ puzzle_images = [
24
+ f
25
+ for f in os.listdir(settings.PUZZLE_IMAGE_STATIC_PATH)
26
+ if f.lower().endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))
27
+ ]
28
+ selected_image = random.choice(puzzle_images)
29
+
30
+ return {
31
+ "uuid": captcha.uuid,
32
+ "width": captcha.width,
33
+ "height": captcha.height,
34
+ "piece_width": captcha.piece_width,
35
+ "piece_height": captcha.piece_height,
36
+ "pos_x_solution": captcha.pos_x_solution,
37
+ "pos_y_solution": captcha.pos_y_solution,
38
+ "piece_pos_x": captcha.piece_pos_x,
39
+ "piece_pos_y": captcha.piece_pos_y,
40
+ "image": f"{puzzle_images_path}{selected_image}",
41
+ }
42
+
43
+
44
+ @require_GET
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
54
+ captcha = get_object_or_404(Captcha, uuid=puzzle_uuid)
55
+
56
+ if (
57
+ abs(captcha.pos_x_solution - pos_x_answer) <= captcha.precision
58
+ and abs(captcha.pos_y_solution - pos_y_answer) <= captcha.precision
59
+ ):
60
+ return True
61
+ else:
62
+ messages.error(request, "Captcha incorrect. Veuillez réessayer.")
63
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prune_captcha
3
- Version: 1.9.0
3
+ Version: 1.11.0
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,81 +61,90 @@ 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/images/"
64
+ PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/"
65
65
  ```
66
66
 
67
67
  ### Utilisation
68
68
 
69
69
  - GET request (form display)
70
70
 
71
- - Use create_and_get_puzzle to generate the captcha data.
71
+ - Use create_captcha_view to generate the captcha data:
72
72
 
73
- - Passes the data into the context under the puzzle variable.
73
+ ```python
74
+ from captcha_prune.views import create_captcha_view
75
+ ```
74
76
 
75
- - Include the component in your template:
77
+ ```python
78
+ puzzle = create_captcha_view(request)
79
+ ```
80
+
81
+ - Passes the data into the context under the puzzle variable:
76
82
 
77
83
  ```python
78
- from captcha_prune.utils import create_and_get_puzzle
84
+ return render(
85
+ request,
86
+ "website/pages/contact/page.html",
87
+ {"form": form, "puzzle": puzzle},
88
+ )
79
89
  ```
80
90
 
91
+ - Include the component in your template:
92
+
81
93
  ```
82
94
  {% include "captcha_prune/captcha.html" %}
83
95
  ```
84
96
 
85
97
  - POST request (form submission)
86
98
 
87
- - Use verify_captcha to validate the captcha.
99
+ - Use verify_captcha_view to validate the captcha:
88
100
 
89
101
  ```python
90
- from captcha_prune.utils import verify_captcha
102
+ from captcha_prune.views import verify_captcha_view
91
103
  ```
92
104
 
93
105
  ```python
94
- verify_captcha(request, redirect("/"), redirect("website:contact-page"), form)
106
+ response = verify_captcha_view(request)
95
107
  ```
96
108
 
97
- - No feedback if the captcha is correct.
109
+ - True if the captcha is correct, else False.
98
110
 
99
- - Redirects in case of expired session or incorrect captcha.
111
+ - Redirects in case of expired session or incorrect captcha:
112
+
113
+ ```python
114
+ if response is False:
115
+ return redirect("website:contact-page")
116
+ ```
100
117
 
101
118
  ### Example
102
119
 
103
120
  ```python
104
- from django.shortcuts import render, redirect
105
-
106
- from django.contrib import messages
107
- from captcha_prune.utils import create_and_get_puzzle, verify_captcha
108
- from .forms import ContactForm
109
-
110
121
  def contact_view(request):
111
122
  if request.method == "POST":
112
123
  form = ContactForm(request.POST)
113
124
  if form.is_valid():
114
- verify_captcha(
115
- request,
116
- redirect("/"),
117
- redirect("website:contact-page"),
118
- form
119
- )
120
- messages.success(request, "Formulaire soumis avec succès.")
121
- return redirect("/")
122
- else:
123
- puzzle = create_and_get_puzzle(request)
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("/")
124
130
  else:
125
- form = ContactForm()
126
- puzzle = create_and_get_puzzle(request)
131
+ puzzle = create_captcha_view(request)
132
+ else:
133
+ form = ContactForm()
134
+ puzzle = create_captcha_view(request)
127
135
  return render(
128
136
  request,
129
137
  "website/pages/contact/page.html",
130
138
  {"form": form, "puzzle": puzzle},
131
139
  )
132
-
133
- ```
140
+ ```
134
141
 
135
142
  # Available Versions
136
143
 
137
144
  | Version | Date | Notes |
138
145
  | ------- | ---------- | ---------------------------------- |
146
+ | 1.11.0 | 2025-05-21 | removed utils |
147
+ | 1.10.0 | 2025-05-20 | fix documentation, removed ... |
139
148
  | 1.9.0 | 2025-05-20 | puzzle images path fixed |
140
149
  | 1.8.0 | 2025-05-20 | added migrations |
141
150
  | 1.7.0 | 2025-05-20 | PUZZLE_IMAGE_STATIC_PATH ... |
@@ -146,4 +155,3 @@ PUZZLE_IMAGE_STATIC_PATH = "website/images/"
146
155
  | 1.2.0 | 2025-04-30 | fixed prune_captcha command, ... |
147
156
  | 1.1.0 | 2025-04-30 | start_server was not a module, ... |
148
157
  | 1.0.0 | 2025-04-29 | First version of the `captcha` ... |
149
- ```
@@ -3,12 +3,10 @@ pyproject.toml
3
3
  captcha_prune/__init__.py
4
4
  captcha_prune/apps.py
5
5
  captcha_prune/asgi.py
6
- captcha_prune/context_processors.py
7
6
  captcha_prune/models.py
8
7
  captcha_prune/payloads.py
9
8
  captcha_prune/settings.py
10
9
  captcha_prune/urls.py
11
- captcha_prune/utils.py
12
10
  captcha_prune/views.py
13
11
  captcha_prune/wsgi.py
14
12
  captcha_prune/migrations/0001_initial.py
@@ -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.9.0"
23
+ version = "1.11.0"
24
24
  description = "A tool to protect formulaire from spam."
25
25
  readme = "README.md"
26
26
  dependencies = [
@@ -1,12 +0,0 @@
1
- from django.conf import settings
2
- from django.core.exceptions import ImproperlyConfigured
3
-
4
-
5
- def puzzle_static_path(request):
6
- try:
7
- path = settings.PUZZLE_IMAGE_STATIC_PATH
8
- except AttributeError:
9
- raise ImproperlyConfigured(
10
- "Vous devez définir PUZZLE_IMAGE_STATIC_PATH dans votre settings.py"
11
- )
12
- return {"PUZZLE_IMAGE_STATIC_PATH": path}
@@ -1,68 +0,0 @@
1
- import os
2
- import random
3
- from urllib.parse import urlencode
4
-
5
- import requests
6
- from django.conf import settings
7
- from django.contrib import messages
8
- from django.http import HttpRequest, HttpResponse
9
- from django.urls import reverse
10
-
11
-
12
- def create_and_get_puzzle(request: HttpRequest) -> HttpResponse | dict:
13
- _, _, puzzle_images_path = settings.PUZZLE_IMAGE_STATIC_PATH.rpartition("static/")
14
- try:
15
- response = requests.post(
16
- request.build_absolute_uri(reverse("captcha:create-captcha"))
17
- ).json()
18
- except requests.RequestException:
19
- return HttpResponse(status=502)
20
- request.session["puzzle_uuid"] = response["uuid"]
21
- puzzle_images = [
22
- f
23
- for f in os.listdir(settings.PUZZLE_IMAGE_STATIC_PATH)
24
- if f.lower().endswith((".jpg", ".jpeg", ".png", ".gif"))
25
- ]
26
- selected_image = random.choice(puzzle_images)
27
- return {
28
- "uuid": response["uuid"],
29
- "width": response["width"],
30
- "height": response["height"],
31
- "piece_width": response["piece_width"],
32
- "piece_height": response["piece_height"],
33
- "pos_x_solution": response["pos_x_solution"],
34
- "pos_y_solution": response["pos_y_solution"],
35
- "piece_pos_x": response["piece_pos_x"],
36
- "piece_pos_y": response["piece_pos_y"],
37
- "image": f"{puzzle_images_path}{selected_image}",
38
- }
39
-
40
-
41
- def verify_captcha(
42
- request: HttpRequest,
43
- session_expired: HttpResponse,
44
- incorrect_captcha: HttpResponse,
45
- form,
46
- ) -> HttpResponse | None:
47
- puzzle_uuid = request.session.get("puzzle_uuid")
48
- if not puzzle_uuid:
49
- messages.error(request, "La session a expiré.")
50
- return session_expired
51
- try:
52
- base_url = request.build_absolute_uri(
53
- reverse("captcha:verify-captcha", kwargs={"uuid": puzzle_uuid}),
54
- )
55
- data = {
56
- "pos_x_answer": request.POST.get("pos_x_answer"),
57
- "pos_y_answer": request.POST.get("pos_y_answer"),
58
- }
59
- query_string = urlencode(data)
60
- full_url = f"{base_url}?{query_string}"
61
- response = requests.get(full_url)
62
- if response.status_code == 401:
63
- messages.error(request, "Captcha incorrect. Veuillez réessayer.")
64
- return incorrect_captcha
65
- del form.fields["pos_x_answer"]
66
- del form.fields["pos_y_answer"]
67
- except requests.RequestException:
68
- return HttpResponse(status=502)
@@ -1,45 +0,0 @@
1
- from django.http import HttpRequest, HttpResponse, JsonResponse
2
- from django.shortcuts import get_object_or_404
3
- from django.views.decorators.csrf import csrf_exempt
4
- from django.views.decorators.http import require_GET, require_POST
5
-
6
- from captcha_prune.models import Captcha
7
- from captcha_prune.payloads import PuzzleAnswerPayload
8
- from commons.decorators import use_payload
9
-
10
-
11
- @require_POST
12
- @csrf_exempt
13
- def create_captcha_view(request: HttpRequest) -> HttpResponse:
14
- captcha = Captcha.objects.create()
15
- return JsonResponse(
16
- status=201,
17
- data={
18
- "uuid": str(captcha.uuid),
19
- "width": captcha.width,
20
- "height": captcha.height,
21
- "piece_width": captcha.piece_width,
22
- "piece_height": captcha.piece_height,
23
- "pos_x_solution": captcha.pos_x_solution,
24
- "pos_y_solution": captcha.pos_y_solution,
25
- "piece_pos_x": captcha.piece_pos_x,
26
- "piece_pos_y": captcha.piece_pos_y,
27
- },
28
- )
29
-
30
-
31
- @require_GET
32
- @use_payload(PuzzleAnswerPayload)
33
- def verify_captcha_view(
34
- request: HttpRequest, uuid: str, payload: PuzzleAnswerPayload
35
- ) -> HttpResponse:
36
- captcha = get_object_or_404(Captcha, uuid=uuid)
37
- pos_x_answer = payload.pos_x_answer
38
- pos_y_answer = payload.pos_y_answer
39
- if (
40
- abs(captcha.pos_x_solution - pos_x_answer) <= captcha.precision
41
- and abs(captcha.pos_y_solution - pos_y_answer) <= captcha.precision
42
- ):
43
- return HttpResponse(status=304)
44
- else:
45
- return HttpResponse(status=401)
File without changes