Skip to content

Commit b2c5c4e

Browse files
committed
chore: update deps
1 parent 4b8b5ba commit b2c5c4e

File tree

7 files changed

+108
-107
lines changed

7 files changed

+108
-107
lines changed

config/settings.py

+26-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import asgiref
99
import django
1010
import environ
11+
from csp.constants import NONCE, NONE, SELF, STRICT_DYNAMIC, UNSAFE_INLINE
1112
from django.contrib.messages import constants as messages
1213
from django.utils.translation import gettext_lazy as _
1314
from template_partials.apps import wrap_loaders
@@ -331,30 +332,31 @@
331332
# https://django-csp.readthedocs.io/en/latest/configuration.html
332333
# https://content-security-policy.com/
333334
# https://csp-evaluator.withgoogle.com/
334-
CSP_DEFAULT_SRC = ("'self'",)
335-
CSP_SCRIPT_SRC = ("'strict-dynamic'", "'unsafe-inline'", "https:")
336-
CSP_SCRIPT_SRC_ATTR = None
337-
CSP_SCRIPT_SRC_ELEM = None
338-
CSP_IMG_SRC = ("'self'", "data:")
339-
CSP_OBJECT_SRC = ("'none'",)
340-
CSP_MEDIA_SRC = ("'self'",)
341-
CSP_FRAME_SRC = ("'none'",)
342-
CSP_FONT_SRC = ("'self'",)
343-
CSP_CONNECT_SRC = env.tuple("CSP_CONNECT_SRC", default=("'self'",))
344-
CSP_STYLE_SRC = ("'strict-dynamic'", "'unsafe-inline'", "https:")
345-
CSP_STYLE_SRC_ATTR = None
346-
CSP_STYLE_SRC_ELEM = None
347-
CSP_BASE_URI = ("'none'",)
348-
CSP_FRAME_ANCESTORS = ("'none'",)
349-
CSP_FORM_ACTION = ("'self'",)
350-
CSP_MANIFEST_SRC = ("'self'",)
351-
CSP_WORKER_SRC = ("'self'",)
352-
CSP_PLUGIN_TYPES = None
353-
CSP_REQUIRE_SRI_FOR = None
354-
CSP_INCLUDE_NONCE_IN = ("script-src", "style-src")
355-
# Those are forced to true in production
356-
CSP_UPGRADE_INSECURE_REQUESTS = IS_PRODUCTION
357-
CSP_BLOCK_ALL_MIXED_CONTENT = IS_PRODUCTION
335+
CONTENT_SECURITY_POLICY = {
336+
"DIRECTIVES": {
337+
"default-src": (SELF,),
338+
"script-src": (STRICT_DYNAMIC, UNSAFE_INLINE, "https:", NONCE),
339+
"script-src-attr": None,
340+
"script-src-elem": None,
341+
"img-src": (SELF, "data:"),
342+
"object-src": (NONE,),
343+
"media-src": (SELF,),
344+
"frame-src": (NONE,),
345+
"font-src": (SELF,),
346+
"connect-src": env.tuple("CSP_CONNECT_SRC", default=(SELF,)),
347+
"style-src": (STRICT_DYNAMIC, UNSAFE_INLINE, "https:", NONCE),
348+
"style-src-attr": None,
349+
"style-src-elem": None,
350+
"base-uri": (NONE,),
351+
"child-src": (NONE,),
352+
"frame-ancestors": (NONE,),
353+
"form-action": (SELF,),
354+
"manifest-src": (SELF,),
355+
"worker-src": (SELF,),
356+
"require-sri-for": (NONE,),
357+
"upgrade-insecure-requests": IS_PRODUCTION,
358+
},
359+
}
358360

359361

360362
# CORS

legadilo/feeds/views/feed_articles_view.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
@require_http_methods(["GET", "POST"])
3232
@login_required
33-
@csp_update(IMG_SRC="https:")
33+
@csp_update({"img-src": "https:"}) # type: ignore[arg-type]
3434
def feed_articles_view(
3535
request: AuthenticatedHttpRequest, feed_id: int, feed_slug: str | None = None
3636
) -> TemplateResponse:

legadilo/reading/tests/test_views/test_manage_reading_lists_view.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def test_invalid_form(self, logged_in_sync_client):
105105
}
106106

107107
def test_create_reading_list(self, logged_in_sync_client, user, django_assert_num_queries):
108-
with django_assert_num_queries(33):
108+
with django_assert_num_queries(49):
109109
response = logged_in_sync_client.post(self.url, data=self.sample_data)
110110

