From 78e1503e738ed51bbb72fc9e32f865e89e69e38b Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Fri, 6 Aug 2021 11:21:21 +0300 Subject: [PATCH] Added handling 'disallow_attester_search_for_domains' OrgRule.| #1203 --- .../email/api/retrofit/ApiRepository.kt | 5 +- .../api/retrofit/FlowcryptApiRepository.kt | 20 +++++- .../api/retrofit/response/model/OrgRules.kt | 22 +++++- .../viewmodel/AccountKeysInfoViewModel.kt | 6 +- .../jetpack/viewmodel/ContactsViewModel.kt | 72 +++++++++---------- 5 files changed, 82 insertions(+), 43 deletions(-) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/ApiRepository.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/ApiRepository.kt index 4fe369ff39..d5a18473c1 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/ApiRepository.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/ApiRepository.kt @@ -81,13 +81,16 @@ interface ApiRepository : BaseApiRepository { ): Result /** + * @param requestCode A unique request code for this call * @param context Interface to global information about an application environment. * @param identData A key id or the user email or a fingerprint. + * @param orgRules Contains client configurations. */ suspend fun getPub( requestCode: Long = 0L, context: Context, - identData: String + identData: String, + orgRules: OrgRules? = null ): Result /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/FlowcryptApiRepository.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/FlowcryptApiRepository.kt index 79911fcb3a..965664547a 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/FlowcryptApiRepository.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/FlowcryptApiRepository.kt @@ -18,6 +18,7 @@ import com.flowcrypt.email.api.retrofit.response.attester.PubResponse import com.flowcrypt.email.api.retrofit.response.attester.TestWelcomeResponse import com.flowcrypt.email.api.retrofit.response.base.ApiResponse import com.flowcrypt.email.api.retrofit.response.base.Result +import com.flowcrypt.email.api.retrofit.response.model.OrgRules import com.flowcrypt.email.api.retrofit.response.oauth2.MicrosoftOAuth2TokenResponse import com.google.gson.JsonObject import kotlinx.coroutines.Dispatchers @@ -97,12 +98,27 @@ class FlowcryptApiRepository : ApiRepository { override suspend fun getPub( requestCode: Long, context: Context, - identData: String + identData: String, + orgRules: OrgRules? ): Result = withContext(Dispatchers.IO) { val apiService = ApiHelper.getInstance(context).retrofit.create(ApiService::class.java) + if (identData.contains('@')) { + if (orgRules?.canLookupThisRecipientOnAttester(identData) == false) { + return@withContext Result.success( + requestCode = requestCode, + data = PubResponse(null, null) + ) + } + } else if (orgRules?.disallowLookupOnAttester() == true) { + return@withContext Result.success( + requestCode = requestCode, + data = PubResponse(null, null) + ) + } + val result = getResult(requestCode = requestCode) { apiService.getPub(identData) } - when (result.status) { + return@withContext when (result.status) { Result.Status.SUCCESS -> Result.success( requestCode = requestCode, data = PubResponse(null, result.data) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/OrgRules.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/OrgRules.kt index 59ff0455e4..f3aebccff3 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/OrgRules.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/OrgRules.kt @@ -184,9 +184,25 @@ data class OrgRules constructor( * public keys for these domains, such as from their own internal keyserver */ fun canLookupThisRecipientOnAttester(emailAddr: String): Boolean { - val domain = EmailUtil.getDomain(emailAddr) - val domains = disallowAttesterSearchForDomains ?: emptyList() - return !domains.contains(if (domain.isEmpty()) "NONE" else domain) + if (disallowLookupOnAttester()) { + return false + } + + val disallowedDomains = disallowAttesterSearchForDomains ?: emptyList() + val userDomain = EmailUtil.getDomain(emailAddr) + if (userDomain.isEmpty()) { + throw IllegalStateException("Not a valid email $emailAddr") + } + + return !disallowedDomains.contains(userDomain) + } + + /** + * + * Some orgs might want to disallow lookup on attester completely + */ + fun disallowLookupOnAttester(): Boolean { + return (disallowAttesterSearchForDomains ?: emptyList()).contains("*") } /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountKeysInfoViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountKeysInfoViewModel.kt index 116a14218f..04ce9961e2 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountKeysInfoViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountKeysInfoViewModel.kt @@ -104,7 +104,11 @@ class AccountKeysInfoViewModel(application: Application) : AccountViewModel(appl } for (email in emails) { - val pubResponseResult = apiRepository.getPub(context = getApplication(), identData = email) + val pubResponseResult = apiRepository.getPub( + context = getApplication(), + identData = email, + orgRules = accountEntity.clientConfiguration + ) pubResponseResult.data?.pubkey?.let { key -> results.addAll(PgpKey.parseKeys(key).toPgpKeyDetailsList()) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index d802598ff0..ae91343045 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -13,7 +13,6 @@ import androidx.lifecycle.liveData import androidx.lifecycle.viewModelScope import com.flowcrypt.email.api.retrofit.ApiRepository import com.flowcrypt.email.api.retrofit.FlowcryptApiRepository -import com.flowcrypt.email.api.retrofit.node.NodeRepository import com.flowcrypt.email.api.retrofit.response.attester.PubResponse import com.flowcrypt.email.api.retrofit.response.base.ApiError import com.flowcrypt.email.api.retrofit.response.base.Result @@ -38,7 +37,6 @@ import java.util.* */ class ContactsViewModel(application: Application) : AccountViewModel(application) { private val apiRepository: ApiRepository = FlowcryptApiRepository() - private val pgpApiRepository = NodeRepository() private val searchPatternLiveData: MutableLiveData = MutableLiveData() val allContactsLiveData: LiveData> = @@ -278,10 +276,12 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun fetchPubKeys(keyIdOrEmail: String, requestCode: Long) { viewModelScope.launch { pubKeysFromAttesterLiveData.value = Result.loading(requestCode = requestCode) + val activeAccount = getActiveAccountSuspend() pubKeysFromAttesterLiveData.value = apiRepository.getPub( requestCode = requestCode, context = getApplication(), - identData = keyIdOrEmail + identData = keyIdOrEmail, + orgRules = activeAccount?.clientConfiguration ) } } @@ -315,45 +315,45 @@ class ContactsViewModel(application: Application) : AccountViewModel(application private suspend fun getPgpContactInfoFromServer( email: String? = null, fingerprint: String? = null - ): - PgpContact? = - withContext(Dispatchers.IO) { - try { - val response = apiRepository.getPub( - context = getApplication(), - identData = email ?: fingerprint ?: "" - ) + ): PgpContact? = withContext(Dispatchers.IO) { + try { + val activeAccount = getActiveAccountSuspend() + val response = apiRepository.getPub( + context = getApplication(), + identData = email ?: fingerprint ?: "", + orgRules = activeAccount?.clientConfiguration + ) - when (response.status) { - Result.Status.SUCCESS -> { - val pubKeyString = response.data?.pubkey - val client = ContactEntity.CLIENT_PGP - - if (pubKeyString?.isNotEmpty() == true) { - PgpKey.parseKeys(pubKeyString).toPgpKeyDetailsList().firstOrNull()?.let { - val pgpContact = it.primaryPgpContact - pgpContact.client = client - pgpContact.pgpKeyDetails = it - return@withContext pgpContact - } + when (response.status) { + Result.Status.SUCCESS -> { + val pubKeyString = response.data?.pubkey + val client = ContactEntity.CLIENT_PGP + + if (pubKeyString?.isNotEmpty() == true) { + PgpKey.parseKeys(pubKeyString).toPgpKeyDetailsList().firstOrNull()?.let { + val pgpContact = it.primaryPgpContact + pgpContact.client = client + pgpContact.pgpKeyDetails = it + return@withContext pgpContact } } + } - Result.Status.ERROR -> { - throw ApiException( - response.data?.apiError - ?: ApiError(code = -1, msg = "Unknown API error") - ) - } + Result.Status.ERROR -> { + throw ApiException( + response.data?.apiError + ?: ApiError(code = -1, msg = "Unknown API error") + ) + } - else -> { - throw response.exception ?: java.lang.Exception() - } + else -> { + throw response.exception ?: java.lang.Exception() } - } catch (e: IOException) { - e.printStackTrace() } - - null + } catch (e: IOException) { + e.printStackTrace() } + + null + } }