Create BaseAccountFragment, which is an abstract class that encapsulates the code needed in both ImportBrainkeyFragment and CreateAccountFragment to store into the information of the created/imported user account into the database.

This commit is contained in:
Severiano Jaramillo 2019-01-08 13:27:18 -06:00
parent 64d30f42ab
commit 860947b351
2 changed files with 98 additions and 89 deletions

View file

@ -0,0 +1,95 @@
package cy.agorise.bitsybitshareswallet.fragments
import android.preference.PreferenceManager
import androidx.navigation.fragment.findNavController
import cy.agorise.bitsybitshareswallet.database.entities.Authority
import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository
import cy.agorise.bitsybitshareswallet.repositories.UserAccountRepository
import cy.agorise.bitsybitshareswallet.utils.Constants
import cy.agorise.bitsybitshareswallet.utils.CryptoUtils
import cy.agorise.graphenej.AuthorityType
import cy.agorise.graphenej.BrainKey
import cy.agorise.graphenej.PublicKey
import cy.agorise.graphenej.models.AccountProperties
import org.bitcoinj.core.ECKey
abstract class BaseAccountFragment : ConnectedFragment() {
/** Private variable that will hold an instance of the [BrainKey] class */
protected var mBrainKey: BrainKey? = null
/**
* Method called internally once an account has been detected. This method will store internally
* the following details:
*
* - Account name in the database
* - Account authorities in the database
* - The current account id in the shared preferences
*
* @param accountProperties Account properties object
*/
protected fun onAccountSelected(accountProperties: AccountProperties, pin: String) {
val encryptedPIN = CryptoUtils.encrypt(context!!, pin)
// Stores the user selected PIN encrypted
PreferenceManager.getDefaultSharedPreferences(context!!)
.edit()
.putString(Constants.KEY_ENCRYPTED_PIN, encryptedPIN)
.apply()
// Stores the accounts this key refers to
val id = accountProperties.id
val name = accountProperties.name
val isLTM = accountProperties.membership_expiration_date == Constants.LIFETIME_EXPIRATION_DATE
val userAccount = cy.agorise.bitsybitshareswallet.database.entities.UserAccount(id, name, isLTM)
val userAccountRepository = UserAccountRepository(context!!.applicationContext)
userAccountRepository.insert(userAccount)
// Stores the id of the currently active user account
PreferenceManager.getDefaultSharedPreferences(context!!).edit()
.putString(Constants.KEY_CURRENT_ACCOUNT_ID, accountProperties.id).apply()
// Trying to store all possible authorities (owner, active and memo) into the database
val ownerAuthority = accountProperties.owner
val activeAuthority = accountProperties.active
val options = accountProperties.options
for (i in 0..2) {
mBrainKey!!.sequenceNumber = i
val publicKey = PublicKey(ECKey.fromPublicOnly(mBrainKey!!.privateKey.pubKey))
if (ownerAuthority.keyAuths.keys.contains(publicKey)) {
addAuthorityToDatabase(accountProperties.id, AuthorityType.OWNER.ordinal, mBrainKey!!)
}
if (activeAuthority.keyAuths.keys.contains(publicKey)) {
addAuthorityToDatabase(accountProperties.id, AuthorityType.ACTIVE.ordinal, mBrainKey!!)
}
if (options.memoKey == publicKey) {
addAuthorityToDatabase(accountProperties.id, AuthorityType.MEMO.ordinal, mBrainKey!!)
}
}
// Send the user back to HomeFragment
findNavController().popBackStack()
}
/**
* Adds the given BrainKey encrypted as AuthorityType of userId.
*/
private fun addAuthorityToDatabase(userId: String, authorityType: Int, brainKey: BrainKey) {
val brainKeyWords = brainKey.brainKey
val wif = brainKey.walletImportFormat
val sequenceNumber = brainKey.sequenceNumber
val encryptedBrainKey = CryptoUtils.encrypt(context!!, brainKeyWords)
val encryptedSequenceNumber = CryptoUtils.encrypt(context!!, sequenceNumber.toString())
val encryptedWIF = CryptoUtils.encrypt(context!!, wif)
val authority = Authority(0, userId, authorityType, encryptedWIF, encryptedBrainKey, encryptedSequenceNumber)
val authorityRepository = AuthorityRepository(context!!)
authorityRepository.insert(authority)
}
}

View file