111111
reading_list = ReadingList.objects.get()
@@ -135,7 +135,7 @@ def test_create_duplicated_reading_list(
135135
**self.sample_data, slug=slugify(self.sample_data["title"]), user=user
136136
)
137137

138-
with django_assert_num_queries(19):
138+
with django_assert_num_queries(35):
139139
response = logged_in_sync_client.post(self.url, data=self.sample_data)
140140

141141
assert response.status_code == HTTPStatus.CONFLICT

legadilo/reading/views/article_details_views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def __init__(
6161

6262
@require_http_methods(["GET", "POST"])
6363
@login_required
64-
@csp_update(IMG_SRC="https:")
64+
@csp_update({"img-src": "https:"}) # type: ignore[arg-type]
6565
def article_details_view(
6666
request: AuthenticatedHttpRequest, article_id: int, article_slug: str
6767
) -> TemplateResponse:

legadilo/reading/views/list_of_articles_views.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from django.core.exceptions import ValidationError
2626
from django.core.paginator import Paginator
2727
from django.db import transaction
28-
from django.http import HttpResponseNotFound, HttpResponseRedirect
28+
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
2929
from django.shortcuts import get_object_or_404
3030
from django.template.response import TemplateResponse
3131
from django.urls import reverse
@@ -47,10 +47,10 @@
4747

4848
@require_GET
4949
@login_required
50-
@csp_update(IMG_SRC="https:")
50+
@csp_update({"img-src": "https:"}) # type: ignore[arg-type]
5151
def reading_list_with_articles_view(
5252
request: AuthenticatedHttpRequest, reading_list_slug: str | None = None
53-
):
53+
) -> HttpResponse:
5454
try:
5555
displayed_reading_list = ReadingList.objects.get_reading_list(
5656
request.user, reading_list_slug
@@ -137,7 +137,7 @@ def _display_list_of_articles(
137137

138138
@require_http_methods(["GET", "POST"])
139139
@login_required
140-
@csp_update(IMG_SRC="https:")
140+
@csp_update({"img-src": "https:"}) # type: ignore[arg-type]
141141
def tag_with_articles_view(request: AuthenticatedHttpRequest, tag_slug: str) -> TemplateResponse:
142142
displayed_tag = get_object_or_404(
143143
Tag,
@@ -154,7 +154,7 @@ def tag_with_articles_view(request: AuthenticatedHttpRequest, tag_slug: str) ->
154154

155155
@require_http_methods(["GET", "POST"])
156156
@login_required
157-
@csp_update(IMG_SRC="https:")
157+
@csp_update({"img-src": "https:"}) # type: ignore[arg-type]
158158
def external_tag_with_articles_view(
159159
request: AuthenticatedHttpRequest, tag: str
160160
) -> TemplateResponse:

legadilo/users/tests/snapshots/test_registration/test_registration_success/login_failure_response.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ <h1>Sign In</h1>
231231

232232
<div id="div_id_login" class="mb-3"> <label
233233
for="id_login" class="form-label requiredField">
234-
Email<span class="asteriskField">*</span> </label> <input type="email" name="login" placeholder="Email address" autocomplete="email" maxlength="320" class="emailinput form-control is-invalid" required aria-invalid="true" id="id_login"> <p id="error_1_id_login" class="invalid-feedback"><strong>This field is required.</strong></p> </div> <div id="div_id_password" class="mb-3"> <label
234+
Email<span class="asteriskField">*</span> </label> <input type="email" name="login" placeholder="Email address" autocomplete="email" maxlength="320" class="emailinput form-control is-invalid" required aria-invalid="true" aria-describedby="id_login_error" id="id_login"> <div id="id_login_error"class="invalid-feedback"> <p id="error_1_id_login"><strong>This field is required.</strong></p> </div> </div> <div id="div_id_password" class="mb-3"> <label
235235
for="id_password" class="form-label requiredField">
236236
Password<span class="asteriskField">*</span> </label> <input type="password" name="password" placeholder="Password" autocomplete="current-password" class="passwordinput form-control" required aria-describedby="id_password_helptext" id="id_password"> <div id="id_password_helptext" class="form-text"><a href="/accounts/password/reset/">Forgot your password?</a></div> </div> <div class="mb-3"> <div id="div_id_remember" class="form-check"> <input type="checkbox" name="remember" class="checkboxinput form-check-input" id="id_remember"> <label for="id_remember" class="form-check-label">
237237
Remember Me

0 commit comments

Comments
 (0)