-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9621b6e
commit 56a2ddc
Showing
3 changed files
with
91 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"<SessionNamespace({self._session[self.name]!r})>" | ||
|
||
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) |