From 56a2ddcb9f61d411d6a8c6f2fd153660dcded2da Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Thu, 22 Dec 2022 08:08:49 +0100 Subject: [PATCH] fix csrf error --- config/settings/base.py | 10 +++-- config/settings/staging.py | 10 ++--- lemarche/utils/sessions.py | 79 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 lemarche/utils/sessions.py diff --git a/config/settings/base.py b/config/settings/base.py index a27a91a5d..1f7471bba 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -349,9 +349,13 @@ # Security # ------------------------------------------------------------------------------ -CSRF_COOKIE_HTTPONLY = True +SESSION_SERIALIZER = "lemarche.utils.session.JSONSerializer" +CSRF_USE_SESSIONS = True -CSRF_COOKIE_SECURE = True +SECURE_CONTENT_TYPE_NOSNIFF = True + +SECURE_HSTS_SECONDS = 31536000 +SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_BROWSER_XSS_FILTER = True @@ -364,7 +368,7 @@ SECURE_SSL_REDIRECT = env.bool("SECURE_SSL_REDIRECT", False) -SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies" +# SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies" SESSION_COOKIE_HTTPONLY = True diff --git a/config/settings/staging.py b/config/settings/staging.py index 4af193419..20c47c54d 100644 --- a/config/settings/staging.py +++ b/config/settings/staging.py @@ -15,11 +15,11 @@ # for review apps ".cleverapps.io", ] -CSRF_TRUSTED_ORIGINS = [ - "https://*.inclusion.beta.gouv.fr", - "https://bitoubi-django-staging.cleverapps.io", - "https://*.cleverapps.io", -] +# CSRF_TRUSTED_ORIGINS = [ +# "https://*.inclusion.beta.gouv.fr", +# "https://bitoubi-django-staging.cleverapps.io", +# "https://*.cleverapps.io", +# ] SECURE_SSL_REDIRECT = env.bool("SECURE_SSL_REDIRECT", True) diff --git a/lemarche/utils/sessions.py b/lemarche/utils/sessions.py new file mode 100644 index 000000000..e14fdb298 --- /dev/null +++ b/lemarche/utils/sessions.py @@ -0,0 +1,79 @@ +import json +import uuid + +from django.core.exceptions import PermissionDenied + +from . import python + + +class SessionNamespace: + """Class to facilitate the usage of namespaces inside the session.""" + + NOT_SET = python.Sentinel() + + def __init__(self, session, namespace): + self._session = session + self.name = str(namespace) + + def __repr__(self): + return f"" + + def __contains__(self, item): + return item in self._session[self.name] + + def init(self, data): + self._session[self.name] = data + self._session.modified = True + + def get(self, key, default=NOT_SET): + return self._session[self.name].get(key, default) + + def set(self, key, value): + self._session[self.name][key] = value + self._session.modified = True + + def update(self, data): + self._session[self.name].update(data) + self._session.modified = True + + def exists(self): + return self.name in self._session + + def delete(self): + if not self.exists(): + return + + del self._session[self.name] + self._session.modified = True + + def save(self): + self._session.save() + + def as_dict(self): + return dict(self._session[self.name]) + + @classmethod + def create_temporary(cls, session): + return cls(session, namespace=str(uuid.uuid4())) + + +class SessionNamespaceRequiredMixin: + required_session_namespaces = [] + + def setup(self, request, *args, **kwargs): + super().setup(request, *args, **kwargs) + + if not all(getattr(self, attr_name).exists() for attr_name in self.required_session_namespaces): + raise PermissionDenied("A session namespace doesn't exist.") + + +class JSONSerializer: + """Class to be used in SESSION_SERIALIZER, so we can serialize data using our custom JSON encoder/decoder.""" + + def dumps(self, obj): + # Using latin-1 like django.contrib.sessions.serializers.JSONSerializer + return json.dumps(obj, cls=json.JSONEncoder).encode("latin-1") + + def loads(self, data): + # Using latin-1 like django.contrib.sessions.serializers.JSONSerializer + return json.loads(data.decode("latin-1"), cls=json.JSONDecoder)