django-cookie-consent 0.8.0__py3-none-any.whl → 1.0.0__py3-none-any.whl

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 (29) hide show
  1. cookie_consent/__init__.py +1 -1
  2. cookie_consent/admin.py +32 -4
  3. cookie_consent/cache.py +13 -8
  4. cookie_consent/conf.py +21 -13
  5. cookie_consent/forms.py +50 -0
  6. cookie_consent/middleware.py +7 -6
  7. cookie_consent/migrations/0001_initial.py +2 -1
  8. cookie_consent/migrations/0003_alter_cookiegroup_varname.py +2 -2
  9. cookie_consent/migrations/0004_cookie_natural_key.py +0 -1
  10. cookie_consent/models.py +30 -20
  11. cookie_consent/processor.py +77 -0
  12. cookie_consent/py.typed +0 -0
  13. cookie_consent/static/cookie_consent/cookiebar.module.js +8 -3
  14. cookie_consent/static/cookie_consent/cookiebar.module.js.map +2 -2
  15. cookie_consent/templates/cookie_consent/_cookie_group.html +4 -2
  16. cookie_consent/templatetags/__init__.py +0 -1
  17. cookie_consent/templatetags/cookie_consent_tags.py +25 -116
  18. cookie_consent/urls.py +3 -25
  19. cookie_consent/util.py +87 -119
  20. cookie_consent/views.py +46 -40
  21. django_cookie_consent-1.0.0.dist-info/METADATA +96 -0
  22. django_cookie_consent-1.0.0.dist-info/RECORD +31 -0
  23. {django_cookie_consent-0.8.0.dist-info → django_cookie_consent-1.0.0.dist-info}/WHEEL +1 -1
  24. cookie_consent/static/cookie_consent/cookiebar.js +0 -67
  25. django_cookie_consent-0.8.0.dist-info/METADATA +0 -125
  26. django_cookie_consent-0.8.0.dist-info/RECORD +0 -30
  27. django_cookie_consent-0.8.0.dist-info/licenses/AUTHORS +0 -14
  28. {django_cookie_consent-0.8.0.dist-info → django_cookie_consent-1.0.0.dist-info}/licenses/LICENSE +0 -0
  29. {django_cookie_consent-0.8.0.dist-info → django_cookie_consent-1.0.0.dist-info}/top_level.txt +0 -0
@@ -1,16 +1,13 @@
1
- import warnings
1
+ from collections.abc import Collection
2
2
 
3
3
  from django import template
4
- from django.urls import reverse
4
+ from django.http import HttpRequest
5
5
  from django.utils.html import json_script
6
6
 
7
7
  from ..cache import all_cookie_groups as get_all_cookie_groups
