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
import android.os.Bundle
import android.preference.PreferenceManager
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.navigation.Navigation
import androidx.navigation.fragment.findNavController
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import com.jakewharton.rxbinding3.widget.textChanges
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.CryptoUtils
import cy.agorise.bitsybitshareswallet.utils.toast
import cy.agorise.graphenej.*
import cy.agorise.graphenej.api.ConnectionStatusUpdate
@ -31,14 +25,11 @@ import org.bitcoinj.core.ECKey
import java.util.ArrayList
import java.util.concurrent.TimeUnit
class ImportBrainkeyFragment : ConnectedFragment() {
class ImportBrainkeyFragment : BaseAccountFragment() {
companion object {
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 */
private var mUserAccount: UserAccount? = null
@ -248,7 +239,7 @@ class ImportBrainkeyFragment : ConnectedFragment() {
// If one account was selected, we keep a reference to it and
// store the account properties
mUserAccount = mUserAccountCandidates!![index]
onAccountSelected(accountPropertiesList[index])
onAccountSelected(accountPropertiesList[index], tietPin.text.toString())
}
}
.positiveButton(android.R.string.ok)
@ -258,7 +249,7 @@ class ImportBrainkeyFragment : ConnectedFragment() {
.cancelable(false)
.show()
} else if (accountPropertiesList.size == 1) {
onAccountSelected(accountPropertiesList[0])
onAccountSelected(accountPropertiesList[0], tietPin.text.toString())
} else {
context?.toast(getString(R.string.error__try_again))
}
@ -268,81 +259,4 @@ class ImportBrainkeyFragment : ConnectedFragment() {
override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) {
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)
}
}