@ -1,23 +1,17 @@
package cy.agorise.bitsybitshareswallet.fragments package cy.agorise.bitsybitshareswallet.fragments
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.navigation.fragment.findNavController
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.afollestad.materialdialogs.list.listItemsSingleChoice
import com.jakewharton.rxbinding3.widget.textChanges import com.jakewharton.rxbinding3.widget.textChanges
import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.R
import cy.agorise.bitsybitshareswallet.database.entities.Authority
import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository
import cy.agorise.bitsybitshareswallet.repositories.UserAccountRepository
import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.utils.Constants
import cy.agorise.bitsybitshareswallet.utils.CryptoUtils
import cy.agorise.bitsybitshareswallet.utils.toast import cy.agorise.bitsybitshareswallet.utils.toast
import cy.agorise.graphenej.* import cy.agorise.graphenej.*
import cy.agorise.graphenej.api.ConnectionStatusUpdate import cy.agorise.graphenej.api.ConnectionStatusUpdate
@ -31,14 +25,11 @@ import org.bitcoinj.core.ECKey
import java.util.ArrayList import java.util.ArrayList
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class ImportBrainkeyFragment : ConnectedFragment() { class ImportBrainkeyFragment : BaseAccountFragment() {
companion object { companion object {
private const val TAG = "ImportBrainkeyActivity" private const val TAG = "ImportBrainkeyActivity"
} }
/** Private variable that will hold an instance of the [BrainKey] class */
private var mBrainKey: BrainKey? = null
/** User account associated with the key derived from the brainkey that the user just typed in */ /** User account associated with the key derived from the brainkey that the user just typed in */
private var mUserAccount: UserAccount? = null private var mUserAccount: UserAccount? = null
@ -248,7 +239,7 @@ class ImportBrainkeyFragment : ConnectedFragment() {
// If one account was selected, we keep a reference to it and // If one account was selected, we keep a reference to it and
// store the account properties // store the account properties
mUserAccount = mUserAccountCandidates!![index] mUserAccount = mUserAccountCandidates!![index]
onAccountSelected(accountPropertiesList[index]) onAccountSelected(accountPropertiesList[index], tietPin.text.toString())
} }
} }
.positiveButton(android.R.string.ok) .positiveButton(android.R.string.ok)
@ -258,7 +249,7 @@ class ImportBrainkeyFragment : ConnectedFragment() {
.cancelable(false) .cancelable(false)
.show() .show()
} else if (accountPropertiesList.size == 1) { } else if (accountPropertiesList.size == 1) {
onAccountSelected(accountPropertiesList[0]) onAccountSelected(accountPropertiesList[0], tietPin.text.toString())
} else { } else {
context?.toast(getString(R.string.error__try_again)) context?.toast(getString(R.string.error__try_again))
} }
@ -268,81 +259,4 @@ class ImportBrainkeyFragment : ConnectedFragment() {
override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) { override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) {
Log.d(TAG, "handleConnectionStatusUpdate. code: " + connectionStatusUpdate.updateCode) Log.d(TAG, "handleConnectionStatusUpdate. code: " + connectionStatusUpdate.updateCode)
} }
/**
* Method called internally once an account has been detected. This method will store internally
* the following details:
*
* - Account name in the database
* - Account authorities in the database
* - The current account id in the shared preferences
*
* @param accountProperties Account properties object
*/
private fun onAccountSelected(accountProperties: AccountProperties) {
mUserAccount!!.name = accountProperties.name
val encryptedPIN = CryptoUtils.encrypt(context!!, tietPin.text!!.toString())
// Stores the user selected PIN encrypted
PreferenceManager.getDefaultSharedPreferences(context!!)
.edit()
.putString(Constants.KEY_ENCRYPTED_PIN, encryptedPIN)
.apply()
// Stores the accounts this key refers to
val id = accountProperties.id
val name = accountProperties.name
val isLTM = accountProperties.membership_expiration_date == Constants.LIFETIME_EXPIRATION_DATE
val userAccount = cy.agorise.bitsybitshareswallet.database.entities.UserAccount(id, name, isLTM)
val userAccountRepository = UserAccountRepository(context!!.applicationContext)
userAccountRepository.insert(userAccount)
// Stores the id of the currently active user account
PreferenceManager.getDefaultSharedPreferences(context!!).edit()
.putString(Constants.KEY_CURRENT_ACCOUNT_ID, mUserAccount!!.objectId).apply()
// Trying to store all possible authorities (owner, active and memo) into the database
val ownerAuthority = accountProperties.owner
val activeAuthority = accountProperties.active
val options = accountProperties.options
for (i in 0..2) {
mBrainKey!!.sequenceNumber = i
val publicKey = PublicKey(ECKey.fromPublicOnly(mBrainKey!!.privateKey.pubKey))
if (ownerAuthority.keyAuths.keys.contains(publicKey)) {
addAuthorityToDatabase(accountProperties.id, AuthorityType.OWNER.ordinal, mBrainKey!!)
}
if (activeAuthority.keyAuths.keys.contains(publicKey)) {
addAuthorityToDatabase(accountProperties.id, AuthorityType.ACTIVE.ordinal, mBrainKey!!)
}
if (options.memoKey == publicKey) {
addAuthorityToDatabase(accountProperties.id, AuthorityType.MEMO.ordinal, mBrainKey!!)
}
}
// Send the user back to HomeFragment
findNavController().popBackStack()
}
/**
* Adds the given BrainKey encrypted as AuthorityType of userId.
*/
private fun addAuthorityToDatabase(userId: String, authorityType: Int, brainKey: BrainKey) {
val brainKeyWords = brainKey.brainKey
val wif = brainKey.walletImportFormat
val sequenceNumber = brainKey.sequenceNumber
val encryptedBrainKey = CryptoUtils.encrypt(context!!, brainKeyWords)
val encryptedSequenceNumber = CryptoUtils.encrypt(context!!, sequenceNumber.toString())
val encryptedWIF = CryptoUtils.encrypt(context!!, wif)
val authority = Authority(0, userId, authorityType, encryptedWIF, encryptedBrainKey, encryptedSequenceNumber)
val authorityRepository = AuthorityRepository(context!!)
authorityRepository.insert(authority)
}
} }