/** * Open a database connection to an ".anki" SQLite file. */ public DB(String ankiFilename) { SupportSQLiteOpenHelper.Configuration configuration = SupportSQLiteOpenHelper.Configuration.builder(AnkiDroidApp.getInstance()) .name(ankiFilename) .callback(getDBCallback()) .build(); SupportSQLiteOpenHelper helper = getSqliteOpenHelperFactory().create(configuration); mDatabase = helper.getWritableDatabase(); // TODO: remove this once everyone has stopped using old AnkiDroid clients with WAL (API >= 16) CompatHelper.getCompat().disableDatabaseWriteAheadLogging(mDatabase); mDatabase.query("PRAGMA synchronous = 2", null); mMod = false; }
@Test(expected = net.sqlcipher.database.SQLiteException.class) public void defaultBehavior() throws IOException { assertTrue(getDbFile().exists()); SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getReadableDatabase(); db.close(); }
@Override public void tearDownDatabase(Context ctxt, SupportSQLiteOpenHelper.Factory factory, SupportSQLiteOpenHelper helper) { String name=helper.getDatabaseName(); if (name!=null) { File db=ctxt.getDatabasePath(name); if (db.exists()) { db.delete(); } File journal=new File(db.getParentFile(), name+"-journal"); if (journal.exists()) { journal.delete(); } } } }
private void enkey(Callable<?> encrypter) throws Exception { final Context ctxt=InstrumentationRegistry.getTargetContext(); assertEquals(SQLCipherUtils.State.DOES_NOT_EXIST, SQLCipherUtils.getDatabaseState(ctxt, DB_NAME)); SQLiteDatabase plainDb= SQLiteDatabase.openOrCreateDatabase(ctxt.getDatabasePath(DB_NAME).getAbsolutePath(), null); plainDb.execSQL("CREATE TABLE foo (bar, goo);"); plainDb.execSQL("INSERT INTO foo (bar, goo) VALUES (?, ?)", new Object[] {1, "two"}); assertOriginalContent(plainDb); plainDb.close(); assertEquals(SQLCipherUtils.State.UNENCRYPTED, SQLCipherUtils.getDatabaseState(ctxt, DB_NAME)); encrypter.call(); assertEquals(SQLCipherUtils.State.ENCRYPTED, SQLCipherUtils.getDatabaseState(ctxt, DB_NAME)); SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getReadableDatabase(); assertOriginalContent(db); db.close(); }
private void dekey(Callable<?> decrypter) throws Exception { SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getWritableDatabase(); assertOriginalContent(db); db.close(); final Context ctxt=InstrumentationRegistry.getTargetContext(); decrypter.call(); SQLiteDatabase plainDb= SQLiteDatabase.openDatabase(ctxt.getDatabasePath(DB_NAME).getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE); assertOriginalContent(plainDb); plainDb.close(); }
@Test public void migrate() throws IOException { assertTrue(getDbFile().exists()); SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE), SafeHelperFactory.POST_KEY_SQL_MIGRATE); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getReadableDatabase(); assertOriginalContent(db); db.close(); // with migrate, the change should be permanent factory=SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); helper=factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); db=helper.getReadableDatabase(); assertOriginalContent(db); db.close(); }
@Test public void wal() throws IOException { SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getWritableDatabase(); assertFalse(db.isWriteAheadLoggingEnabled()); assertTrue(db.enableWriteAheadLogging()); assertTrue(db.isWriteAheadLoggingEnabled()); db.close(); factory=SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); db=helper.getWritableDatabase(); assertTrue(db.isWriteAheadLoggingEnabled()); db.disableWriteAheadLogging(); assertFalse(db.isWriteAheadLoggingEnabled()); db.close(); }
@Test public void v3() throws IOException { assertTrue(getDbFile().exists()); SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE), SafeHelperFactory.POST_KEY_SQL_V3); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getReadableDatabase(); assertOriginalContent(db); db.close(); // with v3, the change should be temporary factory=SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); helper=factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); boolean didWeGoBoom = false; try { db = helper.getReadableDatabase(); } catch (net.sqlcipher.database.SQLiteException ex) { didWeGoBoom = true; } assertTrue(didWeGoBoom); }
@Test public void rekey() throws IOException { SafeHelperFactory factory= SafeHelperFactory.fromUser(new SpannableStringBuilder("sekrit")); SupportSQLiteOpenHelper helper= factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); SupportSQLiteDatabase db=helper.getWritableDatabase(); assertOriginalContent(db); SafeHelperFactory.rekey(db, new SpannableStringBuilder(PASSPHRASE)); assertOriginalContent(db); db.execSQL("UPDATE foo SET bar=?, goo=?", new Object[] {3, "four"}); assertUpdatedContent(db); db.close(); factory=SafeHelperFactory.fromUser(new SpannableStringBuilder(PASSPHRASE)); helper=factory.create(InstrumentationRegistry.getTargetContext(), DB_NAME, new Callback(1)); db=helper.getWritableDatabase(); assertUpdatedContent(db); }
@Test public void notQuiteAsSafeButStillNice() { final Context ctxt=InstrumentationRegistry.getTargetContext(); android.database.sqlite.SQLiteOpenHelper helper = new LessSafeNonRoomHelper(ctxt); helper.getWritableDatabase(); helper.close(); ImportingLessSafeDatabase room = ImportingLessSafeDatabase.gimme(ctxt); SupportSQLiteDatabase db=room.getOpenHelper().getWritableDatabase(); try { assertTrue(db.isWriteAheadLoggingEnabled()); } finally { room.close(); } }
@Test public void safe() { final Context ctxt=InstrumentationRegistry.getTargetContext(); SQLiteDatabase.loadLibs(ctxt); SQLiteOpenHelper helper = new SafeNonRoomHelper(ctxt); helper.getWritableDatabase(PASSPHRASE); helper.close(); ImportingSafeDatabase room = ImportingSafeDatabase.gimme(ctxt); SupportSQLiteDatabase db=room.getOpenHelper().getWritableDatabase(); try { assertTrue(db.isWriteAheadLoggingEnabled()); } finally { room.close(); } }