Reset realm when fail to decrypt

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2018-05-28 18:16:12 +02:00
parent 0955b57d66
commit 26dd1c1f5a
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
2 changed files with 94 additions and 18 deletions

View File

@ -20,18 +20,24 @@
(aset arr i (aget key i)))
(.-buffer arr))))
(defn realm-version
(defn unencrypted-realm?
"Detect whether there is a unencrypted version of realm by checking whether
opening realm is successful"
[file-name]
(boolean
(.schemaVersion rn-dependencies/realm file-name)))
(defn encrypted-realm-version
"Returns -1 if the file does not exists, the schema version if it successfully
decrypts it, nil otherwise."
;; We don't throw here as we want to know whether the
;; user is upgrading from an older version of the app (<= 0.9.18), in which case
;; we need to reset the database, as it was unencrypted / wallet compatibility."
[file-name encryption-key]
(if encryption-key
;; we need to try this if previous version was using unencrypted database
(try
(.schemaVersion rn-dependencies/realm file-name (to-buffer encryption-key))
(catch js/Object e
(log/info "Attempting to read encrypted file failes")))
(try
(.schemaVersion rn-dependencies/realm file-name)
(catch js/Object e
(log/info "Attempting to read unencrypted file failed")))))
(try
(.schemaVersion rn-dependencies/realm file-name (to-buffer encryption-key))
(catch js/Object e
nil)))
(defn open-realm
[options file-name encryption-key]
@ -51,14 +57,36 @@
(when realm
(.close realm)))
(defn migrate-realm [file-name schemas encryption-key]
(let [current-version (realm-version file-name encryption-key)]
(doseq [schema schemas
:when (> (:schemaVersion schema) current-version)
:let [migrated-realm (open-realm schema file-name encryption-key)]]
(close migrated-realm)))
(defn reset-realm
"Delete realm & open a new database using encryption key"
[file-name schemas encryption-key]
(delete-realm file-name)
(open-realm (last schemas) file-name encryption-key))
(defn- migrate-schemas
"Apply migrations in sequence and open database with the last schema"
[file-name schemas encryption-key current-version]
(doseq [schema schemas
:when (> (:schemaVersion schema) current-version)
:let [migrated-realm (open-realm schema file-name encryption-key)]]
(close migrated-realm))
(open-realm (last schemas) file-name encryption-key))
(defn migrate-realm
"Migrate realm if is a compatible version or reset the database"
[file-name schemas encryption-key]
(let [encrypted-version (encrypted-realm-version file-name encryption-key)
;; If it's unencrypted reset schema
unencrypted? (and (not encrypted-version)
(unencrypted-realm? file-name))]
(cond
;; -1 if it's a new installation, n if encrypted and existing
encrypted-version (migrate-schemas file-name schemas encryption-key encrypted-version)
unencrypted? (do
(utils/show-popup "Important: Wallet Upgrade" "The Status Wallet will be upgraded in this release. The 12 mnemonic words will generate different addresses and whisper identities (public key). Given that we changed the algorithm used to generate keys and addresses, it will be impossible to re-import accounts created with the old algorithm in Status. Please create a new account.")
(reset-realm file-name schemas encryption-key)
(migrate-realm file-name schemas encryption-key)))))
(defn open-migrated-realm
[file-name schemas encryption-key]
(migrate-realm file-name schemas encryption-key))

View File

@ -1,7 +1,55 @@
(ns status-im.test.data-store.realm.core
(:require [cljs.test :refer-macros [deftest is testing]]
(:require [cljs.test :refer-macros [deftest is testing use-fixtures]]
[status-im.utils.utils :as utils]
[status-im.data-store.realm.core :as core]))
(def showed-popup? (atom nil))
(def resetted-realm? (atom nil))
(def migrated-realm? (atom nil))
(defn fixtures [f]
(reset! showed-popup? nil)
(reset! resetted-realm? nil)
(reset! migrated-realm? nil)
(f))
(use-fixtures :each fixtures)
(deftest migrate-realm
(with-redefs [core/reset-realm #(reset! resetted-realm? true)
utils/show-popup #(reset! showed-popup? true)
core/open-realm #(reset! migrated-realm? true)]
(testing "the database does not exists"
(with-redefs [core/encrypted-realm-version (constantly -1)]
(core/migrate-realm "test-filename" [] "encryption-key")
(testing "it does not reset realm"
(is (not @resetted-realm?)))
(testing "it does not show a popup"
(is (not @showed-popup?)))
(testing "it migrates the db"
(is @migrated-realm?))))
(testing "the database exists"
(with-redefs [core/encrypted-realm-version (constantly 2)]
(core/migrate-realm "test-filename" [] "encryption-key")
(testing "it does not reset realm"
(is (not @resetted-realm?)))
(testing "it does not show a popup"
(is (not @showed-popup?)))
(testing "it migrates the db"
(is @migrated-realm?))))
(testing "the database exists, but is unencrypted"
(with-redefs [core/encrypted-realm-version #(if @resetted-realm?
-1
nil)
core/unencrypted-realm? (constantly true)]
(core/migrate-realm "test-filename" [] "encryption-key")
(testing "it resets realm"
(is @resetted-realm?))
(testing "it shows a popup"
(is @showed-popup?))
(testing "it migrates the db"
(is @migrated-realm?))))))
(deftest serialization
(is (nil? (core/deserialize "")))
(is (nil? (core/deserialize "giberrish")))