summaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2012-12-18 18:51:01 -0200
committerdrebs <drebs@leap.se>2012-12-18 18:51:01 -0200
commit6306a61d8c6c840a09ea9aa26e439a40dc9b5a9a (patch)
tree5d63e737a7f3169f1fece8afef5d10a4a458dd0a /backends
parent2d4fc3ee887fd52ac06fdd6f99bdc4b445a79463 (diff)
Refactor and symmetric encryption
Diffstat (limited to 'backends')
-rw-r--r--backends/leap.py53
-rw-r--r--backends/objectstore.py7
2 files changed, 38 insertions, 22 deletions
diff --git a/backends/leap.py b/backends/leap.py
index ce00c8f3..4a496d3e 100644
--- a/backends/leap.py
+++ b/backends/leap.py
@@ -7,12 +7,15 @@ from u1db import Document
from u1db.remote.http_target import HTTPSyncTarget
from u1db.remote.http_database import HTTPDatabase
import base64
-from soledad import GPGWrapper
+from soledad.util import GPGWrapper
class NoDefaultKey(Exception):
pass
+class NoSoledadInstance(Exception):
+ pass
+
class LeapDocument(Document):
"""
@@ -22,41 +25,40 @@ class LeapDocument(Document):
"""
def __init__(self, doc_id=None, rev=None, json='{}', has_conflicts=False,
- encrypted_json=None, default_key=None, gpg_wrapper=None):
+ encrypted_json=None, soledad=None):
super(LeapDocument, self).__init__(doc_id, rev, json, has_conflicts)
- # we might want to get already initialized wrappers for testing.
- if gpg_wrapper is None:
- self._gpg = GPGWrapper()
- else:
- self._gpg = gpg_wrapper
+ self._soledad = soledad
if encrypted_json:
self.set_encrypted_json(encrypted_json)
- self._default_key = default_key
def get_encrypted_json(self):
"""
Returns document's json serialization encrypted with user's public key.
"""
- if self._default_key is None:
- raise NoDefaultKey()
- cyphertext = self._gpg.encrypt(self.get_json(),
- self._default_key,
- always_trust = True)
- # TODO: always trust?
- return json.dumps({'cyphertext' : str(cyphertext)})
+ if not self._soledad:
+ raise NoSoledadInstance()
+ cyphertext = self._soledad.encrypt_symmetric(self.get_json())
+ return json.dumps({'_encrypted_json' : cyphertext})
def set_encrypted_json(self, encrypted_json):
"""
Set document's content based on encrypted version of json string.
"""
- cyphertext = json.loads(encrypted_json)['cyphertext']
- plaintext = str(self._gpg.decrypt(cyphertext))
+ if not self._soledad:
+ raise NoSoledadInstance()
+ cyphertext = json.loads(encrypted_json)['_encrypted_json']
+ plaintext = self._soledad.decrypt_symmetric(cyphertext)
return self.set_json(plaintext)
class LeapDatabase(HTTPDatabase):
"""Implement the HTTP remote database API to a Leap server."""
+ def __init__(self, url, document_factory=None, creds=None, soledad=None):
+ super(LeapDatabase, self).__init__(url, creds=creds)
+ self._soledad = soledad
+ self._factory = LeapDocument
+
@staticmethod
def open_database(url, create):
db = LeapDatabase(url)
@@ -74,9 +76,21 @@ class LeapDatabase(HTTPDatabase):
st._creds = self._creds
return st
+ def create_doc_from_json(self, content, doc_id=None):
+ if doc_id is None:
+ doc_id = self._allocate_doc_id()
+ res, headers = self._request_json('PUT', ['doc', doc_id], {},
+ content, 'application/json')
+ new_doc = self._factory(doc_id, res['rev'], content, soledad=self._soledad)
+ return new_doc
+
class LeapSyncTarget(HTTPSyncTarget):
+ def __init__(self, url, creds=None, soledad=None):
+ super(LeapSyncTarget, self).__init__(url, creds)
+ self._soledad = soledad
+
def _parse_sync_stream(self, data, return_doc_cb, ensure_callback=None):
"""
Does the same as parent's method but ensures incoming content will be
@@ -97,8 +111,10 @@ class LeapSyncTarget(HTTPSyncTarget):
raise BrokenSyncStream
line, comma = utils.check_and_strip_comma(entry)
entry = json.loads(line)
+ # decrypt after receiving from server.
doc = LeapDocument(entry['id'], entry['rev'],
- encrypted_json=entry['content'])
+ encrypted_json=entry['content'],
+ soledad=self._soledad)
return_doc_cb(doc, entry['gen'], entry['trans_id'])
if parts[-1] != ']':
try:
@@ -142,6 +158,7 @@ class LeapSyncTarget(HTTPSyncTarget):
ensure=ensure_callback is not None)
comma = ','
for doc, gen, trans_id in docs_by_generations:
+ # encrypt before sending to server.
size += prepare(id=doc.doc_id, rev=doc.rev,
content=doc.get_encrypted_json(),
gen=gen, trans_id=trans_id)
diff --git a/backends/objectstore.py b/backends/objectstore.py
index 298bdda3..a8e139f7 100644
--- a/backends/objectstore.py
+++ b/backends/objectstore.py
@@ -1,8 +1,7 @@
import uuid
from u1db.backends import CommonBackend
-from u1db import errors
-from soledad import SyncLog, TransactionLog
-from soledad.backends.leap import LeapDocument
+from u1db import errors, Document
+from soledad.util import SyncLog, TransactionLog
class ObjectStore(CommonBackend):
@@ -11,7 +10,7 @@ class ObjectStore(CommonBackend):
# This initialization method should be called after the connection
# with the database is established, so it can ensure that u1db data is
# configured and up-to-date.
- self.set_document_factory(LeapDocument)
+ self.set_document_factory(Document)
self._sync_log = SyncLog()
self._transaction_log = TransactionLog()
self._ensure_u1db_data()