Пример #1
0
def _assert_db_is_encrypted(opts):
    """
    Assert that the sqlcipher file contains an encrypted database.

    When opening an existing database, PRAGMA key will not immediately
    throw an error if the key provided is incorrect. To test that the
    database can be successfully opened with the provided key, it is
    necessary to perform some operation on the database (i.e. read from
    it) and confirm it is success.

    The easiest way to do this is select off the sqlite_master table,
    which will attempt to read the first page of the database and will
    parse the schema.

    :param opts:
    """
    # We try to open an encrypted database with the regular u1db
    # backend should raise a DatabaseError exception.
    # If the regular backend succeeds, then we need to stop because
    # the database was not properly initialized.
    try:
        sqlite_backend.SQLitePartialExpandDatabase(opts.path)
    except sqlcipher_dbapi2.DatabaseError:
        # assert that we can access it using SQLCipher with the given
        # key
        dummy_query = ('SELECT count(*) FROM sqlite_master',)
        initialize_sqlcipher_db(opts, on_init=dummy_query)
    else:
        raise DatabaseIsNotEncrypted()
Пример #2
0
 def test_open_database_with_factory(self):
     temp_dir = self.createTempDir(prefix='u1db-test-')
     path = temp_dir + '/existing.sqlite'
     sqlite_backend.SQLitePartialExpandDatabase(path)
     db2 = sqlite_backend.SQLiteDatabase.open_database(
         path, create=False, document_factory=TestAlternativeDocument)
     self.assertEqual(TestAlternativeDocument, db2._factory)
Пример #3
0
 def test__update_indexes(self):
     self.db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
     g = self.db._parse_index_definition('fieldname')
     c = self.db._get_sqlite_handle().cursor()
     self.db._update_indexes('doc-id', {'fieldname': 'val'},
                             [('fieldname', g)], c)
     c.execute('SELECT doc_id, field_name, value FROM document_fields')
     self.assertEqual([('doc-id', 'fieldname', 'val')], c.fetchall())
Пример #4
0
 def test_open_database(self):
     tempdir = self.createTempDir()
     self.state.set_workingdir(tempdir)
     path = tempdir + '/test.db'
     self.assertFalse(os.path.exists(path))
     # Create the db, but don't do anything with it
     sqlite_backend.SQLitePartialExpandDatabase(path)
     db = self.state.open_database('test.db')
     self.assertIsInstance(db, sqlite_backend.SQLitePartialExpandDatabase)
Пример #5
0
 def test_open_existing(self):
     db = sqlite_backend.SQLitePartialExpandDatabase(self.db_path)
     self.addCleanup(db.close)
     doc = db.create_doc_from_json(tests.simple_doc)
     # Even though create=True, we shouldn't wipe the db
     db2 = u1db_open(self.db_path, create=True)
     self.addCleanup(db2.close)
     doc2 = db2.get_doc(doc.doc_id)
     self.assertEqual(doc, doc2)
Пример #6
0
 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.
             sqlite_backend.SQLitePartialExpandDatabase(sqlite_file)
             raise DatabaseIsNotEncrypted()
         except dbapi2.DatabaseError:
             pass
Пример #7
0
 def test__set_replica_uid(self):
     # Start from scratch, so that replica_uid isn't set.
     self.db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
     self.assertIsNot(None, self.db._real_replica_uid)
     self.assertIsNot(None, self.db._replica_uid)
     self.db._set_replica_uid('foo')
     c = self.db._get_sqlite_handle().cursor()
     c.execute("SELECT value FROM u1db_config WHERE name='replica_uid'")
     self.assertEqual(('foo', ), c.fetchone())
     self.assertEqual('foo', self.db._real_replica_uid)
     self.assertEqual('foo', self.db._replica_uid)
     self.db._close_sqlite_handle()
     self.assertEqual('foo', self.db._replica_uid)
Пример #8
0
    def test_check_database(self):
        tempdir = self.createTempDir()
        self.state.set_workingdir(tempdir)
        path = tempdir + '/test.db'
        self.assertFalse(os.path.exists(path))

        # doesn't exist => raises
        self.assertRaises(errors.DatabaseDoesNotExist,
                          self.state.check_database, 'test.db')

        # Create the db, but don't do anything with it
        sqlite_backend.SQLitePartialExpandDatabase(path)
        # exists => returns
        res = self.state.check_database('test.db')
        self.assertIsNone(res)
