diff --git a/app/schemas/com.kunzisoft.keepass.app.database.AppDatabase/3.json b/app/schemas/com.kunzisoft.keepass.app.database.AppDatabase/3.json new file mode 100644 index 000000000..f9b3b72ef --- /dev/null +++ b/app/schemas/com.kunzisoft.keepass.app.database.AppDatabase/3.json @@ -0,0 +1,96 @@ +{ + "formatVersion": 1, + "database": { + "version": 3, + "identityHash": "a20aec7cf09664b1102ec659fa51160a", + "entities": [ + { + "tableName": "file_database_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`database_uri` TEXT NOT NULL, `database_alias` TEXT NOT NULL, `keyfile_uri` TEXT, `hardware_key` TEXT, `read_only` INTEGER, `updated` INTEGER NOT NULL, PRIMARY KEY(`database_uri`))", + "fields": [ + { + "fieldPath": "databaseUri", + "columnName": "database_uri", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "databaseAlias", + "columnName": "database_alias", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "keyFileUri", + "columnName": "keyfile_uri", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "hardwareKey", + "columnName": "hardware_key", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "readOnly", + "columnName": "read_only", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "updated", + "columnName": "updated", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "database_uri" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "cipher_database", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`database_uri` TEXT NOT NULL, `encrypted_value` TEXT NOT NULL, `specs_parameters` TEXT NOT NULL, PRIMARY KEY(`database_uri`))", + "fields": [ + { + "fieldPath": "databaseUri", + "columnName": "database_uri", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedValue", + "columnName": "encrypted_value", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "specParameters", + "columnName": "specs_parameters", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "database_uri" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a20aec7cf09664b1102ec659fa51160a')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/MainCredentialActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/MainCredentialActivity.kt index de0991f5e..8077c9b19 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/MainCredentialActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/MainCredentialActivity.kt @@ -52,6 +52,7 @@ import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.SpecialMode import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity +import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.autofill.AutofillComponent import com.kunzisoft.keepass.autofill.AutofillHelper import com.kunzisoft.keepass.biometric.DeviceUnlockFragment @@ -203,6 +204,13 @@ class MainCredentialActivity : DatabaseModeActivity() { } mForceReadOnly = databaseFileNotExists + // Restore read-only state from database file if not forced + if (!mForceReadOnly) { + databaseFile?.readOnly?.let { savedReadOnlyState -> + mReadOnly = savedReadOnlyState + } + } + invalidateOptionsMenu() // Post init uri with KeyFile only if needed @@ -702,6 +710,12 @@ class MainCredentialActivity : DatabaseModeActivity() { R.id.menu_open_file_read_mode_key -> { mReadOnly = !mReadOnly changeOpenFileReadIcon(item) + // Save the read-only state to database + mDatabaseFileUri?.let { databaseUri -> + FileDatabaseHistoryAction.getInstance(applicationContext).addOrUpdateDatabaseFile( + DatabaseFile(databaseUri = databaseUri, readOnly = mReadOnly) + ) + } } else -> MenuUtil.onDefaultMenuOptionsItemSelected(this, item) } diff --git a/app/src/main/java/com/kunzisoft/keepass/app/database/AppDatabase.kt b/app/src/main/java/com/kunzisoft/keepass/app/database/AppDatabase.kt index 16d1a190c..117e8b67a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/app/database/AppDatabase.kt +++ b/app/src/main/java/com/kunzisoft/keepass/app/database/AppDatabase.kt @@ -26,10 +26,11 @@ import android.content.Context import androidx.room.AutoMigration @Database( - version = 2, + version = 3, entities = [FileDatabaseHistoryEntity::class, CipherDatabaseEntity::class], autoMigrations = [ - AutoMigration (from = 1, to = 2) + AutoMigration (from = 1, to = 2), + AutoMigration (from = 2, to = 3) ] ) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryAction.kt b/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryAction.kt index 1818f8f6e..6f649f362 100644 --- a/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryAction.kt +++ b/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryAction.kt @@ -49,6 +49,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) { databaseUri, fileDatabaseHistoryEntity?.keyFileUri?.parseUri(), HardwareKey.getHardwareKeyFromString(fileDatabaseHistoryEntity?.hardwareKey), + fileDatabaseHistoryEntity?.readOnly, fileDatabaseHistoryEntity?.databaseUri?.decodeUri(), fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistoryEntity?.databaseAlias ?: ""), @@ -99,6 +100,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) { fileDatabaseHistoryEntity.databaseUri.parseUri(), fileDatabaseHistoryEntity.keyFileUri?.parseUri(), HardwareKey.getHardwareKeyFromString(fileDatabaseHistoryEntity.hardwareKey), + fileDatabaseHistoryEntity.readOnly, fileDatabaseHistoryEntity.databaseUri.decodeUri(), fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistoryEntity.databaseAlias), fileDatabaseInfo.exists, @@ -147,6 +149,8 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) { ?: "", databaseFileToAddOrUpdate.keyFileUri?.toString(), databaseFileToAddOrUpdate.hardwareKey?.value, + databaseFileToAddOrUpdate.readOnly + ?: fileDatabaseHistoryRetrieve?.readOnly, System.currentTimeMillis() ) @@ -168,6 +172,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) { fileDatabaseHistory.databaseUri.parseUri(), fileDatabaseHistory.keyFileUri?.parseUri(), HardwareKey.getHardwareKeyFromString(fileDatabaseHistory.hardwareKey), + fileDatabaseHistory.readOnly, fileDatabaseHistory.databaseUri.decodeUri(), fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistory.databaseAlias), fileDatabaseInfo.exists, @@ -195,6 +200,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) { fileDatabaseHistory.databaseUri.parseUri(), fileDatabaseHistory.keyFileUri?.parseUri(), HardwareKey.getHardwareKeyFromString(fileDatabaseHistory.hardwareKey), + fileDatabaseHistory.readOnly, fileDatabaseHistory.databaseUri.decodeUri(), databaseFileToDelete.databaseAlias ) diff --git a/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryEntity.kt b/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryEntity.kt index 96fd5df08..c406a7468 100644 --- a/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryEntity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/app/database/FileDatabaseHistoryEntity.kt @@ -38,6 +38,9 @@ data class FileDatabaseHistoryEntity( @ColumnInfo(name = "hardware_key") var hardwareKey: String?, + @ColumnInfo(name = "read_only") + var readOnly: Boolean?, + @ColumnInfo(name = "updated") val updated: Long ) { diff --git a/database/src/main/java/com/kunzisoft/keepass/model/DatabaseFile.kt b/database/src/main/java/com/kunzisoft/keepass/model/DatabaseFile.kt index 92470c2fe..fa2320fe9 100644 --- a/database/src/main/java/com/kunzisoft/keepass/model/DatabaseFile.kt +++ b/database/src/main/java/com/kunzisoft/keepass/model/DatabaseFile.kt @@ -6,6 +6,7 @@ import com.kunzisoft.keepass.hardware.HardwareKey data class DatabaseFile(var databaseUri: Uri? = null, var keyFileUri: Uri? = null, var hardwareKey: HardwareKey? = null, + var readOnly: Boolean? = null, var databaseDecodedPath: String? = null, var databaseAlias: String? = null, var databaseFileExists: Boolean = false,