Skip to content

Commit

Permalink
Added the token encryption when we store an access token to AccountMa…
Browse files Browse the repository at this point in the history
…nager. Fixed a bug of the message sending.| #716
  • Loading branch information
DenBond7 committed Aug 14, 2020
1 parent 3c9f5c2 commit 23c909b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.flowcrypt.email.BuildConfig
import com.flowcrypt.email.api.oauth.OAuth2Helper
import com.flowcrypt.email.api.retrofit.ApiHelper
import com.flowcrypt.email.api.retrofit.ApiService
import com.flowcrypt.email.security.KeyStoreCryptoManager
import com.flowcrypt.email.ui.activity.SignInActivity


Expand Down Expand Up @@ -58,13 +59,21 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe
var authToken = accountManager.peekAuthToken(account, authTokenType)

if (authToken.isNullOrEmpty()) {
val refreshToken = accountManager.getUserData(account, KEY_REFRESH_TOKEN)
val encryptedRefreshToken = accountManager.getUserData(account, KEY_REFRESH_TOKEN)
if (encryptedRefreshToken.isNullOrEmpty()) {
return Bundle().apply {
putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_BAD_ARGUMENTS)
putString(AccountManager.KEY_ERROR_MESSAGE, "Refresh token is wrong or was corrupted!")
}
}
val refreshToken = KeyStoreCryptoManager.decrypt(encryptedRefreshToken)
val apiService = ApiHelper.getInstance(context).retrofit.create(ApiService::class.java)
val apiResponse = apiService.refreshMicrosoftOAuth2Token(refreshToken).execute()
if (apiResponse.isSuccessful) {
val tokenResponse = apiResponse.body()
authToken = tokenResponse?.accessToken
accountManager.setUserData(account, KEY_REFRESH_TOKEN, tokenResponse?.refreshToken)
authToken = KeyStoreCryptoManager.encrypt(tokenResponse?.accessToken)
accountManager.setAuthToken(account, authTokenType, authToken)
accountManager.setUserData(account, KEY_REFRESH_TOKEN, KeyStoreCryptoManager.encrypt(tokenResponse?.refreshToken))
accountManager.setUserData(account, KEY_EXPIRES_AT, OAuth2Helper.getExpiresAtTime(tokenResponse?.expiresIn).toString())
} else return Bundle().apply {
putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_BAD_AUTHENTICATION)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.flowcrypt.email.api.email.JavaEmailConstants
import com.flowcrypt.email.api.email.gmail.GmailConstants
import com.flowcrypt.email.api.email.model.SecurityType
import com.flowcrypt.email.database.entity.AccountEntity
import com.flowcrypt.email.security.KeyStoreCryptoManager
import com.flowcrypt.email.util.LogsUtil
import com.google.android.gms.auth.GoogleAuthUtil
import com.sun.mail.gimap.GmailSSLStore
Expand Down Expand Up @@ -151,8 +152,13 @@ class OpenStoreHelper {
val accountManager = AccountManager.get(context)
val oauthAccount = accountManager.accounts.firstOrNull { it.name == account.email }
if (oauthAccount != null) {
accountManager.blockingGetAuthToken(oauthAccount,
val encryptedToken = accountManager.blockingGetAuthToken(oauthAccount,
FlowcryptAccountAuthenticator.AUTH_TOKEN_TYPE_EMAIL, true)
if (encryptedToken.isNullOrEmpty()) {
""//need to think about
} else {
KeyStoreCryptoManager.decrypt(encryptedToken)
}
} else {
account.password
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@

package com.flowcrypt.email.api.email.protocol

import android.accounts.AccountManager
import android.content.Context
import com.flowcrypt.email.accounts.FlowcryptAccountAuthenticator
import com.flowcrypt.email.api.email.EmailUtil
import com.flowcrypt.email.api.email.JavaEmailConstants
import com.flowcrypt.email.api.email.gmail.GmailConstants
import com.flowcrypt.email.database.entity.AccountEntity
import com.flowcrypt.email.security.KeyStoreCryptoManager
import com.google.android.gms.auth.GoogleAuthException
import java.io.IOException
import javax.mail.MessagingException
Expand Down Expand Up @@ -50,7 +53,7 @@ class SmtpProtocolUtil {

else -> {
val userName: String?
val password: String?
var password: String?

if (accountEntity.useCustomSignForSmtp == true) {
userName = accountEntity.smtpUsername
Expand All @@ -60,6 +63,20 @@ class SmtpProtocolUtil {
password = accountEntity.password
}

if (accountEntity.useOAuth2) {
val accountManager = AccountManager.get(context)
val oAuthAccount = accountManager.accounts.firstOrNull { it.name == accountEntity.email }
if (oAuthAccount != null) {
val encryptedToken = accountManager.blockingGetAuthToken(oAuthAccount,
FlowcryptAccountAuthenticator.AUTH_TOKEN_TYPE_EMAIL, true)
password = if (encryptedToken.isNullOrEmpty()) {
""//need to think about
} else {
KeyStoreCryptoManager.decrypt(encryptedToken)
}
}
}

transport.connect(accountEntity.smtpServer, accountEntity.smtpPort
?: 0, userName, password)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.flowcrypt.email.api.oauth.OAuth2Helper
import com.flowcrypt.email.api.retrofit.ApiRepository
import com.flowcrypt.email.api.retrofit.FlowcryptApiRepository
import com.flowcrypt.email.api.retrofit.response.base.Result
import com.flowcrypt.email.security.KeyStoreCryptoManager
import com.flowcrypt.email.util.exception.ApiException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -123,7 +124,7 @@ class OAuth2AuthCredentialsViewModel(application: Application) : BaseAndroidView
email = email,
accessToken = accessToken,
expiresAt = OAuth2Helper.getExpiresAtTime(response.data.expiresIn),
refreshToken = response.data.refreshToken
refreshToken = KeyStoreCryptoManager.encryptSuspend(response.data.refreshToken)
)
)?.copy(password = "", smtpSignInPassword = null)
?: throw NullPointerException("Couldn't find default settings for $email!")
Expand Down

0 comments on commit 23c909b

Please sign in to comment.