Просмотр исходного кода

#401: custom serializer that signs bases

Rafał Pitoń 10 лет назад
Родитель
Сommit
192be4db63

+ 3 - 8
misago/acl/migrations/0003_default_roles.py

@@ -1,19 +1,14 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-import base64
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-
 from django.db import models, migrations
 from django.utils.translation import ugettext as _
 
+from misago.core import serializer
+
 
 def pickle_permissions(role, permissions):
-    role.pickled_permissions = base64.encodestring(
-        pickle.dumps(permissions, pickle.HIGHEST_PROTOCOL))
+    role.pickled_permissions = serializer.dumps(permissions)
 
 
 def create_default_roles(apps, schema_editor):

+ 5 - 10
misago/acl/models.py

@@ -1,11 +1,7 @@
-import base64
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-
 from django.db import models
 
+from misago.core import serializer
+
 from misago.acl import version as acl_version
 
 
@@ -35,8 +31,8 @@ class BaseRole(models.Model):
             return self.permissions_cache
         except AttributeError:
             try:
-                self.permissions_cache = pickle.loads(
-                    base64.decodestring(self.pickled_permissions))
+                self.permissions_cache = serializer.loads(
+                    self.pickled_permissions)
             except Exception:
                 self.permissions_cache = {}
         return self.permissions_cache
@@ -44,8 +40,7 @@ class BaseRole(models.Model):
     @permissions.setter
     def permissions(self, permissions):
         self.permissions_cache = permissions
-        self.pickled_permissions = base64.encodestring(
-            pickle.dumps(permissions, pickle.HIGHEST_PROTOCOL))
+        self.pickled_permissions = serializer.dumps(permissions)
 
 
 class Role(BaseRole):

+ 2 - 9
misago/conf/migrationutils.py

@@ -1,10 +1,4 @@
-import base64
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-from importlib import import_module
-
+from misago.core import serializer
 from misago.core.cache import cache as default_cache
 
 from misago.conf.dbsettings import CACHE_KEY
@@ -64,8 +58,7 @@ def migrate_setting(Setting, group, setting_fixture, order, old_value):
             setting.python_type, setting_fixture.get("default_value"))
 
     if field_extra:
-        pickled_extra = pickle.dumps(field_extra, pickle.HIGHEST_PROTOCOL)
-        setting.pickled_field_extra = base64.encodestring(pickled_extra)
+        setting.pickled_field_extra = serializer.dumps(field_extra)
 
     setting.save()
 

+ 4 - 9
misago/conf/models.py

@@ -1,11 +1,7 @@
-import base64
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-
 from django.db import models
 
+from misago.core import serializer
+
 from misago.conf import hydrators
 
 
@@ -86,12 +82,11 @@ class Setting(models.Model):
     @property
     def field_extra(self):
         if self.pickled_field_extra:
-            return pickle.loads(base64.decodestring(self.pickled_field_extra))
+            return serializer.loads(self.pickled_field_extra)
         else:
             return {}
 
     @field_extra.setter
     def field_extra(self, new_extra):
         if new_extra:
-            pickled_extra = pickle.dumps(new_extra, pickle.HIGHEST_PROTOCOL)
-            self.pickled_field_extra = base64.encodestring(pickled_extra)
+            self.pickled_field_extra = serializer.dumps(new_extra)

+ 28 - 0
misago/core/serializer.py

@@ -0,0 +1,28 @@
+import base64
+from hashlib import sha256
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+from django.conf import settings
+
+
+def _checksum(base):
+    return sha256('%s+%s' % (settings.SECRET_KEY, base)).hexdigest()[:14]
+
+
+def loads(dry):
+    checksum = dry[:14]
+    base = dry[14:]
+
+    if _checksum(base) == checksum:
+        return pickle.loads(base64.decodestring(base))
+    else:
+        raise ValueError("pickle checksum is invalid")
+
+
+def dumps(wet):
+    base = base64.encodestring(pickle.dumps(wet, pickle.HIGHEST_PROTOCOL))
+    checksum = _checksum(base)
+    return '%s%s' % (checksum, base)

+ 14 - 0
misago/core/tests/test_serializer.py

@@ -0,0 +1,14 @@
+from django.test import TestCase
+from misago.core import serializer
+
+
+class SerializerTests(TestCase):
+    def test_serializer(self):
+        """serializer dehydrates and hydrates values"""
+        TEST_CASES = (
+            'LoremIpsum', 123, [1, 2, '4d'], {'bawww': 'zong', 23: True}
+        )
+
+        for wet in TEST_CASES:
+            dry = serializer.dumps(wet)
+            self.assertEqual(wet, serializer.loads(dry))

+ 4 - 8
misago/forums/migrations/0003_forums_roles.py

@@ -1,18 +1,14 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-import base64
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-
 from django.db import models, migrations
 from django.utils.translation import ugettext as _
 
+from misago.core import serializer
+
+
 def pickle_permissions(role, permissions):
-    role.pickled_permissions = base64.encodestring(
-        pickle.dumps(permissions, pickle.HIGHEST_PROTOCOL))
+    role.pickled_permissions = serializer.dumps(permissions)
 
 
 def create_default_forums_roles(apps, schema_editor):