Skip to content

Instantly share code, notes, and snippets.

Avatar

Daniel Ochoa shafty023

View GitHub Profile
@shafty023
shafty023 / get_storable.kt
Last active Aug 7, 2020
Retrieve Storable instance from storage
View get_storable.kt
/**
* Retrieves the [Storable] instance from prefs.
*
* @param context the caller's context
* @return the storable instance
*/
fun getStorable(context: Context): Storable? {
val prefs = context.getSharedPreferences("database",
Context.MODE_PRIVATE)
val serialized = prefs.getString("key", null)
@shafty023
shafty023 / messy_prefs.kt
Last active Jun 10, 2020
Messy preferences
View messy_prefs.kt
@Singleton
class Preferences(context: Context) {
private val prefs: SharedPreferences = context.getSharedPreferences("Prefs", Context.MODE_PRIVATE)
companion object {
const val PREF_CURRENT_STATE = "CurrentState"
const val PREF_LAST_KNOWN_ERROR = "LastKnownError"
const val PREF_LAST_ACTION_PERFORMED = "LastActionPerformed"
}
View state_machine.kt
/**
* Keeps track of current and prior application state.
*
* @param dataStore storage
*/
@Singleton
class StateMachine(private val dataStore: DataStore) {
/**
* Storage implementation for our state machine.
*
View datastore.kt
/**
* A storage implementation that enforces whole class serialization/deserialization.
*
* This enforces organization of data that needs to be persisted rather than having generic classes
* with lots of unrelated data.
*
* @param context the caller's context
*/
@Singleton
class DataStore(context: Context) {
View gson_utils.kt
/**
* A factory that can serialize/deserialize json.
*/
object GsonUtils {
/**
* Handles deserializing the json string into a [T] instance.
*
* @param json the json to deserialize into an instance of [T]
* @throws JsonSyntaxException if there is a failure deserializing then this exception is thrown
*/
View encrypted_room_db.kt
abstract class EncryptedDatabase : RoomDatabase() {
companion object {
fun getInstance(passcode: CharArray, context: Context):
EncryptedDatabase = buildDatabase(passcode, context)
private fun buildDatabase(
passcode: CharArray,
context: Context
): EncryptedDatabase {
// DatabaseKeyMgr is a singleton that all of the above code is wrapped into.
@shafty023
shafty023 / encrypt_and_store_key.kt
Last active Jun 9, 2020
Encrypt the key and store it
View encrypt_and_store_key.kt
fun persistRawKey(userPasscode: CharArray) {
val storable = toStorable(rawByteKey, userPasscode)
// Implementation explained in next step
saveToPrefs(storable)
}
/**
* Returns a [Storable] instance with the db key encrypted using PBE.
*
* @param rawDbKey the raw database key
View get_char_key.kt
/**
* Returns the database key suitable for using with Room.
*
* @param passcode the user's passcode
* @param context the caller's context
*/
fun getCharKey(passcode: CharArray, context: Context): CharArray {
if (dbCharKey == null) {
initKey(passcode, context)
}
@shafty023
shafty023 / get_raw_byte_key.kt
Created Jun 9, 2020
Decrypts the Storable instance using a passcode
View get_raw_byte_key.kt
/**
* Decrypts the [Storable] instance using the [passcode].
*
* @pararm passcode the user's passcode
* @param storable the storable instance previously saved with [saveToPrefs]
* @return the raw byte key previously generated with [generateRandomKey]
*/
fun getRawByteKey(passcode: CharArray, storable: Storable): ByteArray {
val aesWrappedKey = Base64.decode(storable.key, Base64.DEFAULT)
val iv = Base64.decode(storable.iv, Base64.DEFAULT)
@shafty023
shafty023 / save_to_prefs.kt
Created Jun 9, 2020
Persist the db key to storage
View save_to_prefs.kt
/**
* Save the storable instance to preferences.
*
* @param storable a storable instance
*/
fun saveToPrefs(context: Context, storable: Storable) {
val serialized = Gson().toJson(storable)
val prefs = context.getSharedPreferences("database",
Context.MODE_PRIVATE)
prefs.edit().putString("key", serialized).apply()
You can’t perform that action at this time.