mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Compare commits
14 Commits
release-1.
...
sqlite-jdb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a872851a78 | ||
|
|
f3050f9fb8 | ||
|
|
a3ba1ac91e | ||
|
|
0ac4b5c613 | ||
|
|
f4425acfaf | ||
|
|
7b65c63bc9 | ||
|
|
bf2de56abe | ||
|
|
8d7ac49bff | ||
|
|
9b2c8b0f98 | ||
|
|
b7c0bc468f | ||
|
|
852f3fd78b | ||
|
|
6734284585 | ||
|
|
87ef5e58ee | ||
|
|
b8b5e6c201 |
@@ -104,3 +104,12 @@ mailbox integration test:
|
|||||||
script:
|
script:
|
||||||
- (cd briar-mailbox; git fetch; git reset --hard origin/main)
|
- (cd briar-mailbox; git fetch; git reset --hard origin/main)
|
||||||
- MAILBOX_INTEGRATION_TESTS=true ./gradlew --info mailbox-integration-tests:test
|
- MAILBOX_INTEGRATION_TESTS=true ./gradlew --info mailbox-integration-tests:test
|
||||||
|
|
||||||
|
db_performance_comparison_test:
|
||||||
|
extends: .base-test
|
||||||
|
stage: optional_tests
|
||||||
|
script:
|
||||||
|
- OPTIONAL_TESTS=org.briarproject.bramble.db.H2SqliteDatabasePerformanceComparisonTest ./gradlew --info -Djava.security.egd=file:/dev/urandom :bramble-core:test --tests H2SqliteDatabasePerformanceComparisonTest
|
||||||
|
rules:
|
||||||
|
- when: manual
|
||||||
|
|
||||||
|
|||||||
1
bramble-android/.gitignore
vendored
1
bramble-android/.gitignore
vendored
@@ -4,3 +4,4 @@ build
|
|||||||
.settings
|
.settings
|
||||||
src/main/res/raw/*.zip
|
src/main/res/raw/*.zip
|
||||||
src/main/jniLibs
|
src/main/jniLibs
|
||||||
|
!src/main/jniLibs/.gitkeep
|
||||||
@@ -11,6 +11,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
// FIXME: sqlite-jdbc-crypt uses __register_atfork which is only available on API >= 23.
|
||||||
|
// We might be able to solve this by recompiling (or asking upstream to recompile)
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 10506
|
versionCode 10506
|
||||||
@@ -37,6 +39,7 @@ android {
|
|||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
tor
|
tor
|
||||||
|
sqliteJdbcCrypt
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -57,6 +60,8 @@ dependencies {
|
|||||||
tor "org.briarproject:obfs4proxy-android:$obfs4proxy_version"
|
tor "org.briarproject:obfs4proxy-android:$obfs4proxy_version"
|
||||||
tor "org.briarproject:snowflake-android:$snowflake_version"
|
tor "org.briarproject:snowflake-android:$snowflake_version"
|
||||||
|
|
||||||
|
sqliteJdbcCrypt "io.github.willena:sqlite-jdbc:$sqlite_jdbc_crypt_version"
|
||||||
|
|
||||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||||
|
|
||||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||||
@@ -69,26 +74,50 @@ dependencies {
|
|||||||
testImplementation "org.jmock:jmock-imposters:$jmock_version"
|
testImplementation "org.jmock:jmock-imposters:$jmock_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
def torLibsDir = 'src/main/jniLibs'
|
def jniLibsDir = 'src/main/jniLibs'
|
||||||
|
|
||||||
task cleanTorBinaries {
|
task cleanJniLibs {
|
||||||
outputs.dir torLibsDir
|
inputs.dir jniLibsDir
|
||||||
|
outputs.dir jniLibsDir
|
||||||
doLast {
|
doLast {
|
||||||
delete fileTree(torLibsDir)
|
delete fileTree(jniLibsDir).filter { it.name.endsWith('.so') }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clean.dependsOn cleanTorBinaries
|
clean.dependsOn cleanJniLibs
|
||||||
|
|
||||||
task unpackTorBinaries {
|
task unpackJniLibs {
|
||||||
outputs.dir torLibsDir
|
outputs.dir jniLibsDir
|
||||||
doLast {
|
doLast {
|
||||||
|
// Tor
|
||||||
copy {
|
copy {
|
||||||
from configurations.tor.collect { zipTree(it) }
|
from configurations.tor.collect { zipTree(it) }
|
||||||
into torLibsDir
|
into jniLibsDir
|
||||||
|
}
|
||||||
|
// sqlite-jdbc-crypt
|
||||||
|
def archMap = [
|
||||||
|
aarch64: 'arm64-v8a',
|
||||||
|
arm : 'armeabi-v7a',
|
||||||
|
x86 : 'x86',
|
||||||
|
x86_64 : 'x86_64'
|
||||||
|
]
|
||||||
|
configurations.sqliteJdbcCrypt.collect { File artifact ->
|
||||||
|
zipTree(artifact).each { File f ->
|
||||||
|
for (String arch : archMap.keySet()) {
|
||||||
|
if (f.absolutePath.endsWith("/Linux-Android/$arch/libsqlitejdbc.so")) {
|
||||||
|
def archDir = new File(jniLibsDir, archMap.get(arch))
|
||||||
|
archDir.mkdirs()
|
||||||
|
copy {
|
||||||
|
from f
|
||||||
|
into archDir
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependsOn cleanTorBinaries
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependsOn cleanJniLibs
|
||||||
}
|
}
|
||||||
|
|
||||||
preBuild.dependsOn unpackTorBinaries
|
preBuild.dependsOn unpackJniLibs
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
-dontwarn org.h2.**
|
-dontwarn org.h2.**
|
||||||
-dontnote org.h2.**
|
-dontnote org.h2.**
|
||||||
|
|
||||||
|
# Keep sqlite-jdbc-crypt classes that are loaded via reflection or accessed via JNI
|
||||||
|
-keep class org.sqlite.** { *; }
|
||||||
|
|
||||||
-keep class dagger.** { *; }
|
-keep class dagger.** { *; }
|
||||||
-dontwarn dagger.**
|
-dontwarn dagger.**
|
||||||
-dontnote dagger.**
|
-dontnote dagger.**
|
||||||
|
|||||||
0
bramble-android/src/main/jniLibs/.gitkeep
Normal file
0
bramble-android/src/main/jniLibs/.gitkeep
Normal file
@@ -18,6 +18,7 @@ dependencyVerification {
|
|||||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||||
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
|
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
|
||||||
|
'io.github.willena:sqlite-jdbc:3.41.2.1:sqlite-jdbc-3.41.2.1.jar:fb60e7137c1791db89240701338d31ca42a0bec5508c1aab1c1131cf885f2309',
|
||||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||||
@@ -38,10 +39,10 @@ dependencyVerification {
|
|||||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||||
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
|
'org.jacoco:org.jacoco.agent:0.8.8:org.jacoco.agent-0.8.8.jar:072ecbd496896623899a696fff12c01c1615f737616d2792e6d0e10cdf8a610d',
|
||||||
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
|
'org.jacoco:org.jacoco.ant:0.8.8:org.jacoco.ant-0.8.8.jar:02e33bd2c48dc0be67c2fea84d43beececfd400da6797c58153253d4c30aca15',
|
||||||
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
|
'org.jacoco:org.jacoco.core:0.8.8:org.jacoco.core-0.8.8.jar:474c782f809d88924713dfdbf0acb79d330f904be576484803463d0465611643',
|
||||||
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
|
'org.jacoco:org.jacoco.report:0.8.8:org.jacoco.report-0.8.8.jar:2c129110f3e3fcaa1f8179578ea3894586199cb0826be5c7790278084c9622a9',
|
||||||
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0:kotlin-stdlib-common-1.8.0.jar:78ef93b59e603cc0fe51def9bd4c037b07cbace3b3b7806d1a490a42bc1f4cb2',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0:kotlin-stdlib-common-1.8.0.jar:78ef93b59e603cc0fe51def9bd4c037b07cbace3b3b7806d1a490a42bc1f4cb2',
|
||||||
@@ -58,10 +59,10 @@ dependencyVerification {
|
|||||||
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
||||||
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
||||||
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
|
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
|
||||||
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
|
'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
|
||||||
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
|
'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
|
||||||
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
|
'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
|
||||||
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
|
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
|
||||||
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ dependencies {
|
|||||||
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
||||||
//noinspection GradleDependency
|
//noinspection GradleDependency
|
||||||
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
|
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
|
||||||
|
implementation "io.github.willena:sqlite-jdbc:$sqlite_jdbc_crypt_version"
|
||||||
implementation 'org.bitlet:weupnp:0.1.4'
|
implementation 'org.bitlet:weupnp:0.1.4'
|
||||||
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
||||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||||
|
|||||||
@@ -413,6 +413,9 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Collection<MessageId> getMessageIds(T txn, GroupId g) throws DbException;
|
Collection<MessageId> getMessageIds(T txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
|
Collection<String> explainGetMessageIds(T txn, GroupId g)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IDs of any delivered messages in the given group with
|
* Returns the IDs of any delivered messages in the given group with
|
||||||
* metadata that matches all entries in the given query. If the query is
|
* metadata that matches all entries in the given query. If the query is
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class DatabaseModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
Database<Connection> provideDatabase(DatabaseConfig config,
|
Database<Connection> provideDatabase(DatabaseConfig config,
|
||||||
MessageFactory messageFactory, Clock clock) {
|
MessageFactory messageFactory, Clock clock) {
|
||||||
return new H2Database(config, messageFactory, clock);
|
return new SqliteDatabase(config, messageFactory, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -4,14 +4,16 @@ class DatabaseTypes {
|
|||||||
|
|
||||||
private final String hashType, secretType, binaryType;
|
private final String hashType, secretType, binaryType;
|
||||||
private final String counterType, stringType;
|
private final String counterType, stringType;
|
||||||
|
private final String explainCommand; // FIXME: Remove
|
||||||
|
|
||||||
public DatabaseTypes(String hashType, String secretType, String binaryType,
|
public DatabaseTypes(String hashType, String secretType, String binaryType,
|
||||||
String counterType, String stringType) {
|
String counterType, String stringType, String explainCommand) {
|
||||||
this.hashType = hashType;
|
this.hashType = hashType;
|
||||||
this.secretType = secretType;
|
this.secretType = secretType;
|
||||||
this.binaryType = binaryType;
|
this.binaryType = binaryType;
|
||||||
this.counterType = counterType;
|
this.counterType = counterType;
|
||||||
this.stringType = stringType;
|
this.stringType = stringType;
|
||||||
|
this.explainCommand = explainCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,6 +24,7 @@ class DatabaseTypes {
|
|||||||
* <li> _BINARY
|
* <li> _BINARY
|
||||||
* <li> _COUNTER
|
* <li> _COUNTER
|
||||||
* <li> _STRING
|
* <li> _STRING
|
||||||
|
* <li> _EXPLAIN
|
||||||
*/
|
*/
|
||||||
String replaceTypes(String s) {
|
String replaceTypes(String s) {
|
||||||
s = s.replaceAll("_HASH", hashType);
|
s = s.replaceAll("_HASH", hashType);
|
||||||
@@ -29,6 +32,7 @@ class DatabaseTypes {
|
|||||||
s = s.replaceAll("_BINARY", binaryType);
|
s = s.replaceAll("_BINARY", binaryType);
|
||||||
s = s.replaceAll("_COUNTER", counterType);
|
s = s.replaceAll("_COUNTER", counterType);
|
||||||
s = s.replaceAll("_STRING", stringType);
|
s = s.replaceAll("_STRING", stringType);
|
||||||
|
s = s.replaceAll("_EXPLAIN", explainCommand);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,13 @@ class H2Database extends JdbcDatabase {
|
|||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT";
|
private static final String COUNTER_TYPE =
|
||||||
|
"INT NOT NULL AUTO_INCREMENT PRIMARY KEY";
|
||||||
private static final String STRING_TYPE = "VARCHAR";
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
|
private static final String EXPLAIN_COMMAND = "EXPLAIN";
|
||||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
|
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
|
||||||
|
EXPLAIN_COMMAND);
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseConfig config;
|
||||||
private final String url;
|
private final String url;
|
||||||
@@ -73,7 +76,7 @@ class H2Database extends JdbcDatabase {
|
|||||||
boolean reopen = isNonEmptyDirectory(dir);
|
boolean reopen = isNonEmptyDirectory(dir);
|
||||||
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
||||||
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
||||||
super.open("org.h2.Driver", reopen, key, listener);
|
super.open("org.h2.Driver", reopen, false, key, listener);
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Contents of account directory after opening DB:");
|
LOG.info("Contents of account directory after opening DB:");
|
||||||
logFileOrDir(LOG, INFO, dir.getParentFile());
|
logFileOrDir(LOG, INFO, dir.getParentFile());
|
||||||
|
|||||||
@@ -38,11 +38,13 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
private static final String COUNTER_TYPE =
|
private static final String COUNTER_TYPE = "INTEGER NOT NULL"
|
||||||
"INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1)";
|
+ " PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1)";
|
||||||
private static final String STRING_TYPE = "VARCHAR";
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
|
private static final String EXPLAIN_COMMAND = "EXPLAIN PLAN FOR";
|
||||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
|
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
|
||||||
|
EXPLAIN_COMMAND);
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseConfig config;
|
||||||
private final String url;
|
private final String url;
|
||||||
@@ -70,7 +72,7 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
boolean reopen = isNonEmptyDirectory(dir);
|
boolean reopen = isNonEmptyDirectory(dir);
|
||||||
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
||||||
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
||||||
super.open("org.hsqldb.jdbc.JDBCDriver", reopen, key, listener);
|
super.open("org.hsqldb.jdbc.JDBCDriver", reopen, true, key, listener);
|
||||||
return reopen;
|
return reopen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,8 +143,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " handshakePublicKey _BINARY," // Null if key is unknown
|
+ " handshakePublicKey _BINARY," // Null if key is unknown
|
||||||
+ " localAuthorId _HASH NOT NULL,"
|
+ " localAuthorId _HASH NOT NULL,"
|
||||||
+ " verified BOOLEAN NOT NULL,"
|
+ " verified BOOLEAN NOT NULL,"
|
||||||
+ " syncVersions _BINARY DEFAULT '00' NOT NULL,"
|
+ " syncVersions _BINARY DEFAULT x'00' NOT NULL,"
|
||||||
+ " PRIMARY KEY (contactId),"
|
|
||||||
+ " FOREIGN KEY (localAuthorId)"
|
+ " FOREIGN KEY (localAuthorId)"
|
||||||
+ " REFERENCES localAuthors (authorId)"
|
+ " REFERENCES localAuthors (authorId)"
|
||||||
+ " ON DELETE CASCADE)";
|
+ " ON DELETE CASCADE)";
|
||||||
@@ -295,11 +294,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " active BOOLEAN NOT NULL,"
|
+ " active BOOLEAN NOT NULL,"
|
||||||
+ " rootKey _SECRET," // Null for rotation keys
|
+ " rootKey _SECRET," // Null for rotation keys
|
||||||
+ " alice BOOLEAN," // Null for rotation keys
|
+ " alice BOOLEAN," // Null for rotation keys
|
||||||
+ " PRIMARY KEY (transportId, keySetId),"
|
// FIXME: Primary key has changed, migration needed
|
||||||
+ " FOREIGN KEY (transportId)"
|
+ " FOREIGN KEY (transportId)"
|
||||||
+ " REFERENCES transports (transportId)"
|
+ " REFERENCES transports (transportId)"
|
||||||
+ " ON DELETE CASCADE,"
|
+ " ON DELETE CASCADE,"
|
||||||
+ " UNIQUE (keySetId),"
|
// FIXME: Unique constraint removed, migration needed
|
||||||
+ " FOREIGN KEY (contactId)"
|
+ " FOREIGN KEY (contactId)"
|
||||||
+ " REFERENCES contacts (contactId)"
|
+ " REFERENCES contacts (contactId)"
|
||||||
+ " ON DELETE CASCADE,"
|
+ " ON DELETE CASCADE,"
|
||||||
@@ -358,6 +357,85 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
"CREATE INDEX IF NOT EXISTS messagesByCleanupDeadline"
|
"CREATE INDEX IF NOT EXISTS messagesByCleanupDeadline"
|
||||||
+ " ON messages (cleanupDeadline)";
|
+ " ON messages (cleanupDeadline)";
|
||||||
|
|
||||||
|
// FIXME: Migration needs to add new index
|
||||||
|
private static final String INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID_KEY_SET_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByTransportIdKeySetId"
|
||||||
|
+ " ON outgoingKeys (transportId, keySetId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_CONTACTS_BY_LOCAL_AUTHOR_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS contactsByLocalAuthorId"
|
||||||
|
+ " ON contacts (localAuthorId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_GROUP_METADATA_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS groupMetadataByGroupId"
|
||||||
|
+ " ON groupMetadata (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_GROUP_VISIBILITIES_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS groupVisibilitiesByContactId"
|
||||||
|
+ " ON groupVisibilities (contactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_GROUP_VISIBILITIES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS groupVisibilitiesByGroupId"
|
||||||
|
+ " ON groupVisibilities (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messagesByGroupId"
|
||||||
|
+ " ON messages (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGE_METADATA_BY_MESSAGE_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageMetadataByMessageId"
|
||||||
|
+ " ON messageMetadata (messageId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGE_METADATA_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageMetadataByGroupId"
|
||||||
|
+ " ON messageMetadata (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageDependenciesByGroupId"
|
||||||
|
+ " ON messageDependencies (groupId)";
|
||||||
|
|
||||||
|
private static final String
|
||||||
|
FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_MESSAGE_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageDependenciesByMessageId"
|
||||||
|
+ " ON messageDependencies (messageId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_OFFERS_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS offersByContactId"
|
||||||
|
+ " ON offers (contactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_STATUSES_BY_MESSAGE_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS statusesByMessageId"
|
||||||
|
+ " ON statuses (messageId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_STATUSES_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS statusesByContactId"
|
||||||
|
+ " ON statuses (contactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_STATUSES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS statusesByGroupId"
|
||||||
|
+ " ON statuses (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByTransportId"
|
||||||
|
+ " ON outgoingKeys (transportId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_OUTGOING_KEYS_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByContactId"
|
||||||
|
+ " ON outgoingKeys (contactId)";
|
||||||
|
|
||||||
|
private static final String
|
||||||
|
FOREIGN_INDEX_OUTGOING_KEYS_BY_PENDING_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByPendingContactId"
|
||||||
|
+ " ON outgoingKeys (pendingContactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_INCOMING_KEYS_BY_TRANSPORT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS incomingKeysByTransportId"
|
||||||
|
+ " ON incomingKeys (transportId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_INCOMING_KEYS_BY_KEY_SET_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS incomingKeysByKeySetId"
|
||||||
|
+ " ON incomingKeys (keySetId)";
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(JdbcDatabase.class.getName());
|
getLogger(JdbcDatabase.class.getName());
|
||||||
|
|
||||||
@@ -393,6 +471,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void open(String driverClass, boolean reopen,
|
protected void open(String driverClass, boolean reopen,
|
||||||
|
boolean createForeignKeyIndexes,
|
||||||
@SuppressWarnings("unused") SecretKey key,
|
@SuppressWarnings("unused") SecretKey key,
|
||||||
@Nullable MigrationListener listener) throws DbException {
|
@Nullable MigrationListener listener) throws DbException {
|
||||||
// Load the JDBC driver
|
// Load the JDBC driver
|
||||||
@@ -419,7 +498,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("db dirty? " + wasDirtyOnInitialisation);
|
LOG.info("db dirty? " + wasDirtyOnInitialisation);
|
||||||
}
|
}
|
||||||
createIndexes(txn);
|
createIndexes(txn, createForeignKeyIndexes);
|
||||||
setDirty(txn, true);
|
setDirty(txn, true);
|
||||||
commitTransaction(txn);
|
commitTransaction(txn);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -552,7 +631,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createIndexes(Connection txn) throws DbException {
|
private void createIndexes(Connection txn, boolean createForeignKeyIndexes)
|
||||||
|
throws DbException {
|
||||||
Statement s = null;
|
Statement s = null;
|
||||||
try {
|
try {
|
||||||
s = txn.createStatement();
|
s = txn.createStatement();
|
||||||
@@ -564,6 +644,31 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TX_COUNT_TIMESTAMP);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TX_COUNT_TIMESTAMP);
|
||||||
s.executeUpdate(INDEX_MESSAGES_BY_CLEANUP_DEADLINE);
|
s.executeUpdate(INDEX_MESSAGES_BY_CLEANUP_DEADLINE);
|
||||||
|
s.executeUpdate(INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID_KEY_SET_ID);
|
||||||
|
// Some DB implementations automatically create indexes on columns
|
||||||
|
// that are foreign keys, others don't
|
||||||
|
if (createForeignKeyIndexes) {
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_CONTACTS_BY_LOCAL_AUTHOR_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_GROUP_METADATA_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_GROUP_VISIBILITIES_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_GROUP_VISIBILITIES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGE_METADATA_BY_MESSAGE_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGE_METADATA_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(
|
||||||
|
FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_MESSAGE_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_OFFERS_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_STATUSES_BY_MESSAGE_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_STATUSES_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_STATUSES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_OUTGOING_KEYS_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(
|
||||||
|
FOREIGN_INDEX_OUTGOING_KEYS_BY_PENDING_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_INCOMING_KEYS_BY_TRANSPORT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_INCOMING_KEYS_BY_KEY_SET_ID);
|
||||||
|
}
|
||||||
s.close();
|
s.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s, LOG, WARNING);
|
||||||
@@ -1914,6 +2019,38 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> explainGetMessageIds(Connection txn, GroupId g)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = dbTypes.replaceTypes("_EXPLAIN SELECT messageId"
|
||||||
|
+ " FROM messages"
|
||||||
|
+ " WHERE groupId = ? AND state = ?");
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, g.getBytes());
|
||||||
|
ps.setInt(2, DELIVERED.getValue());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
int cols = rs.getMetaData().getColumnCount();
|
||||||
|
List<String> explanation = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 1; i <= cols; i++) {
|
||||||
|
sb.append(rs.getString(i)).append(' ');
|
||||||
|
}
|
||||||
|
explanation.add(sb.toString());
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return explanation;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<MessageId> getMessageIds(Connection txn, GroupId g,
|
public Collection<MessageId> getMessageIds(Connection txn, GroupId g,
|
||||||
Metadata query) throws DbException {
|
Metadata query) throws DbException {
|
||||||
@@ -2597,6 +2734,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PublicKey publicKey = new AgreementPublicKey(rs.getBytes(1));
|
PublicKey publicKey = new AgreementPublicKey(rs.getBytes(1));
|
||||||
String alias = rs.getString(2);
|
String alias = rs.getString(2);
|
||||||
long timestamp = rs.getLong(3);
|
long timestamp = rs.getLong(3);
|
||||||
|
if (rs.next()) throw new DbStateException();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
return new PendingContact(p, publicKey, alias, timestamp);
|
return new PendingContact(p, publicKey, alias, timestamp);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
|
import org.briarproject.bramble.api.db.DbClosedException;
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
import org.sqlite.mc.SQLiteMCSqlCipherConfig;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
import static org.briarproject.bramble.util.IoUtils.isNonEmptyDirectory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains all the SQLite-specific code for the database.
|
||||||
|
*/
|
||||||
|
@NotNullByDefault
|
||||||
|
class SqliteDatabase extends JdbcDatabase {
|
||||||
|
|
||||||
|
private static final Logger LOG = getLogger(SqliteDatabase.class.getName());
|
||||||
|
|
||||||
|
private static final String HASH_TYPE = "BLOB";
|
||||||
|
private static final String SECRET_TYPE = "BLOB";
|
||||||
|
private static final String BINARY_TYPE = "BLOB";
|
||||||
|
private static final String COUNTER_TYPE =
|
||||||
|
"INTEGER PRIMARY KEY AUTOINCREMENT";
|
||||||
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
|
private static final String EXPLAIN_COMMAND = "EXPLAIN QUERY PLAN";
|
||||||
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
|
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
|
||||||
|
EXPLAIN_COMMAND);
|
||||||
|
|
||||||
|
private final DatabaseConfig config;
|
||||||
|
private final String url;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile Properties properties = null;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SqliteDatabase(DatabaseConfig config, MessageFactory messageFactory,
|
||||||
|
Clock clock) {
|
||||||
|
super(dbTypes, messageFactory, clock);
|
||||||
|
this.config = config;
|
||||||
|
File dir = config.getDatabaseDirectory();
|
||||||
|
String path = new File(dir, "db").getAbsolutePath();
|
||||||
|
url = "jdbc:sqlite:" + path + "?cipher=sqlcipher";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean open(SecretKey key, @Nullable MigrationListener listener)
|
||||||
|
throws DbException {
|
||||||
|
properties = SQLiteMCSqlCipherConfig.getDefault()
|
||||||
|
.withHexKey(key.getBytes())
|
||||||
|
.build()
|
||||||
|
.toProperties();
|
||||||
|
File dir = config.getDatabaseDirectory();
|
||||||
|
boolean reopen = isNonEmptyDirectory(dir);
|
||||||
|
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
||||||
|
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
||||||
|
super.open("org.sqlite.JDBC", reopen, true, key, listener);
|
||||||
|
return reopen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws DbException {
|
||||||
|
Connection c = null;
|
||||||
|
try {
|
||||||
|
c = createConnection();
|
||||||
|
setDirty(c, false);
|
||||||
|
c.close();
|
||||||
|
closeAllConnections();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(c, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Connection createConnection() throws DbException, SQLException {
|
||||||
|
Properties properties = this.properties;
|
||||||
|
if (properties == null) throw new DbClosedException();
|
||||||
|
Connection c = DriverManager.getConnection(url, properties);
|
||||||
|
Statement s = null;
|
||||||
|
try {
|
||||||
|
s = c.createStatement();
|
||||||
|
s.execute("PRAGMA foreign_keys = ON");
|
||||||
|
s.execute("PRAGMA secure_delete = ON");
|
||||||
|
s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(s, LOG, WARNING);
|
||||||
|
tryToClose(c, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compactAndClose() throws DbException {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
public class H2SqliteDatabasePerformanceComparisonTest
|
||||||
|
extends DatabasePerformanceComparisonTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
assumeTrue(isOptionalTestEnabled(
|
||||||
|
H2SqliteDatabasePerformanceComparisonTest.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Database<Connection> createDatabase(boolean conditionA,
|
||||||
|
DatabaseConfig databaseConfig, MessageFactory messageFactory,
|
||||||
|
Clock clock) {
|
||||||
|
if (conditionA) {
|
||||||
|
return new H2Database(databaseConfig, messageFactory, clock);
|
||||||
|
} else {
|
||||||
|
return new SqliteDatabase(databaseConfig, messageFactory, clock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestName() {
|
||||||
|
return getClass().getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,14 +10,21 @@ import static org.junit.Assume.assumeTrue;
|
|||||||
|
|
||||||
public class HyperSqlDatabaseTest extends JdbcDatabaseTest {
|
public class HyperSqlDatabaseTest extends JdbcDatabaseTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
assumeTrue(isCryptoStrengthUnlimited());
|
assumeTrue(isCryptoStrengthUnlimited());
|
||||||
|
super.setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JdbcDatabase createDatabase(DatabaseConfig config,
|
protected JdbcDatabase createDatabase(DatabaseConfig config,
|
||||||
MessageFactory messageFactory, Clock clock) {
|
MessageFactory messageFactory, Clock clock) {
|
||||||
return new HyperSqlDatabase(config, messageFactory ,clock);
|
return new HyperSqlDatabase(config, messageFactory, clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testExplainGetMessageIds() {
|
||||||
|
// Ugh, HSQLDB can't handle EXPLAIN PLAN FOR in prepared statements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2500,6 +2500,21 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(NO_CLEANUP_DEADLINE, db.getNextCleanupDeadline(txn));
|
assertEquals(NO_CLEANUP_DEADLINE, db.getNextCleanupDeadline(txn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Remove
|
||||||
|
@Test
|
||||||
|
public void testExplainGetMessageIds() throws Exception {
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
db.addGroup(txn, group);
|
||||||
|
Collection<String> explanation = db.explainGetMessageIds(txn, groupId);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
|
||||||
|
System.out.println("getMessageIds(T, GroupId)");
|
||||||
|
for (String line : explanation) System.out.println(line);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
private Database<Connection> open(boolean resume) throws Exception {
|
private Database<Connection> open(boolean resume) throws Exception {
|
||||||
return open(resume, new TestMessageFactory(), new SystemClock());
|
return open(resume, new TestMessageFactory(), new SystemClock());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.isCryptoStrengthUnlimited;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
public class SqliteDatabaseTest extends JdbcDatabaseTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
assumeTrue(isCryptoStrengthUnlimited());
|
||||||
|
super.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JdbcDatabase createDatabase(DatabaseConfig config,
|
||||||
|
MessageFactory messageFactory, Clock clock) {
|
||||||
|
return new SqliteDatabase(config, messageFactory, clock);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ dependencyVerification {
|
|||||||
'com.squareup.okio:okio-jvm:3.0.0:okio-jvm-3.0.0.jar:be64a0cc1f28ea9cd5c970dd7e7557af72c808d738c495b397bf897c9921e907',
|
'com.squareup.okio:okio-jvm:3.0.0:okio-jvm-3.0.0.jar:be64a0cc1f28ea9cd5c970dd7e7557af72c808d738c495b397bf897c9921e907',
|
||||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||||
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
|
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
|
||||||
|
'io.github.willena:sqlite-jdbc:3.41.2.1:sqlite-jdbc-3.41.2.1.jar:fb60e7137c1791db89240701338d31ca42a0bec5508c1aab1c1131cf885f2309',
|
||||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||||
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
|
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
|
||||||
|
|||||||
@@ -21,22 +21,31 @@ android {
|
|||||||
|
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
doNotStrip '**/*.so'
|
doNotStrip '**/*.so'
|
||||||
|
jniLibs {
|
||||||
|
// Unpack native libs from the APK rather than using them in-place. We package the
|
||||||
|
// Tor binaries as native libs and need them to be unpacked so we can execute them
|
||||||
|
useLegacyPackaging = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
// FIXME: sqlite-jdbc-crypt uses __register_atfork which is only available on API >= 23.
|
||||||
|
// We might be able to solve this by recompiling (or asking upstream to recompile)
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 10506
|
versionCode 10506
|
||||||
versionName "1.5.6"
|
versionName "1.5.6"
|
||||||
applicationId "org.briarproject.briar.android"
|
applicationId "org.briarproject.briar.android"
|
||||||
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
|
||||||
|
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|
||||||
|
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
||||||
buildConfigField "String", "GitHash",
|
buildConfigField "String", "GitHash",
|
||||||
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
|
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
|
||||||
def now = (long) (System.currentTimeMillis() / 1000)
|
def now = (long) (System.currentTimeMillis() / 1000)
|
||||||
buildConfigField "Long", "BuildTimestamp",
|
buildConfigField "Long", "BuildTimestamp",
|
||||||
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L"
|
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L"
|
||||||
|
|
||||||
testInstrumentationRunner 'org.briarproject.briar.android.BriarTestRunner'
|
testInstrumentationRunner 'org.briarproject.briar.android.BriarTestRunner'
|
||||||
testInstrumentationRunnerArguments disableAnalytics: 'true'
|
testInstrumentationRunnerArguments disableAnalytics: 'true'
|
||||||
}
|
}
|
||||||
@@ -78,6 +87,7 @@ android {
|
|||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
}
|
}
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
@@ -97,6 +107,10 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Workaround for https://github.com/gradle/gradle/issues/20330 to make gradle-witness work
|
||||||
|
// with Android Gradle Plugin 7.4
|
||||||
|
project.evaluationDependsOn(project.getRootProject().findProject("bramble-android").getPath())
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will
|
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will
|
||||||
// complain about unresolved symbols for bramble-api test classes in briar-android tests,
|
// complain about unresolved symbols for bramble-api test classes in briar-android tests,
|
||||||
@@ -143,6 +157,8 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||||
|
|
||||||
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||||
|
|
||||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
Briar е приложение за обменяне на съобщения, предназначено за активисти, журналисти и всички други, които имат нужда от безопасен, лесен и стабилен начин за общуване. За разлика от другите подобни приложения, Briar може да използва Bluetooth или Wi-Fi, за да поддържа потока на информация по време на криза. При наличие на интернет, Briar използва мрежата на Tor и така предпазва потребителите и техните взаимоотношения от наблюдение.
|
Briar е приложение за обменяне на съобщения, предназначено за активисти, журналисти и всички други, които имат нужда от безопасен, лесен и стабилен начин за общуване. За разлика от другите подобни приложения, Briar не използва централен сървър - съобщенията се обменят между устройствата не потребителите. За да поддържа потока на информация по време на криза Briar използва Bluetooth, Wi-Fi или карти с памет. При наличие на интернет, Briar използва мрежата на Tor и така предпазва потребителите и техните взаимоотношения от наблюдение.
|
||||||
|
|
||||||
Приложението предлага лични съобщения, групи, форуми, а също и блогове. Вградена поддръжка на мрежата на Tor. Всичко, което правите в Briar се съхранява само на устройството ви, освен ако не решите да го споделите с други потребители.
|
Приложението предлага лични съобщения, групи, форуми, а също и блогове. Вградена поддръжка на мрежата на Tor. Всичко, което правите в Briar се съхранява само на устройството ви, освен ако не решите да го споделите с други потребители.
|
||||||
|
|
||||||
Няма реклами и проследяване. Изходният код на приложението е достъпен за преглед от всеки и е преминал професионален одит. Всички издания на Briar могат да бъдат пресъздадени и така може да бъде проверено, че публикувания изходен код отговаря на публикуваното тук приложение. Разработката се извършва от малък екип с нестопанска цел.
|
Няма реклами и проследяване. Изходният код на приложението е достъпен за преглед от всеки и е преминал професионален одит. Всички издания на Briar могат да бъдат пресъздадени и така може да бъде проверено, че публикувания изходен код точно отговаря на публикуваното тук приложение. Разработката се извършва от малък екип с нестопанска цел.
|
||||||
|
|
||||||
|
Политика за лични данни: https://briarproject.org/privacy
|
||||||
|
|
||||||
|
Ръководство: https://briarproject.org/manual
|
||||||
|
|
||||||
|
Изходен код: https://code.briarproject.org/briar/briar
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
Briar ist eine Messaging-App für Aktivisten, Journalisten und jeden, der eine sichere, einfache und robuste Art der Kommunikation benötigt. Im Gegensatz zu herkömmlichen Messaging-Apps benötigt Briar keinen zentralen Server. Nachrichten werden direkt zwischen den Geräten der Benutzer ausgetauscht. Wenn das Internet ausfällt, kann Briar diese auch über Bluetooth oder WLAN austauschen, um den Informationsaustausch in einer Krise aufrecht zu erhalten. Mit einer Internetverbindung kann Briar sich über das Tor-Netzwerk synchronisieren und schützt so die Nutzer und ihre Kontakte vor Überwachung.
|
Briar ist eine Messaging-App, die für Aktivisten, Journalisten und alle anderen entwickelt wurde, die eine sichere, einfache und robuste Möglichkeit zur Kommunikation benötigen. Im Gegensatz zu herkömmlichen Messaging-Apps verlässt sich Briar nicht auf einen zentralen Server - Nachrichten werden direkt zwischen den Geräten der Benutzer synchronisiert. Wenn das Internet nicht funktioniert, kann Briar über Bluetooth, WLAN oder Speicherkarten synchronisieren und so den Informationsaustausch in Krisenzeiten aufrechterhalten. Wenn das Internet verfügbar ist, kann Briar über das Tor-Netzwerk synchronisieren und Nutzer sowie ihre Kontakte vor Überwachung schützen.
|
||||||
|
|
||||||
Die App bietet private Nachrichten, Gruppen und Foren sowie Blogs. Die Unterstützung für das Tor-Netzwerk ist in die App integriert. Alles, was du in Briar machst, wird nur auf deinem Gerät gespeichert, es sei denn, du entscheidest dich, es mit anderen Benutzern zu teilen.
|
Die App bietet private Nachrichten, Gruppen und Foren sowie Blogs. Unterstützung für das Tor-Netzwerk ist in die App eingebaut. Alles, was du in Briar tust, wird nur auf deinem Gerät gespeichert, es sei denn, du entscheidest dich, es mit anderen Nutzern zu teilen.
|
||||||
|
|
||||||
Es gibt keine Werbung und kein Tracking. Der Quellcode der App ist komplett offen für jeden einsehbar und wurde bereits professionell auditiert. Alle Versionen von Briar sind reproduzierbar, so dass überprüft werden kann, ob der veröffentlichte Quellcode genau mit der hier veröffentlichten App übereinstimmt. Die Entwicklung wird von einem kleinen Non-Profit-Team durchgeführt.
|
Es gibt keine Werbung und kein Tracking. Der Quellcode der App ist vollständig offen und für jeden zur Inspektion zugänglich und wurde bereits professionell überprüft. Alle Versionen von Briar sind reproduzierbar, was es möglich macht, zu überprüfen, dass der veröffentlichte Quellcode genau mit der hier veröffentlichten App übereinstimmt. Die Entwicklung erfolgt durch ein kleines gemeinnütziges Team.
|
||||||
|
|
||||||
|
Datenschutzrichtlinien: https://briarproject.org/privacy
|
||||||
|
|
||||||
|
Benutzeranleitung: https://briarproject.org/manual
|
||||||
|
|
||||||
|
Quellcode: https://code.briarproject.org/briar/briar
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
Briar este o aplicație de mesagerie concepută pentru activiști, jurnaliști și oricine altcineva care are nevoie de o modalitate sigură, ușoară și robustă de a comunica. Spre deosebire de aplicațiile de mesagerie tradiționale, Briar nu se bazează pe un server central, ci mesajele sunt sincronizate direct între dispozitivele utilizatorilor. Dacă nu este disponibilă o conexiune la internet, Briar poate realiza sincronizarea mesajelor prin Bluetooth sau Wi-Fi, permițând schimbul de informații într-o situație de criză. Când se reface conexiunea la internet, Briar poate realiza sincronizarea prin intermediul rețelei Tor, asigurând protecția utilizatorilor și a relațiilor lor împotriva supravegherii.
|
Briar este o aplicație de mesagerie concepută pentru activiști, jurnaliști și oricine altcineva care are nevoie de o modalitate sigură, ușoară și robustă de a comunica. Spre deosebire de aplicațiile de mesagerie tradiționale, Briar nu se bazează pe un server central, ci mesajele sunt sincronizate direct între dispozitivele utilizatorilor. Dacă nu este disponibilă o conexiune la internet, Briar poate realiza sincronizarea mesajelor prin Bluetooth, Wi-Fi sau carduri de memorie, permițând schimbul de informații într-o situație de criză. Când se reface conexiunea la internet, Briar poate realiza sincronizarea prin intermediul rețelei Tor, asigurând protecția utilizatorilor și a relațiilor lor împotriva supravegherii.
|
||||||
|
|
||||||
Aplicația oferă mesaje private, grupuri și forumuri, precum și bloguri. Suportul pentru rețeaua Tor este integrat în aplicație. Tot ceea ce faceți în Briar se stochează doar pe dispozitivul dvs., cu excepția cazului în care decideți partajarea cu alți utilizatori.
|
Aplicația oferă mesaje private, grupuri și forumuri, precum și bloguri. Suportul pentru rețeaua Tor este integrat în aplicație. Tot ceea ce faceți în Briar se stochează doar pe dispozitivul dvs., cu excepția cazului în care decideți partajarea cu alți utilizatori.
|
||||||
|
|
||||||
Nu există reclame și nici urmărire. Codul sursă al aplicației este complet deschis pentru a fi inspectat de oricine și a fost deja auditat de specialiști. Toate versiunile Briar sunt reproductibile, ceea ce face posibilă verificarea potrivirii exacte a codului sursă publicat cu aplicația publicată aici. Dezvoltarea este realizată de o mică echipă non-profit.
|
Nu există reclame și nici urmărire. Codul sursă al aplicației este complet deschis pentru a fi inspectat de oricine și a fost deja auditat de specialiști. Toate versiunile Briar sunt reproductibile, ceea ce face posibilă verificarea potrivirii exacte a codului sursă publicat cu aplicația publicată aici. Dezvoltarea este realizată de o mică echipă non-profit.
|
||||||
|
|
||||||
|
Politica de intimitate: https://briarproject.org/privacy
|
||||||
|
|
||||||
|
Manualul de utilizare: https://briarproject.org/manual
|
||||||
|
|
||||||
|
Codul sursă: https://code.briarproject.org/briar/briar
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
Briar je aplikácia na zasielanie správ určená pre aktivistov, novinárov a všetkých, ktorí potrebujú bezpečný, jednoduchý a spoľahlivý spôsob komunikácie. Na rozdiel od tradičných aplikácií na zasielanie správ, Briar sa nespolieha na centrálny server - správy sa synchronizujú priamo medzi zariadeniami používateľov. Ak vypadne internet, Briar sa dokáže synchronizovať cez Bluetooth alebo Wi-Fi, čím udržiava tok informácií aj v krízových situáciách. Ak internet funguje, Briar sa môže synchronizovať cez sieť Tor, čím chráni používateľov a ich vzťahy pred sledovaním.
|
Briar je aplikácia na zasielanie správ určená pre aktivistov, novinárov a všetkých, ktorí potrebujú bezpečný, jednoduchý a spoľahlivý spôsob komunikácie. Na rozdiel od tradičných aplikácií na zasielanie správ, Briar sa nespolieha na centrálny server - správy sa synchronizujú priamo medzi zariadeniami používateľov. V prípade výpadku internetu sa Briar dokáže synchronizovať cez Bluetooth, Wi-Fi alebo pamäťové karty, čím udržiava tok informácií aj v krízových situáciách. Ak je internet v prevádzke, Briar sa môže synchronizovať prostredníctvom siete Tor, čím chráni používateľov a ich vzťahy pred sledovaním.
|
||||||
|
|
||||||
Aplikácia poskytuje súkromné správy, skupiny a fóra, ako aj blogy. V aplikácii je zabudovaná podpora siete Tor. Všetko, čo robíte v aplikácii Briar, sa ukladá len vo vašom zariadení, pokiaľ sa to nerozhodnete zdieľať s ostatnými používateľmi.
|
Aplikácia poskytuje súkromné správy, skupiny a fóra, ako aj blogy. V aplikácii je zabudovaná podpora siete Tor. Všetko, čo robíte v aplikácii Briar, sa ukladá len vo vašom zariadení, pokiaľ sa to nerozhodnete zdieľať s ostatnými používateľmi.
|
||||||
|
|
||||||
Nie sú tu žiadne reklamy ani sledovanie. Zdrojový kód aplikácie je úplne otvorený, aby si ho mohol ktokoľvek pozrieť a už bol profesionálne skontrolovaný. Všetky vydania aplikácie Briar sú reprodukovateľné, čo umožňuje overiť, či sa zverejnený zdrojový kód presne zhoduje s tu zverejnenou aplikáciou. Vývoj aplikácie vykonáva malý neziskový tím.
|
Nie sú tu žiadne reklamy ani sledovanie. Zdrojový kód aplikácie je úplne otvorený, aby si ho mohol ktokoľvek pozrieť, a už bol profesionálne skontrolovaný. Všetky vydania aplikácie Briar sú reprodukovateľné, čo umožňuje overiť, či sa zverejnený zdrojový kód presne zhoduje s touto zverejnenou aplikáciou. Vývoj vykonáva malý neziskový tím.
|
||||||
|
|
||||||
|
Zásady ochrany osobných údajov: https://briarproject.org/privacy
|
||||||
|
|
||||||
|
Používateľská príručka: https://briarproject.org/manual
|
||||||
|
|
||||||
|
Zdrojový kód: https://code.briarproject.org/briar/briar
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
Briar është një aplikacion për shkëmbim mesazhesh, i konceptuar për veprimtarë, gazetarë, dhe cilido tjetër që ka nevojë për një mënyrë të sigurt, të lehtë dhe të fuqishme komunikimi. Ndryshe nga aplikacionet tradicionale, Briar-i nuk bazohet në një shërbyes qendror - mesazhet njëkohësohen drejtpërdrejt mes pajisjeve të përdoruesve. Nëse s’ka internet, Briar-i mund të bëjë njëkohësimin me Bluetooth ose Wi-Fi, duke mbajtur kështu rrjedhën e informacioneve në rast krizash. Nëse ka Internet, Briar-i mund të bëjë njëkohësimet përmes rrjetit Tor, duke i mbrojtur përdoruesit dhe marrëdhëniet e tyre nga survejimi.
|
Briar është një aplikacion për shkëmbim mesazhesh, i konceptuar për veprimtarë, gazetarë, dhe cilido tjetër që ka nevojë për një mënyrë të sigurt, të lehtë dhe të fuqishme komunikimi. Ndryshe nga aplikacionet tradicionale, Briar-i nuk bazohet në një shërbyes qendror - mesazhet njëkohësohen drejtpërdrejt mes pajisjeve të përdoruesve. Nëse s’ka Internet, Briar-i mund të bëjë njëkohësimin me Bluetooth, Wi-Fi, ose karta kujtese, duke mbajtur kështu rrjedhën e informacioneve në rast krizash. Nëse ka Internet, Briar-i mund të bëjë njëkohësimet përmes rrjetit Tor, duke i mbrojtur përdoruesit dhe marrëdhëniet e tyre nga survejimi.
|
||||||
|
|
||||||
Aplikacioni lejon mesazhe, grupe dhe forume private, si edhe blogje. Rrjeti Tor mbulohet së brendshmi nga aplikacioni. Gjithçka që bëni në Briar depozitohet vetëm në pajisjen tuaj, veç në vendosshi ta ndani me përdorues të tjerë.
|
Aplikacioni lejon mesazhe, grupe dhe forume private, si edhe blogje. Rrjeti Tor mbulohet së brendshmi nga aplikacioni. Gjithçka që bëni në Briar depozitohet vetëm në pajisjen tuaj, veç në vendosshi ta ndani me përdorues të tjerë.
|
||||||
|
|
||||||
S’ka reklama dhe as gjurmim. Kodi burim i aplikacionit është plotësisht i lirë që ta inspektojë cilido dhe është shqyrtuar tashmë profesionalisht. Krejt hedhjet në qarkullim të Briar-it janë të riprodhueshme, duke bërë të mundur të verifikohet se kodi burim i bërë publik përputhet plotësisht me aplikacionin e publikuar këtu. Zhvillimi bëhet nga një ekip i vogël jofitimprurës.
|
S’ka reklama dhe as gjurmim. Kodi burim i aplikacionit është plotësisht i lirë që ta inspektojë cilido dhe është shqyrtuar tashmë profesionalisht. Krejt hedhjet në qarkullim të Briar-it janë të riprodhueshme, duke bërë të mundur të verifikohet se kodi burim i bërë publik përputhet saktësisht me aplikacionin e publikuar këtu. Zhvillimi bëhet nga një ekip i vogël jofitimprurës.
|
||||||
|
|
||||||
|
Rregulla privatësie: https://briarproject.org/privacy
|
||||||
|
|
||||||
|
Doracak përdoruesi: https://briarproject.org/manual
|
||||||
|
|
||||||
|
Kod burim: https://code.briarproject.org/briar/briar
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
Briar aktivistler ve gazeteciler başta olmak üzere güvenli, kolay ve sağlam bir iletişim isteyen herkes için tasarlanmış bir ileti sistemidir. Geleneksel ileti sistemlerinin aksine Briar merkezi bir sunucu kullanmaz, iletiler doğrudan kullanıcıların aygıtları arasında eşleştirilir. Briar, eğer İnternet yoksa Bluetooth veya Wi-Fi aracılığıyla da iletileri iletebilir, böylece kriz durumlarında bilgi akışını sürdürür. İnternet varken Briar Tor ağı aracılığıyla iletim sağlar, böylece kullanıcıları ve ilişkilerini gözetimden korumuş olur.
|
Briar aktivistler ve gazeteciler başta olmak üzere güvenli, kolay ve sağlam bir iletişim isteyen herkes için tasarlanmış bir ileti aktarımı sistemidir. Geleneksel ileti aktarımı sistemlerinin aksine Briar merkezi bir sunucu kullanmaz. İletiler doğrudan kullanıcıların aygıtları arasında eşleştirilir. İnternet erişimi yoksa Briar iletileri Bluetooth veya Wi-Fi üzerinden de aktarabilir ve kriz durumlarında bilgi akışını sürdürür. İnternet erişimi varken Briar iletileri Tor ağı üzerinden aktarır. Böylece kullanıcılar ve yazıştıkları kişiler izlenmekten korunmuş olur.
|
||||||
|
|
||||||
Bu uygulama özel iletiler, gruplar ve forumlarla birlikte blog özelliklerine sahiptir. Tor ağı desteği uygulamada gömülüdür. Briar üzerinde yaptığınız her şey, siz başka kullanıcılarla paylaşmayı seçmediğiniz sürece, sadece kendi aygıtınızda saklanır.
|
Bu uygulamada özel iletiler, gruplar, forumlar ve günlük özellikleri bulunur. Tor ağı desteği uygulama ile bütünleştirilmiştir. Briar üzerinde yaptığınız her şey, siz başka kullanıcılarla paylaşmayı seçmediğiniz sürece, yalnızca kendi aygıtınızda tutulur.
|
||||||
|
|
||||||
Ne reklam var, ne de sizi izleme. Uygulamanın kaynak kodu, incelemek isteyen herkese tamamen açıktır ve zaten profesyonel olarak da denetlenmiştir. Briar'ın tüm sürümleri yeniden üretilebilir, böylece yayınlanan kaynak kodun, burada yayınlanan uygulamayla tam olarak eşlendiğini doğrulamak mümkündür. Uygulama kâr amacı gütmeyen küçük bir ekip tarafından geliştirilmektedir.
|
Reklam yok, izleme yok. Uygulamanın kaynak kodu, incelemek isteyen herkese açıktır ve profesyonel uzmanlar tarafından da denetlenmiştir. Tüm Briar sürümleri yeniden üretilebilir. Böylece yayınlanmış kaynak kodunun, burada yayınlanan uygulamayla bire bir aynı olduğu doğrulanabilir. Uygulama kâr amacı gütmeyen küçük bir ekip tarafından geliştirilmektedir.
|
||||||
|
|
||||||
|
Gizlilik ilkesi: https://briarproject.org/privacy
|
||||||
|
|
||||||
|
Kullanım rehberi: https://briarproject.org/manual
|
||||||
|
|
||||||
|
Kaynak kodu: https://code.briarproject.org/briar/briar
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Güvenli mesajlaşma, nerede olursa olsun.
|
Güvenli ileti gönderimi, her yerde.
|
||||||
@@ -25,8 +25,9 @@
|
|||||||
-dontnote com.android.org.conscrypt.SSLParametersImpl
|
-dontnote com.android.org.conscrypt.SSLParametersImpl
|
||||||
-dontnote org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
|
-dontnote org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
|
||||||
-dontnote sun.security.ssl.SSLContextImpl
|
-dontnote sun.security.ssl.SSLContextImpl
|
||||||
-dontwarn org.conscrypt.OpenSSLProvider
|
-dontwarn org.bouncycastle.jsse.**
|
||||||
-dontwarn org.conscrypt.Conscrypt
|
-dontwarn org.conscrypt.**
|
||||||
|
-dontwarn org.openjsse.**
|
||||||
|
|
||||||
# HTML sanitiser
|
# HTML sanitiser
|
||||||
-keep class org.jsoup.safety.Whitelist
|
-keep class org.jsoup.safety.Whitelist
|
||||||
|
|||||||
@@ -150,7 +150,8 @@ public class AppModule {
|
|||||||
//FIXME: StrictMode
|
//FIXME: StrictMode
|
||||||
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskReads();
|
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskReads();
|
||||||
StrictMode.allowThreadDiskWrites();
|
StrictMode.allowThreadDiskWrites();
|
||||||
File dbDir = app.getApplicationContext().getDir("db", MODE_PRIVATE);
|
File dbDir = app.getApplicationContext().getDir("db_sqlite",
|
||||||
|
MODE_PRIVATE);
|
||||||
File keyDir = app.getApplicationContext().getDir("key", MODE_PRIVATE);
|
File keyDir = app.getApplicationContext().getDir("key", MODE_PRIVATE);
|
||||||
StrictMode.setThreadPolicy(tp);
|
StrictMode.setThreadPolicy(tp);
|
||||||
KeyStrengthener keyStrengthener = SDK_INT >= 23
|
KeyStrengthener keyStrengthener = SDK_INT >= 23
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ dependencyVerification {
|
|||||||
'androidx.window:window:1.0.0:window-1.0.0.aar:3212985be4127373ca4d0ea7f8b81a250ae2105e924f7940105d067a0f9ac130',
|
'androidx.window:window:1.0.0:window-1.0.0.aar:3212985be4127373ca4d0ea7f8b81a250ae2105e924f7940105d067a0f9ac130',
|
||||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||||
'com.almworks.sqlite4java:sqlite4java:1.0.392:sqlite4java-1.0.392.jar:243a64470fda0e86a6fddeb0af4c7aa9426ce84e68cbfe18d75ee5da4b7e0b92',
|
'com.almworks.sqlite4java:sqlite4java:1.0.392:sqlite4java-1.0.392.jar:243a64470fda0e86a6fddeb0af4c7aa9426ce84e68cbfe18d75ee5da4b7e0b92',
|
||||||
|
'com.android.tools:desugar_jdk_libs:2.0.3:desugar_jdk_libs-2.0.3.jar:7f4e68385dfe88eba4344ff71912912bdc731806b9b2ce4a12bef9aa6a7d4565',
|
||||||
|
'com.android.tools:desugar_jdk_libs_configuration:2.0.3:desugar_jdk_libs_configuration-2.0.3.jar:9f834a20ca4e1376522afe7bf523d3f1d5e9ad9bb0214b534ee79cc8481b4fc5',
|
||||||
'com.github.bumptech.glide:annotations:4.14.2:annotations-4.14.2.jar:8419bf262be70edeb6b9582b386546be66d2e8659c7aae65fd69a9ede02c4877',
|
'com.github.bumptech.glide:annotations:4.14.2:annotations-4.14.2.jar:8419bf262be70edeb6b9582b386546be66d2e8659c7aae65fd69a9ede02c4877',
|
||||||
'com.github.bumptech.glide:compiler:4.14.2:compiler-4.14.2.jar:315b1325283c3d0cf9bc0599c1ecdb85e5f7863b1aa25991b63d616b13930cb6',
|
'com.github.bumptech.glide:compiler:4.14.2:compiler-4.14.2.jar:315b1325283c3d0cf9bc0599c1ecdb85e5f7863b1aa25991b63d616b13930cb6',
|
||||||
'com.github.bumptech.glide:gifdecoder:4.14.2:gifdecoder-4.14.2.aar:d021eee1ac1a036fcdc377b6dc3b218f4a0cc2bc2f096d69b474198b635e8302',
|
'com.github.bumptech.glide:gifdecoder:4.14.2:gifdecoder-4.14.2.aar:d021eee1ac1a036fcdc377b6dc3b218f4a0cc2bc2f096d69b474198b635e8302',
|
||||||
@@ -148,10 +150,10 @@ dependencyVerification {
|
|||||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||||
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
|
'org.jacoco:org.jacoco.agent:0.8.8:org.jacoco.agent-0.8.8.jar:072ecbd496896623899a696fff12c01c1615f737616d2792e6d0e10cdf8a610d',
|
||||||
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
|
'org.jacoco:org.jacoco.ant:0.8.8:org.jacoco.ant-0.8.8.jar:02e33bd2c48dc0be67c2fea84d43beececfd400da6797c58153253d4c30aca15',
|
||||||
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
|
'org.jacoco:org.jacoco.core:0.8.8:org.jacoco.core-0.8.8.jar:474c782f809d88924713dfdbf0acb79d330f904be576484803463d0465611643',
|
||||||
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
|
'org.jacoco:org.jacoco.report:0.8.8:org.jacoco.report-0.8.8.jar:2c129110f3e3fcaa1f8179578ea3894586199cb0826be5c7790278084c9622a9',
|
||||||
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20:kotlin-stdlib-common-1.8.20.jar:fa20188abaa8ecf1d0035e93a969b071f10e45a1c8378c314521eade73f75fd5',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20:kotlin-stdlib-common-1.8.20.jar:fa20188abaa8ecf1d0035e93a969b071f10e45a1c8378c314521eade73f75fd5',
|
||||||
@@ -174,14 +176,10 @@ dependencyVerification {
|
|||||||
'org.mockito:mockito-core:5.1.1:mockito-core-5.1.1.jar:447bdedceaef4107c50db3d33e252bf030c6ae0e46454b40dbcfc0dfbf041264',
|
'org.mockito:mockito-core:5.1.1:mockito-core-5.1.1.jar:447bdedceaef4107c50db3d33e252bf030c6ae0e46454b40dbcfc0dfbf041264',
|
||||||
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
||||||
'org.objenesis:objenesis:3.3:objenesis-3.3.jar:02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb',
|
'org.objenesis:objenesis:3.3:objenesis-3.3.jar:02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb',
|
||||||
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
|
|
||||||
'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
|
'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
|
||||||
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
|
|
||||||
'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
|
'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
|
||||||
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
|
|
||||||
'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
|
'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
|
||||||
'org.ow2.asm:asm-util:9.2:asm-util-9.2.jar:ff5b3cd331ae8a9a804768280da98f50f424fef23dd3c788bb320e08c94ee598',
|
'org.ow2.asm:asm-util:9.2:asm-util-9.2.jar:ff5b3cd331ae8a9a804768280da98f50f424fef23dd3c788bb320e08c94ee598',
|
||||||
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
|
||||||
'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
|
'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
|
||||||
'org.robolectric:annotations:4.8.2:annotations-4.8.2.jar:998a02f2573884d017b04e1c0cc3ff3a416620daa8cc8d93d6aa15fc00b02c4b',
|
'org.robolectric:annotations:4.8.2:annotations-4.8.2.jar:998a02f2573884d017b04e1c0cc3ff3a416620daa8cc8d93d6aa15fc00b02c4b',
|
||||||
'org.robolectric:junit:4.8.2:junit-4.8.2.jar:eb0996f147566d722a178b1e1dcb849f69f5dbdd45a0149f10ce0d823b9e5a61',
|
'org.robolectric:junit:4.8.2:junit-4.8.2.jar:eb0996f147566d722a178b1e1dcb849f69f5dbdd45a0149f10ce0d823b9e5a61',
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ internal class HeadlessModule(private val appDir: File) {
|
|||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
internal fun provideDatabaseConfig(): DatabaseConfig {
|
internal fun provideDatabaseConfig(): DatabaseConfig {
|
||||||
val dbDir = File(appDir, "db")
|
val dbDir = File(appDir, "db_sqlite")
|
||||||
val keyDir = File(appDir, "key")
|
val keyDir = File(appDir, "key")
|
||||||
return HeadlessDatabaseConfig(dbDir, keyDir)
|
return HeadlessDatabaseConfig(dbDir, keyDir)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ internal class HeadlessTestModule(private val appDir: File) {
|
|||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
internal fun provideDatabaseConfig(): DatabaseConfig {
|
internal fun provideDatabaseConfig(): DatabaseConfig {
|
||||||
val dbDir = File(appDir, "db")
|
val dbDir = File(appDir, "db_sqlite")
|
||||||
val keyDir = File(appDir, "key")
|
val keyDir = File(appDir, "key")
|
||||||
return HeadlessDatabaseConfig(dbDir, keyDir)
|
return HeadlessDatabaseConfig(dbDir, keyDir)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ buildscript {
|
|||||||
jmock_version = '2.12.0'
|
jmock_version = '2.12.0'
|
||||||
mockwebserver_version = '4.10.0'
|
mockwebserver_version = '4.10.0'
|
||||||
onionwrapper_version = '0.0.5'
|
onionwrapper_version = '0.0.5'
|
||||||
|
sqlite_jdbc_crypt_version = '3.41.2.1'
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
// upgrading this let's us run into https://github.com/gradle/gradle/issues/20330
|
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
|
||||||
classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.7.0'
|
classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.7.0'
|
||||||
classpath files('libs/gradle-witness.jar')
|
classpath files('libs/gradle-witness.jar')
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|||||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
||||||
distributionSha256Sum=c9490e938b221daf0094982288e4038deed954a3f12fb54cbf270ddf4e37d879
|
distributionSha256Sum=97a52d145762adc241bad7fd18289bf7f6801e08ece6badf80402fe2b9f250b1
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
Reference in New Issue
Block a user