Skip to content
This repository has been archived by the owner on Dec 17, 2020. It is now read-only.

Commit

Permalink
First test pass. PicklingError when testing with actual zodb
Browse files Browse the repository at this point in the history
  • Loading branch information
rcrafton committed Jun 27, 2008
1 parent 4d3a903 commit 1d28419
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
24 changes: 18 additions & 6 deletions src/z3c/encryptedpersistent/README.txt
@@ -1,7 +1,8 @@
---------------------
Encrypted Persistence
---------------------

This package also provides integration with persistent objects. Ususally,
This package provides integration with persistent objects. Ususally,
objects are stored in the ZODB in plain text. The ``EncryptedPersistent`` base
class ensures that all data of the class is encrypted before being stored.

Expand All @@ -12,18 +13,29 @@ class ensures that all data of the class is encrypted before being stored.
>>> myObj = MyObject()
>>> myObj.name = u'Stephan Richter'

Setup
-----

We need a utility that provides IEncryption for use with the
EncryptedPersistent object. We have defined a very simple demonstration
class that simply adds an "encryption string" to the data in order to indicate
that it has encrypted it, and removes that string to decrypt the data:

>>> from zope.app.testing import ztapi
>>> from z3c.encryptedpersistent import testing, interfaces
>>> ztapi.provideUtility(interfaces.IEncryption, testing.DemoEncrypter())


When an object is stored to a database, its ``__getstate__`` method is called:


>> myObj.__getstate__()
('key1',
"psHem+cmqG{(dp1\nS'name'\np2\nVStephan Richter\np3\nsS'__key__'\np4\nS'key1'\np5\ns.}")
>>> myObj.__getstate__()
"ENCRYPTED_(dp1\nS'name'\np2\nVStephan Richter\np3\ns."

When an object is loaded from the database, the state is passed into the
``__setstate__`` method:

>> state = myObj.__getstate__()
>>> state = myObj.__getstate__()

>>> myObj2 = MyObject()
>>> myObj2.__setstate__(state)
Expand Down Expand Up @@ -56,5 +68,5 @@ When the database is loaded again, the object's data is still there, ...

and the data is truly encrypted in the file:

>>> state[1] in open(dbFile).read()
>>> state in open(dbFile).read()
True
12 changes: 4 additions & 8 deletions src/z3c/encryptedpersistent/encryptedpersistent.py
Expand Up @@ -12,7 +12,7 @@
#
##############################################################################
"""
$Id:$
$Id$
"""
__docformat__ = "reStructuredText"

Expand All @@ -31,21 +31,17 @@ class EncryptedPersistent(persistent.Persistent):
def __getstate__(self):
# 1. Check that the key is really in the client.
encryption = zope.component.getUtility(interfaces.IEncryption)
if self.__key__ not in encryption:
raise interfaces.InvalidKey(self.__key__)
# 2. Get the state of the object using the Persistent implementation.
state = super(EncryptedPersistent, self).__getstate__()
# 3. Convert the state to a string.
stateStr = cPickle.dumps(state)
# 4. Encrypt the state string and return it as the state.
return (self.__key__, encryption[self.__key__].encrypt(stateStr))
return encryption.encrypt(stateStr)

def __setstate__(self, (key, encryptedState)):
# 1. Set the key on the object first:
self.__key__ = key
def __setstate__(self, encryptedState):
# 2. Decrypt the state string.
encryption = zope.component.getUtility(interfaces.IEncryption)
stateStr = encryption[self.__key__].decrypt(encryptedState)
stateStr = encryption.decrypt(encryptedState)
# 3. Convert the state string to the state
state = cPickle.loads(stateStr)
# 4. Set the state of the object using the Persistent implementation.
Expand Down
23 changes: 23 additions & 0 deletions src/z3c/encryptedpersistent/testing.py
@@ -0,0 +1,23 @@
##############################################################################
#
# Copyright (c) 2008 by JSA Technologies, Inc
#
##############################################################################
"""
$Id$
"""
import zope.interface

import interfaces


class DemoEncrypter(object):
zope.interface.implements(interfaces.IEncryption)

_EncryptionString = "ENCRYPTED_"

def encrypt(self, data):
return self._EncryptionString + data

def decrypt(self, data):
return data.lstrip(self._EncryptionString)

0 comments on commit 1d28419

Please sign in to comment.