diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BaseAccountFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BaseAccountFragment.kt new file mode 100644 index 0000000..56a3fa7 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BaseAccountFragment.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ImportBrainkeyFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ImportBrainkeyFragment.kt index 7af7150..bed18e5 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ImportBrainkeyFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ImportBrainkeyFragment.kt @@ -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) - } } \ No newline at end of file