Пример #9
0
    def assert_db_is_encrypted(cls, sqlcipher_file, key, raw_key, cipher,
                               kdf_iter, cipher_page_size):
        """
        Assert that C{sqlcipher_file} contains an encrypted database.

        When opening an existing database, PRAGMA key will not immediately
        throw an error if the key provided is incorrect. To test that the
        database can be successfully opened with the provided key, it is
        necessary to perform some operation on the database (i.e. read from
        it) and confirm it is success.

        The easiest way to do this is select off the sqlite_master table,
        which will attempt to read the first page of the database and will
        parse the schema.

        :param sqlcipher_file: The path for the SQLCipher file.
        :type sqlcipher_file: str
        :param key: The key that protects the SQLCipher db.
        :type key: str
        :param raw_key: Whether C{key} is a raw 64-char hex string or a
            passphrase that should be hashed to obtain the encyrption key.
        :type raw_key: bool
        :param cipher: The cipher and mode to use.
        :type cipher: str
        :param kdf_iter: The number of iterations to use.
        :type kdf_iter: int
        :param cipher_page_size: The page size.
        :type cipher_page_size: int
        """
        try:
            # try to open an encrypted database with the regular u1db
            # backend should raise a DatabaseError exception.
            sqlite_backend.SQLitePartialExpandDatabase(sqlcipher_file)
            raise DatabaseIsNotEncrypted()
        except dbapi2.DatabaseError:
            # assert that we can access it using SQLCipher with the given
            # key
            with cls.k_lock:
                db_handle = dbapi2.connect(
                    sqlcipher_file,
                    isolation_level=SQLITE_ISOLATION_LEVEL,
                    check_same_thread=SQLITE_CHECK_SAME_THREAD)
                cls._set_crypto_pragmas(db_handle, key, raw_key, cipher,
                                        kdf_iter, cipher_page_size)
                db_handle.cursor().execute(
                    'SELECT count(*) FROM sqlite_master')
Пример #10
0
def copy_sqlite_partial_expanded_for_test(test, db):
    # DO NOT COPY OR REUSE THIS CODE OUTSIDE TESTS: COPYING U1DB DATABASES IS
    # THE WRONG THING TO DO, THE ONLY REASON WE DO SO HERE IS TO TEST THAT WE
    # CORRECTLY DETECT IT HAPPENING SO THAT WE CAN RAISE ERRORS RATHER THAN
    # CORRUPT USER DATA. USE SYNC INSTEAD, OR WE WILL SEND NINJA TO YOUR
    # HOUSE.
    new_db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
    tmpfile = StringIO()
    for line in db._db_handle.iterdump():
        if not 'sqlite_sequence' in line:  # work around bug in iterdump
            tmpfile.write('%s\n' % line)
    tmpfile.seek(0)
    new_db._db_handle = dbapi2.connect(':memory:')
    new_db._db_handle.cursor().executescript(tmpfile.read())
    new_db._db_handle.commit()
    new_db._set_replica_uid(db._replica_uid)
    new_db._factory = db._factory
    return new_db
Пример #11
0
def make_sqlite_partial_expanded_for_test(test, replica_uid):
    db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
    db._set_replica_uid(replica_uid)
    return db
Пример #12
0
 def test_open_existing_no_create(self):
     db = sqlite_backend.SQLitePartialExpandDatabase(self.db_path)
     self.addCleanup(db.close)
     db2 = u1db_open(self.db_path, create=False)
     self.addCleanup(db2.close)
     self.assertIsInstance(db2, sqlite_backend.SQLitePartialExpandDatabase)
Пример #13
0
 def test_default_replica_uid(self):
     self.db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
     self.assertIsNot(None, self.db._replica_uid)
     self.assertEqual(32, len(self.db._replica_uid))
     int(self.db._replica_uid, 16)
Пример #14
0
 def setUp(self):
     super(TestSQLitePartialExpandDatabase, self).setUp()
     self.db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
     self.db._set_replica_uid('test')
Пример #15
0
 def test_open_database_existing(self):
     temp_dir = self.createTempDir(prefix='u1db-test-')
     path = temp_dir + '/existing.sqlite'
     sqlite_backend.SQLitePartialExpandDatabase(path)
     db2 = sqlite_backend.SQLiteDatabase.open_database(path, create=False)
     self.assertIsInstance(db2, sqlite_backend.SQLitePartialExpandDatabase)
Пример #16
0
 def test__open_database(self):
     temp_dir = self.createTempDir(prefix='u1db-test-')
     path = temp_dir + '/test.sqlite'
     sqlite_backend.SQLitePartialExpandDatabase(path)
     db2 = sqlite_backend.SQLiteDatabase._open_database(path)
     self.assertIsInstance(db2, sqlite_backend.SQLitePartialExpandDatabase)
Пример #17
0
 def test__parse_index(self):
     self.db = sqlite_backend.SQLitePartialExpandDatabase(':memory:')
     g = self.db._parse_index_definition('fieldname')
     self.assertIsInstance(g, query_parser.ExtractField)
     self.assertEqual(['fieldname'], g.field)