8
- from ..conf import settings
8
+ from ..models import CookieGroup
9
9
  from ..util import (
10
10
  are_all_cookies_accepted,
11
- get_accepted_cookies,
12
- get_cookie_dict_from_request,
13
- get_cookie_string,
14
11
  get_cookie_value_from_request,
15
12
  get_not_accepted_or_declined_cookie_groups,
16
13
  is_cookie_consent_enabled,
@@ -20,31 +17,39 @@ register = template.Library()
20
17
 
21
18
 
22
19
  @register.filter
23
- def cookie_group_accepted(request, arg):
20
+ def cookie_group_accepted(request: HttpRequest, group_or_cookie: str) -> bool:
24
21
  """
25
- Filter returns if cookie group is accepted.
22
+ Return ``True`` if the cookie group/cookie is accepted.
26
23
 
27
24
  Examples:
28
- ::
25
+
26
+ .. code-block:: django
29
27
 
30
28
  {{ request|cookie_group_accepted:"analytics" }}
31
29
  {{ request|cookie_group_accepted:"analytics=*:.google.com" }}
32
30
  """
33
- value = get_cookie_value_from_request(request, *arg.split("="))
31
+ value = get_cookie_value_from_request(request, *group_or_cookie.split("="))
34
32
  return value is True
35
33
 
36
34
 
37
35
  @register.filter
38
- def cookie_group_declined(request, arg):
36
+ def cookie_group_declined(request: HttpRequest, group_or_cookie: str) -> bool:
39
37
  """
40
- Filter returns if cookie group is declined.
38
+ Return ``True`` if the cookie group/cookie is declined.
39
+
40
+ Examples:
41
+
42
+ .. code-block:: django
43
+
44
+ {{ request|cookie_group_declined:"analytics" }}
45
+ {{ request|cookie_group_declined:"analytics=*:.google.com" }}
41
46
  """
42
- value = get_cookie_value_from_request(request, *arg.split("="))
47
+ value = get_cookie_value_from_request(request, *group_or_cookie.split("="))
43
48
  return value is False
44
49
 
45
50
 
46
51
  @register.filter
47
- def all_cookies_accepted(request):
52
+ def all_cookies_accepted(request: HttpRequest) -> bool:
48
53
  """
49
54
  Filter returns if all cookies are accepted.
50
55
  """
@@ -52,119 +57,23 @@ def all_cookies_accepted(request):
52
57
 
53
58
 
54
59
  @register.simple_tag
55
- def not_accepted_or_declined_cookie_groups(request):
60
+ def not_accepted_or_declined_cookie_groups(
61
+ request: HttpRequest,
62
+ ) -> Collection[CookieGroup]:
56
63
  """
57
- Assignement tag returns cookie groups that does not yet given consent
58
- or decline.
64
+ Return the cookie groups for which no explicit accept or decline has been given.
59
65
  """
60
66
  return get_not_accepted_or_declined_cookie_groups(request)
61
67
 
62
68
 
63
69
  @register.filter
64
- def cookie_consent_enabled(request):
70
+ def cookie_consent_enabled(request: HttpRequest) -> bool:
65
71
  """
66
- Filter returns if cookie consent enabled for this request.
72
+ Indicate whether the cookie-consent app is enabled or not.
67
73
  """
68
74
  return is_cookie_consent_enabled(request)
69
75
 
70
76
 
71
- @register.simple_tag
72
- def cookie_consent_accept_url(cookie_groups):
73
- """
74
- Assignement tag returns url for accepting given concept groups.
75
- """
76
- varnames = ",".join([g.varname for g in cookie_groups])
77
- url = reverse("cookie_consent_accept", kwargs={"varname": varnames})
78
- return url
79
-
80
-
81
- @register.simple_tag
82
- def cookie_consent_decline_url(cookie_groups):
83
- """
84
- Assignement tag returns url for declining given concept groups.
85
- """
86
- varnames = ",".join([g.varname for g in cookie_groups])
87
- url = reverse("cookie_consent_decline", kwargs={"varname": varnames})
88
- return url
89
-
90
-
91
- @register.simple_tag
92
- def get_accept_cookie_groups_cookie_string(request, cookie_groups): # pragma: no cover
93
- """
94
- Tag returns accept cookie string suitable to use in javascript.
95
- """
96
- warnings.warn(
97
- "Cookie string template tags for JS are deprecated and will be removed "
98
- "in django-cookie-consent 1.0",
99
- DeprecationWarning,
100
- )
101
- cookie_dic = get_cookie_dict_from_request(request)
102
- for cookie_group in cookie_groups:
103
- cookie_dic[cookie_group.varname] = cookie_group.get_version()
104
- return get_cookie_string(cookie_dic)
105
-
106
-
107
- @register.simple_tag
108
- def get_decline_cookie_groups_cookie_string(request, cookie_groups):
109
- """
110
- Tag returns decline cookie string suitable to use in javascript.
111
- """
112
- warnings.warn(
113
- "Cookie string template tags for JS are deprecated and will be removed "
114
- "in django-cookie-consent 1.0",
115
- DeprecationWarning,
116
- )
117
- cookie_dic = get_cookie_dict_from_request(request)
118
- for cookie_group in cookie_groups:
119
- cookie_dic[cookie_group.varname] = settings.COOKIE_CONSENT_DECLINE
120
- return get_cookie_string(cookie_dic)
121
-
122
-
123
- @register.simple_tag
124
- def js_type_for_cookie_consent(request, varname, cookie=None):
125
- """
126
- Tag returns "x/cookie_consent" when processing javascript
127
- will create an cookie and consent does not exists yet.
128
-
129
- Example::
130
-
131
- <script type="{% js_type_for_cookie_consent request "social" %}"
132
- data-varname="social">
133
- alert("Social cookie accepted");
134
- </script>
135
- """
136
- # This approach doesn't work with page caches and/or strict Content-Security-Policies
137
- # (unless you use nonces, which again doesn't work with aggressive page caching).
138
- warnings.warn(
139
- "Template tags for use in/with JS are deprecated and will be removed "
140
- "in django-cookie-consent 1.0",
141
- DeprecationWarning,
142
- )
143
- enabled = is_cookie_consent_enabled(request)
144
- if not enabled:
145
- res = True
146
- else:
147
- value = get_cookie_value_from_request(request, varname, cookie)
148
- if value is None:
149
- res = settings.COOKIE_CONSENT_OPT_OUT
150
- else:
151
- res = value
152
- return "text/javascript" if res else "x/cookie_consent"
153
-
154
-
155
- @register.filter
156
- def accepted_cookies(request):
157
- """
158
- Filter returns accepted cookies varnames.
159
-
160
- .. code-block:: django
161
-
162
- {{ request|accepted_cookies }}
163
-
164
- """
165
- return [c.varname for c in get_accepted_cookies(request)]
166
-
167
-
168
77
  @register.simple_tag
169
78
  def all_cookie_groups(element_id: str):
170
79
  """
cookie_consent/urls.py CHANGED
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- from django.urls import path, re_path
3
- from django.views.decorators.csrf import csrf_exempt
1
+ from django.urls import path
4
2
 
5
3
  from .views import (
6
4
  CookieGroupAcceptView,
@@ -10,28 +8,8 @@ from .views import (
10
8
  )
11
9
 
12
10
  urlpatterns = [
13
- path(
14
- "accept/",
15
- csrf_exempt(CookieGroupAcceptView.as_view()),
16
- name="cookie_consent_accept_all",
17
- ),
18
- # TODO: use form or query string params for this instead?
19
- re_path(
20
- r"^accept/(?P<varname>.*)/$",
21
- csrf_exempt(CookieGroupAcceptView.as_view()),
22
- name="cookie_consent_accept",
23
- ),
24
- # TODO: use form or query string params for this instead?
25
- re_path(
26
- r"^decline/(?P<varname>.*)/$",
27
- csrf_exempt(CookieGroupDeclineView.as_view()),
28
- name="cookie_consent_decline",
29
- ),
30
- path(
31
- "decline/",
32
- csrf_exempt(CookieGroupDeclineView.as_view()),
33
- name="cookie_consent_decline_all",
34
- ),
11
+ path("accept/", CookieGroupAcceptView.as_view(), name="cookie_consent_accept"),
12
+ path("decline/", CookieGroupDeclineView.as_view(), name="cookie_consent_decline"),
35
13
  path("status/", CookieStatusView.as_view(), name="cookie_consent_status"),
36
14
  path("", CookieGroupListView.as_view(), name="cookie_consent_cookie_group_list"),
37
15
  ]
cookie_consent/util.py CHANGED
@@ -1,125 +1,125 @@
1
- # -*- coding: utf-8 -*-
2
- import datetime
3
- from typing import Union
1
+ import logging
2
+ from collections.abc import Callable, Collection, Iterator
3
+
4
+ from django.http import HttpRequest, HttpResponseBase
4
5
 
5
6
  from .cache import all_cookie_groups, get_cookie, get_cookie_group
6
7
  from .conf import settings
7
- from .models import ACTION_ACCEPTED, ACTION_DECLINED, LogItem
8
+ from .models import Cookie, CookieGroup
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ COOKIE_GROUP_SEP = "|"
13
+ KEY_VALUE_SEP = "="
8
14
 
9
15
 
10
- def parse_cookie_str(cookie):
11
- dic = {}
16
+ def parse_cookie_str(cookie: str) -> dict[str, str]:
12
17
  if not cookie:
13
- return dic
14
- for c in cookie.split("|"):
15
- key, value = c.split("=")
16
- dic[key] = value
17
- return dic
18
+ return {}
19
+
20
+ bits = cookie.split(COOKIE_GROUP_SEP)
21
+
22
+ def _gen_pairs() -> Iterator[tuple[str, str]]:
23
+ for possible_pair in bits:
24
+ parts = possible_pair.split(KEY_VALUE_SEP)
25
+ if len(parts) == 2:
26
+ varname, cookie = parts
27
+ yield varname, cookie
28
+ else:
29
+ logger.debug("cookie_value_discarded", extra={"value": possible_pair})
18
30
 
31
+ return dict(_gen_pairs())
19
32
 
20
- def dict_to_cookie_str(dic):
21
- return "|".join(["%s=%s" % (k, v) for k, v in dic.items() if v])
22
33
 
34
+ def _contains_invalid_characters(*inputs: str) -> bool:
35
+ # = and | are special separators. They are unexpected characters in both
36
+ # keys and values.
37
+ for separator in (COOKIE_GROUP_SEP, KEY_VALUE_SEP):
38
+ for value in inputs:
39
+ if separator in value:
40
+ logger.debug("skip_separator", extra={"value": value, "sep": separator})
41
+ return True
42
+ return False
23
43
 
24
- def get_cookie_dict_from_request(request):
25
- cookie_str = request.COOKIES.get(settings.COOKIE_CONSENT_NAME)
44
+
45
+ def dict_to_cookie_str(dic: dict[str, str]) -> str:
46
+ """
47
+ Serialize a dictionary of cookie-group metadata to a string.
48
+
49
+ The result is stored in a cookie itself. Note that the dictionary keys are expected
50
+ to be cookie group ``varname`` fields, which are validated against a slug regex. The
51
+ values are supposed to be ISO-8601 timestamps.
52
+
53
+ Invalid key/value pairs are dropped.
54
+ """
55
+
56
+ def _gen_pairs() -> Iterator[str]:
57
+ for key, value in dic.items():
58
+ if _contains_invalid_characters(key, value):
59
+ continue
60
+ yield f"{key}={value}"
61
+
62
+ return "|".join(_gen_pairs())
63
+
64
+
65
+ def get_cookie_dict_from_request(request: HttpRequest) -> dict[str, str]:
66
+ cookie_str = request.COOKIES.get(settings.COOKIE_CONSENT_NAME, "")
26
67
  return parse_cookie_str(cookie_str)
27
68
 
28
69
 
29
- def set_cookie_dict_to_response(response, dic):
70
+ def set_cookie_dict_to_response(
71
+ response: HttpResponseBase, dic: dict[str, str]
72
+ ) -> None:
30
73
  response.set_cookie(
31
74
  settings.COOKIE_CONSENT_NAME,
32
75
  dict_to_cookie_str(dic),
33
76
  max_age=settings.COOKIE_CONSENT_MAX_AGE,
34
77
  domain=settings.COOKIE_CONSENT_DOMAIN,
35
- secure=settings.COOKIE_CONSENT_SECURE or None,
36
- httponly=settings.COOKIE_CONSENT_HTTPONLY or None,
78
+ secure=settings.COOKIE_CONSENT_SECURE,
79
+ httponly=settings.COOKIE_CONSENT_HTTPONLY,
37
80
  samesite=settings.COOKIE_CONSENT_SAMESITE,
38
81
  )
39
82
 
40
83
 
41
- def get_cookie_value_from_request(request, varname, cookie=None):
84
+ def get_cookie_value_from_request(
85
+ request: HttpRequest, varname: str, cookie: str = ""
86
+ ) -> bool | None:
42
87
  """
43
88
  Returns if cookie group or its specific cookie has been accepted.
44
89
 
45
90
  Returns True or False when cookie is accepted or declined or None
46
91
  if cookie is not set.
47
92
  """
48
- cookie_dic = get_cookie_dict_from_request(request)
49
- if not cookie_dic:
93
+ if not (cookie_dic := get_cookie_dict_from_request(request)):
50
94
  return None
51
-
52
- cookie_group = get_cookie_group(varname=varname)
53
- if not cookie_group:
95
+ if not (cookie_group := get_cookie_group(varname=varname)):
54
96
  return None
97
+
98
+ _cookie: Cookie | None = None
55
99
  if cookie:
56
100
  name, domain = cookie.split(":")
57
- cookie = get_cookie(cookie_group, name, domain)
58
- else:
59
- cookie = None
101
+ _cookie = get_cookie(cookie_group, name, domain)
60
102
 
61
- version = cookie_dic.get(varname, None)
103
+ match version := cookie_dic.get(varname, None):
104
+ case None:
105
+ return None
106
+ case str() if version == settings.COOKIE_CONSENT_DECLINE:
107
+ return False
62
108
 
63
- if version == settings.COOKIE_CONSENT_DECLINE:
64
- return False
65
- if version is None:
66
- return None
67
- if not cookie:
68
- v = cookie_group.get_version()
69
- else:
70
- v = cookie.get_version()
71
- if version >= v:
109
+ reference_version = _cookie.get_version() if _cookie else cookie_group.get_version()
110
+ if version >= reference_version:
72
111
  return True
73
112
  return None
74
113
 
75
114
 
76
- def get_cookie_groups(varname=None):
115
+ def get_cookie_groups(varname: str = "") -> Collection[CookieGroup]:
77
116
  if not varname:
78
117
  return all_cookie_groups().values()
79
118
  keys = varname.split(",")
80
119
  return [g for k, g in all_cookie_groups().items() if k in keys]
81
120
 
82
121
 
83
- def accept_cookies(request, response, varname=None):
84
- """
85
- Accept cookies in Cookie Group specified by ``varname``.
86
- """
87
- cookie_dic = get_cookie_dict_from_request(request)
88
- for cookie_group in get_cookie_groups(varname):
89
- cookie_dic[cookie_group.varname] = cookie_group.get_version()
90
- if settings.COOKIE_CONSENT_LOG_ENABLED:
91
- LogItem.objects.create(
92
- action=ACTION_ACCEPTED,
93
- cookiegroup=cookie_group,
94
- version=cookie_group.get_version(),
95
- )
96
- set_cookie_dict_to_response(response, cookie_dic)
97
-
98
-
99
- def delete_cookies(response, cookie_group):
100
- if cookie_group.is_deletable:
101
- for cookie in cookie_group.cookie_set.all():
102
- response.delete_cookie(cookie.name, cookie.path, cookie.domain)
103
-
104
-
105
- def decline_cookies(request, response, varname=None):
106
- """
107
- Decline and delete cookies in CookieGroup specified by ``varname``.
108
- """
109
- cookie_dic = get_cookie_dict_from_request(request)
110
- for cookie_group in get_cookie_groups(varname):
111
- cookie_dic[cookie_group.varname] = settings.COOKIE_CONSENT_DECLINE
112
- delete_cookies(response, cookie_group)
113
- if settings.COOKIE_CONSENT_LOG_ENABLED:
114
- LogItem.objects.create(
115
- action=ACTION_DECLINED,
116
- cookiegroup=cookie_group,
117
- version=cookie_group.get_version(),
118
- )
119
- set_cookie_dict_to_response(response, cookie_dic)
120
-
121
-
122
- def are_all_cookies_accepted(request):
122
+ def are_all_cookies_accepted(request: HttpRequest) -> bool:
123
123
  """
124
124
  Returns if all cookies are accepted.
125
125
  """
@@ -131,7 +131,7 @@ def are_all_cookies_accepted(request):
131
131
  )
132
132
 
133
133
 
134
- def _get_cookie_groups_by_state(request, state: Union[bool, None]):
134
+ def _get_cookie_groups_by_state(request, state: bool | None) -> Collection[CookieGroup]:
135
135
  return [
136
136
  cookie_group
137
137
  for cookie_group in get_cookie_groups()
@@ -139,64 +139,32 @@ def _get_cookie_groups_by_state(request, state: Union[bool, None]):
139
139
  ]
140
140
 
141
141
 
142
- def get_not_accepted_or_declined_cookie_groups(request):
142
+ def get_not_accepted_or_declined_cookie_groups(
143
+ request: HttpRequest,
144
+ ) -> Collection[CookieGroup]:
143
145
  """
144
146
  Returns all cookie groups that are neither accepted or declined.
145
147
  """
146
148
  return _get_cookie_groups_by_state(request, state=None)
147
149
 
148
150
 
149
- def get_accepted_cookie_groups(request):
151
+ def get_accepted_cookie_groups(request: HttpRequest) -> Collection[CookieGroup]:
150
152
  """
151
153
  Returns all cookie groups that are accepted.
152
154
  """
153
155
  return _get_cookie_groups_by_state(request, state=True)
154
156
 
155
157
 
156
- def get_declined_cookie_groups(request):
158
+ def get_declined_cookie_groups(request: HttpRequest) -> Collection[CookieGroup]:
157
159
  """
158
160
  Returns all cookie groups that are declined.
159
161
  """
160
162
  return _get_cookie_groups_by_state(request, state=False)
161
163
 
162
164
 
163
- def is_cookie_consent_enabled(request):
165
+ def is_cookie_consent_enabled(request: HttpRequest) -> bool:
164
166
  """
165
167
  Returns if django-cookie-consent is enabled for given request.
166
168
  """
167
- enabled = settings.COOKIE_CONSENT_ENABLED
168
- if callable(enabled):
169
- return enabled(request)
170
- else:
171
- return enabled
172
-
173
-
174
- def get_cookie_string(cookie_dic):
175
- """
176
- Returns cookie in format suitable for use in javascript.
177
- """
178
- expires = datetime.datetime.now() + datetime.timedelta(
179
- seconds=settings.COOKIE_CONSENT_MAX_AGE
180
- )
181
- cookie_str = "%s=%s; expires=%s; path=/" % (
182
- settings.COOKIE_CONSENT_NAME,
183
- dict_to_cookie_str(cookie_dic),
184
- expires.strftime("%a, %d %b %Y %H:%M:%S GMT"),
185
- )
186
- return cookie_str
187
-
188
-
189
- def get_accepted_cookies(request):
190
- """
191
- Returns all accepted cookies.
192
- """
193
- cookie_dic = get_cookie_dict_from_request(request)
194
- accepted_cookies = []
195
- for cookie_group in all_cookie_groups().values():
196
- version = cookie_dic.get(cookie_group.varname, None)
197
- if not version or version == settings.COOKIE_CONSENT_DECLINE:
198
- continue
199
- for cookie in cookie_group.cookie_set.all():
200
- if version >= cookie.get_version():
201
- accepted_cookies.append(cookie)
202
- return accepted_cookies
169
+ enabled: bool | Callable[[HttpRequest], bool] = settings.COOKIE_CONSENT_ENABLED
170
+ return enabled(request) if callable(enabled) else enabled
cookie_consent/views.py CHANGED
@@ -1,16 +1,22 @@
1
- # -*- coding: utf-8 -*-
1
+ from typing import Literal
2
+
2
3
  from django.contrib.auth.views import RedirectURLMixin
3
- from django.core.exceptions import SuspiciousOperation
4
- from django.http import HttpRequest, HttpResponse, HttpResponseRedirect, JsonResponse
4
+ from django.http import (
5
+ HttpRequest,
6
+ HttpResponse,
7
+ HttpResponseBase,
8
+ HttpResponseRedirect,
9
+ JsonResponse,
10
+ )
5
11
  from django.middleware.csrf import get_token as get_csrf_token
6
12
  from django.urls import reverse
7
- from django.utils.http import url_has_allowed_host_and_scheme
8
13
  from django.views.generic import ListView, View
9
14
 
15
+ from .conf import settings
16
+ from .forms import ProcessCookiesForm
10
17
  from .models import CookieGroup
18
+ from .processor import CookiesProcessor
11
19
  from .util import (
12
- accept_cookies,
13
- decline_cookies,
14
20
  get_accepted_cookie_groups,
15
21
  get_declined_cookie_groups,
16
22
  get_not_accepted_or_declined_cookie_groups,
@@ -36,31 +42,40 @@ class CookieGroupListView(ListView):
36
42
 
37
43
 
38
44
  class CookieGroupBaseProcessView(RedirectURLMixin, View):
39
- def get_success_url(self):
40
- """
41
- If user adds a 'next' as URL parameter or hidden input,
42
- redirect to the value of 'next'. Otherwise, redirect to
43
- cookie consent group list
44
- """
45
- redirect_to = self.request.POST.get("next", self.request.GET.get("next"))
46
- if redirect_to and not url_has_allowed_host_and_scheme(
47
- url=redirect_to,
48
- allowed_hosts=self.get_success_url_allowed_hosts(),
49
- require_https=self.request.is_secure(),
50
- ):
51
- raise SuspiciousOperation("Unsafe open redirect suspected.")
52
- return redirect_to or reverse("cookie_consent_cookie_group_list")
53
-
54
- def process(self, request, response, varname): # pragma: no cover
55
- raise NotImplementedError()
56
-
57
- def post(self, request, *args, **kwargs):
58
- varname = kwargs.get("varname", None)
45
+ """
46
+ Process the cookie groups submitted in the POST request (or URL parameters).
47
+
48
+ :class:`RedirectURLMixin` takes care of the hardening against open redirects.
49
+ """
50
+
51
+ cookie_process_action: Literal["accept", "decline"]
52
+ """
53
+ Processing action to apply, must be set on the subclasses.
54
+ """
55
+
56
+ def get_default_redirect_url(self) -> str:
57
+ return settings.COOKIE_CONSENT_SUCCESS_URL
58
+
59
+ def post(self, request: HttpRequest, *args, **kwargs):
60
+ form = ProcessCookiesForm(data=request.POST)
61
+
62
+ if not form.is_valid():
63
+ if is_ajax_like(request):
64
+ return JsonResponse(form.errors.get_json_data())
65
+ else:
66
+ return HttpResponse(form.errors.render())
67
+
68
+ cookie_groups = form.get_cookie_groups()
69
+
70
+ response: HttpResponseBase
59
71
  if is_ajax_like(request):
60
72
  response = HttpResponse()
61
73
  else:
62
74
  response = HttpResponseRedirect(self.get_success_url())
63
- self.process(request, response, varname)
75
+
76
+ processor = CookiesProcessor(request, response)
77
+ processor.process(cookie_groups, action=self.cookie_process_action)
78
+
64
79
  return response
65
80
 
66
81
 
@@ -69,8 +84,7 @@ class CookieGroupAcceptView(CookieGroupBaseProcessView):
69
84
  View to accept CookieGroup.
70
85
  """
71
86
 
72
- def process(self, request, response, varname):
73
- accept_cookies(request, response, varname)
87
+ cookie_process_action = "accept"
74
88
 
75
89
 
76
90
  class CookieGroupDeclineView(CookieGroupBaseProcessView):
@@ -78,11 +92,7 @@ class CookieGroupDeclineView(CookieGroupBaseProcessView):
78
92
  View to decline CookieGroup.
79
93
  """
80
94
 
81
- def process(self, request, response, varname):
82
- decline_cookies(request, response, varname)
83
-
84
- def delete(self, request, *args, **kwargs):
85
- return self.post(request, *args, **kwargs)
95
+ cookie_process_action = "decline"
86
96
 
87
97
 
88
98
  class CookieStatusView(View):
@@ -100,14 +110,10 @@ class CookieStatusView(View):
100
110
  accepted = get_accepted_cookie_groups(request)
101
111
  declined = get_declined_cookie_groups(request)
102
112
  not_accepted_or_declined = get_not_accepted_or_declined_cookie_groups(request)
103
- # TODO: change this csv URL param into proper POST params
104
- varnames = ",".join([group.varname for group in not_accepted_or_declined])
105
113
  data = {
106
114
  "csrftoken": get_csrf_token(request),
107
- "acceptUrl": reverse("cookie_consent_accept", kwargs={"varname": varnames}),
108
- "declineUrl": reverse(
109
- "cookie_consent_decline", kwargs={"varname": varnames}
110
- ),
115
+ "acceptUrl": reverse("cookie_consent_accept"),
116
+ "declineUrl": reverse("cookie_consent_decline"),
111
117
  "acceptedCookieGroups": [group.varname for group in accepted],
112
118
  "declinedCookieGroups": [group.varname for group in declined],
113
119
  "notAcceptedOrDeclinedCookieGroups": [