summaryrefslogtreecommitdiff
path: root/src/leap/soledad/backends/sqlcipher.py
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2013-01-22 10:09:43 -0200
committerdrebs <drebs@leap.se>2013-01-22 10:09:43 -0200
commit3359370d9ae06ffc0d60930e7f997d2331dc9037 (patch)
tree252b348a0501976e099cc45c386d95d0a05b8367 /src/leap/soledad/backends/sqlcipher.py
parent6fb952397573f4bc90f4cd9e72b49fcf6256e95c (diff)
parent9fc4829334e337155ef49de168e492ed7cfe58d7 (diff)
Merge branch 'feature/soledad-api' into develop
Conflicts: src/leap/soledad/__init__.py src/leap/soledad/backends/couch.py src/leap/soledad/backends/leap_backend.py src/leap/soledad/backends/objectstore.py src/leap/soledad/tests/test_couch.py src/leap/soledad/tests/test_logs.py src/leap/soledad/tests/test_sqlcipher.py src/leap/soledad/util.py
Diffstat (limited to 'src/leap/soledad/backends/sqlcipher.py')
-rw-r--r--src/leap/soledad/backends/sqlcipher.py68
1 files changed, 43 insertions, 25 deletions
diff --git a/src/leap/soledad/backends/sqlcipher.py b/src/leap/soledad/backends/sqlcipher.py
index 6fd6e619..3d03449e 100644
--- a/src/leap/soledad/backends/sqlcipher.py
+++ b/src/leap/soledad/backends/sqlcipher.py
@@ -16,30 +16,21 @@
"""A U1DB implementation that uses SQLCipher as its persistence layer."""
-import errno
import os
-try:
- import simplejson as json
-except ImportError:
- import json # noqa
-from sqlite3 import dbapi2
-import sys
+from sqlite3 import dbapi2, DatabaseError
import time
-import uuid
-import pkg_resources
-
-from u1db.backends import CommonBackend, CommonSyncTarget
-from u1db.backends.sqlite_backend import SQLitePartialExpandDatabase
+from u1db.backends.sqlite_backend import (
+ SQLiteDatabase,
+ SQLitePartialExpandDatabase,
+)
from u1db import (
Document,
errors,
- query_parser,
- vectorclock,
- )
+)
-def open(path, create, document_factory=None, password=None):
+def open(path, password, create=True, document_factory=None):
"""Open a database at the given location.
Will raise u1db.errors.DatabaseDoesNotExist if create=False and the
@@ -52,11 +43,17 @@ def open(path, create, document_factory=None, password=None):
parameters as Document.__init__.
:return: An instance of Database.
"""
- from u1db.backends import sqlite_backend
- return sqlite_backend.SQLCipherDatabase.open_database(
+ return SQLCipherDatabase.open_database(
path, password, create=create, document_factory=document_factory)
+class DatabaseIsNotEncrypted(Exception):
+ """
+ Exception raised when trying to open non-encrypted databases.
+ """
+ pass
+
+
class SQLCipherDatabase(SQLitePartialExpandDatabase):
"""A U1DB implementation that uses SQLCipher as its persistence layer."""
@@ -67,14 +64,30 @@ class SQLCipherDatabase(SQLitePartialExpandDatabase):
def set_pragma_key(cls, db_handle, key):
db_handle.cursor().execute("PRAGMA key = '%s'" % key)
+
def __init__(self, sqlite_file, password, document_factory=None):
- """Create a new sqlite file."""
+ """Create a new sqlcipher file."""
+ self._check_if_db_is_encrypted(sqlite_file)
self._db_handle = dbapi2.connect(sqlite_file)
SQLCipherDatabase.set_pragma_key(self._db_handle, password)
self._real_replica_uid = None
self._ensure_schema()
self._factory = document_factory or Document
+
+ def _check_if_db_is_encrypted(self, sqlite_file):
+ if not os.path.exists(sqlite_file):
+ return
+ else:
+ try:
+ # try to open an encrypted database with the regular u1db backend
+ # should raise a DatabaseError exception.
+ SQLitePartialExpandDatabase(sqlite_file)
+ raise DatabaseIsNotEncrypted()
+ except DatabaseError:
+ pass
+
+
@classmethod
def _open_database(cls, sqlite_file, password, document_factory=None):
if not os.path.isfile(sqlite_file):
@@ -100,6 +113,7 @@ class SQLCipherDatabase(SQLitePartialExpandDatabase):
return SQLCipherDatabase._sqlite_registry[v](
sqlite_file, password, document_factory=document_factory)
+
@classmethod
def open_database(cls, sqlite_file, password, create, backend_cls=None,
document_factory=None):
@@ -115,13 +129,17 @@ class SQLCipherDatabase(SQLitePartialExpandDatabase):
return backend_cls(sqlite_file, password,
document_factory=document_factory)
- @staticmethod
- def register_implementation(klass):
- """Register that we implement an SQLCipherDatabase.
- The attribute _index_storage_value will be used as the lookup key.
+ def sync(self, url, creds=None, autocreate=True, soledad=None):
+ """
+ Synchronize encrypted documents with remote replica exposed at url.
"""
- SQLCipherDatabase._sqlite_registry[klass._index_storage_value] = klass
+ from u1db.sync import Synchronizer
+ from leap.soledad.backends.leap_backend import LeapSyncTarget
+ return Synchronizer(self, LeapSyncTarget(url, creds=creds),
+ soledad=self._soledad).sync(
+ autocreate=autocreate)
+
+SQLiteDatabase.register_implementation(SQLCipherDatabase)
-SQLCipherDatabase.register_implementation(SQLCipherDatabase)