summaryrefslogtreecommitdiffstats
path: root/accounts/utils/sessions.py
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/utils/sessions.py')
-rw-r--r--accounts/utils/sessions.py27
1 files changed, 15 insertions, 12 deletions
diff --git a/accounts/utils/sessions.py b/accounts/utils/sessions.py
index e156f0c..007c928 100644
--- a/accounts/utils/sessions.py
+++ b/accounts/utils/sessions.py
@@ -3,20 +3,21 @@
from Crypto import Random
from Crypto.Cipher import AES
-from flask import Flask
+from flask import Flask, Request
from flask.sessions import TaggedJSONSerializer, SecureCookieSessionInterface
from itsdangerous import BadPayload
+from base64 import b64encode, b64decode
from accounts.app import accounts_app
from typing import cast
-def _pad(value, block_size):
+def _pad(value: str, block_size: int) -> bytes:
padding = block_size - len(value) % block_size
return (value + (padding * chr(padding))).encode("UTF-8")
-def _unpad(value):
+def _unpad(value: str) -> str:
pad_length = ord(value[len(value)-1:])
return value[:-pad_length]
@@ -27,12 +28,12 @@ class EncryptedSerializer(TaggedJSONSerializer):
super(EncryptedSerializer, self).__init__()
self.block_size = AES.block_size
- def _cipher(self, iv):
+ def _cipher(self, iv: bytes):
key = accounts_app.config['SESSION_ENCRYPTION_KEY']
assert len(key) == 32
return AES.new(key, AES.MODE_CBC, iv)
- def dumps(self, value):
+ def dumps(self, value: str) -> str:
"""
Encrypt the serialized values with `config.SESSION_ENCRYPTION_KEY`.
The key must be 32 bytes long.
@@ -40,23 +41,25 @@ class EncryptedSerializer(TaggedJSONSerializer):
serialized_value = super(EncryptedSerializer, self).dumps(value)
raw = _pad(serialized_value, self.block_size)
- iv = Random.new().read(self.block_size)
- return iv + self._cipher(iv).encrypt(raw)
+ iv: bytes = Random.new().read(self.block_size)
+ return b64encode(iv + self._cipher(iv).encrypt(raw)).decode("UTF-8")
- def loads(self, value):
+ def loads(self, value: str):
"""
Decrypt the given serialized session data with
`config.SESSION_ENCRYPTION_KEY`.
"""
- iv = value[:self.block_size]
- raw = self._cipher(iv).decrypt(value[AES.block_size:])
- return super(EncryptedSerializer, self).loads(_unpad(raw))
+ decoded = b64decode(value.encode("UTF-8"))
+ iv = decoded[:self.block_size]
+ raw = self._cipher(iv).decrypt(decoded[AES.block_size:])
+ return super(EncryptedSerializer, self) \
+ .loads(_unpad(raw))
class EncryptedSessionInterface(SecureCookieSessionInterface):
serializer = EncryptedSerializer()
- def open_session(self, app: Flask, request):
+ def open_session(self, app: Flask, request: Request):
session = None
try:
parent = super(EncryptedSessionInterface, self)