Add logging for SDK functionality in debug only (#3738)

This commit is contained in:
David Perez 2024-08-14 16:10:19 -05:00 committed by GitHub
parent 4b35484abb
commit 524b9e9a08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 98 additions and 72 deletions

View file

@ -7,11 +7,11 @@ import com.bitwarden.core.RegisterKeyResponse
import com.bitwarden.core.RegisterTdeKeyResponse
import com.bitwarden.crypto.HashPurpose
import com.bitwarden.crypto.Kdf
import com.bitwarden.sdk.Client
import com.bitwarden.sdk.ClientAuth
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toPasswordStrengthOrNull
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toUByte
import com.x8bit.bitwarden.data.platform.datasource.sdk.BaseSdkSource
import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
/**
@ -19,12 +19,13 @@ import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
* [ClientAuth].
*/
class AuthSdkSourceImpl(
private val sdkClientManager: SdkClientManager,
) : AuthSdkSource {
sdkClientManager: SdkClientManager,
) : BaseSdkSource(sdkClientManager = sdkClientManager),
AuthSdkSource {
override suspend fun getNewAuthRequest(
email: String,
): Result<AuthRequestResponse> = runCatching {
): Result<AuthRequestResponse> = runCatchingWithLogs {
getClient()
.auth()
.newAuthRequest(
@ -35,7 +36,7 @@ class AuthSdkSourceImpl(
override suspend fun getUserFingerprint(
email: String,
publicKey: String,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient()
.platform()
.fingerprint(
@ -51,7 +52,7 @@ class AuthSdkSourceImpl(
password: String,
kdf: Kdf,
purpose: HashPurpose,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient()
.auth()
.hashPassword(
@ -66,7 +67,7 @@ class AuthSdkSourceImpl(
email: String,
password: String,
kdf: Kdf,
): Result<RegisterKeyResponse> = runCatching {
): Result<RegisterKeyResponse> = runCatchingWithLogs {
getClient()
.auth()
.makeRegisterKeys(
@ -81,7 +82,7 @@ class AuthSdkSourceImpl(
email: String,
orgPublicKey: String,
rememberDevice: Boolean,
): Result<RegisterTdeKeyResponse> = runCatching {
): Result<RegisterTdeKeyResponse> = runCatchingWithLogs {
getClient(userId = userId)
.auth()
.makeRegisterTdeKeys(
@ -95,7 +96,7 @@ class AuthSdkSourceImpl(
email: String,
password: String,
additionalInputs: List<String>,
): Result<PasswordStrength> = runCatching {
): Result<PasswordStrength> = runCatchingWithLogs {
@Suppress("UnsafeCallOnNullableType")
getClient()
.auth()
@ -111,7 +112,7 @@ class AuthSdkSourceImpl(
password: String,
passwordStrength: PasswordStrength,
policy: MasterPasswordPolicyOptions,
): Result<Boolean> = runCatching {
): Result<Boolean> = runCatchingWithLogs {
getClient()
.auth()
.satisfiesPolicy(
@ -120,8 +121,4 @@ class AuthSdkSourceImpl(
policy = policy,
)
}
private suspend fun getClient(
userId: String? = null,
): Client = sdkClientManager.getOrCreateClient(userId = userId)
}

View file

@ -0,0 +1,35 @@
package com.x8bit.bitwarden.data.platform.datasource.sdk
import android.util.Log
import com.bitwarden.sdk.Client
import com.x8bit.bitwarden.BuildConfig
import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
/**
* Base class for simplifying sdk interactions.
*/
@Suppress("UnnecessaryAbstractClass")
abstract class BaseSdkSource(
protected val sdkClientManager: SdkClientManager,
) {
/**
* Helper function to retrieve the [Client] associated with the given [userId].
*/
protected suspend fun getClient(
userId: String? = null,
): Client = sdkClientManager.getOrCreateClient(userId = userId)
/**
* Invokes the [block] with `this` value as its receiver and returns its result if it was
* successful and catches any exception that was thrown from the `block` and wrapping it as a
* failure.
*/
protected inline fun <T, R> T.runCatchingWithLogs(
block: T.() -> R,
): Result<R> = runCatching(block = block)
.onFailure {
if (BuildConfig.DEBUG) {
Log.w(this@BaseSdkSource::class.java.simpleName, it)
}
}
}

View file

@ -3,8 +3,8 @@ package com.x8bit.bitwarden.data.tools.generator.datasource.sdk
import com.bitwarden.generators.PassphraseGeneratorRequest
import com.bitwarden.generators.PasswordGeneratorRequest
import com.bitwarden.generators.UsernameGeneratorRequest
import com.bitwarden.sdk.Client
import com.bitwarden.sdk.ClientGenerators
import com.x8bit.bitwarden.data.platform.datasource.sdk.BaseSdkSource
import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
/**
@ -14,46 +14,43 @@ import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
* [ClientGenerators] provided by the Bitwarden SDK.
*/
class GeneratorSdkSourceImpl(
private val sdkClientManager: SdkClientManager,
) : GeneratorSdkSource {
sdkClientManager: SdkClientManager,
) : BaseSdkSource(sdkClientManager = sdkClientManager),
GeneratorSdkSource {
override suspend fun generatePassword(
request: PasswordGeneratorRequest,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient().generators().password(request)
}
override suspend fun generatePassphrase(
request: PassphraseGeneratorRequest,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient().generators().passphrase(request)
}
override suspend fun generatePlusAddressedEmail(
request: UsernameGeneratorRequest.Subaddress,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient().generators().username(request)
}
override suspend fun generateCatchAllEmail(
request: UsernameGeneratorRequest.Catchall,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient().generators().username(request)
}
override suspend fun generateRandomWord(
request: UsernameGeneratorRequest.Word,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient().generators().username(request)
}
override suspend fun generateForwardedServiceEmail(
request: UsernameGeneratorRequest.Forwarded,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient().generators().username(request)
}
private suspend fun getClient(
userId: String? = null,
): Client = sdkClientManager.getOrCreateClient(userId = userId)
}

View file

@ -11,7 +11,6 @@ import com.bitwarden.fido.Fido2CredentialAutofillView
import com.bitwarden.fido.PublicKeyCredentialAuthenticatorAssertionResponse
import com.bitwarden.fido.PublicKeyCredentialAuthenticatorAttestationResponse
import com.bitwarden.sdk.BitwardenException
import com.bitwarden.sdk.Client
import com.bitwarden.sdk.ClientVault
import com.bitwarden.sdk.Fido2CredentialStore
import com.bitwarden.send.Send
@ -28,6 +27,7 @@ import com.bitwarden.vault.FolderView
import com.bitwarden.vault.PasswordHistory
import com.bitwarden.vault.PasswordHistoryView
import com.bitwarden.vault.TotpResponse
import com.x8bit.bitwarden.data.platform.datasource.sdk.BaseSdkSource
import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.AuthenticateFido2CredentialRequest
@ -50,16 +50,18 @@ import java.io.File
*/
@Suppress("TooManyFunctions")
class VaultSdkSourceImpl(
private val sdkClientManager: SdkClientManager,
sdkClientManager: SdkClientManager,
private val dispatcherManager: DispatcherManager,
) : VaultSdkSource {
) : BaseSdkSource(sdkClientManager = sdkClientManager),
VaultSdkSource {
override fun clearCrypto(userId: String) {
sdkClientManager.destroyClient(userId = userId)
}
override suspend fun getTrustDevice(
userId: String,
): Result<TrustDeviceResponse> = runCatching {
): Result<TrustDeviceResponse> = runCatchingWithLogs {
getClient(userId = userId)
.auth()
.trustDevice()
@ -69,7 +71,7 @@ class VaultSdkSourceImpl(
userId: String,
pin: String,
): Result<DerivePinKeyResponse> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.crypto()
.derivePinKey(pin = pin)
@ -79,7 +81,7 @@ class VaultSdkSourceImpl(
userId: String,
encryptedPin: String,
): Result<String> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.crypto()
.derivePinUserKey(encryptedPin = encryptedPin)
@ -89,7 +91,7 @@ class VaultSdkSourceImpl(
publicKey: String,
userId: String,
): Result<String> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.auth()
.approveAuthRequest(publicKey = publicKey)
@ -98,7 +100,7 @@ class VaultSdkSourceImpl(
override suspend fun getResetPasswordKey(
orgPublicKey: String,
userId: String,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient(userId = userId)
.crypto()
.enrollAdminPasswordReset(publicKey = orgPublicKey)
@ -107,7 +109,7 @@ class VaultSdkSourceImpl(
override suspend fun getUserEncryptionKey(
userId: String,
): Result<String> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.crypto()
.getUserEncryptionKey()
@ -116,7 +118,7 @@ class VaultSdkSourceImpl(
override suspend fun getUserFingerprint(
userId: String,
): Result<String> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.platform()
.userFingerprint(fingerprintMaterial = userId)
@ -126,7 +128,7 @@ class VaultSdkSourceImpl(
userId: String,
request: InitUserCryptoRequest,
): Result<InitializeCryptoResult> =
runCatching {
runCatchingWithLogs {
try {
getClient(userId = userId)
.crypto()
@ -142,7 +144,7 @@ class VaultSdkSourceImpl(
userId: String,
request: InitOrgCryptoRequest,
): Result<InitializeCryptoResult> =
runCatching {
runCatchingWithLogs {
try {
getClient(userId = userId)
.crypto()
@ -160,7 +162,7 @@ class VaultSdkSourceImpl(
userId: String,
sendView: SendView,
): Result<Send> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.sends()
.encrypt(send = sendView)
@ -171,7 +173,7 @@ class VaultSdkSourceImpl(
send: Send,
fileBuffer: ByteArray,
): Result<ByteArray> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.sends()
.encryptBuffer(
@ -186,7 +188,7 @@ class VaultSdkSourceImpl(
path: String,
destinationFilePath: String,
): Result<File> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.sends()
.encryptFile(
@ -204,7 +206,7 @@ class VaultSdkSourceImpl(
decryptedFilePath: String,
encryptedFilePath: String,
): Result<Attachment> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.attachments()
@ -220,7 +222,7 @@ class VaultSdkSourceImpl(
userId: String,
cipherView: CipherView,
): Result<Cipher> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.ciphers()
@ -231,7 +233,7 @@ class VaultSdkSourceImpl(
userId: String,
cipher: Cipher,
): Result<CipherView> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.ciphers()
@ -242,7 +244,7 @@ class VaultSdkSourceImpl(
userId: String,
cipherList: List<Cipher>,
): Result<List<CipherListView>> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.ciphers()
@ -253,7 +255,7 @@ class VaultSdkSourceImpl(
userId: String,
cipherList: List<Cipher>,
): Result<List<CipherView>> =
runCatching {
runCatchingWithLogs {
val ciphers = getClient(userId = userId).vault().ciphers()
withContext(context = dispatcherManager.default) {
cipherList.map { async { ciphers.decrypt(cipher = it) } }.awaitAll()
@ -264,7 +266,7 @@ class VaultSdkSourceImpl(
userId: String,
collection: Collection,
): Result<CollectionView> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.collections()
@ -275,7 +277,7 @@ class VaultSdkSourceImpl(
userId: String,
collectionList: List<Collection>,
): Result<List<CollectionView>> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.collections()
@ -286,7 +288,7 @@ class VaultSdkSourceImpl(
userId: String,
send: Send,
): Result<SendView> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.sends()
.decrypt(send = send)
@ -296,7 +298,7 @@ class VaultSdkSourceImpl(
userId: String,
sendList: List<Send>,
): Result<List<SendView>> =
runCatching {
runCatchingWithLogs {
val sends = getClient(userId = userId).sends()
withContext(dispatcherManager.default) {
sendList.map { async { sends.decrypt(send = it) } }.awaitAll()
@ -307,7 +309,7 @@ class VaultSdkSourceImpl(
userId: String,
folder: FolderView,
): Result<Folder> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.folders()
@ -318,7 +320,7 @@ class VaultSdkSourceImpl(
userId: String,
folder: Folder,
): Result<FolderView> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.folders()
@ -329,7 +331,7 @@ class VaultSdkSourceImpl(
userId: String,
folderList: List<Folder>,
): Result<List<FolderView>> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.folders()
@ -343,7 +345,7 @@ class VaultSdkSourceImpl(
encryptedFilePath: String,
decryptedFilePath: String,
): Result<Unit> =
runCatching {
runCatchingWithLogs {
getClient(userId = userId)
.vault()
.attachments()
@ -358,7 +360,7 @@ class VaultSdkSourceImpl(
override suspend fun encryptPasswordHistory(
userId: String,
passwordHistory: PasswordHistoryView,
): Result<PasswordHistory> = runCatching {
): Result<PasswordHistory> = runCatchingWithLogs {
getClient(userId = userId)
.vault()
.passwordHistory()
@ -368,7 +370,7 @@ class VaultSdkSourceImpl(
override suspend fun decryptPasswordHistoryList(
userId: String,
passwordHistoryList: List<PasswordHistory>,
): Result<List<PasswordHistoryView>> = runCatching {
): Result<List<PasswordHistoryView>> = runCatchingWithLogs {
getClient(userId = userId)
.vault()
.passwordHistory()
@ -379,7 +381,7 @@ class VaultSdkSourceImpl(
userId: String,
totp: String,
time: DateTime,
): Result<TotpResponse> = runCatching {
): Result<TotpResponse> = runCatchingWithLogs {
getClient(userId = userId)
.vault()
.generateTotp(
@ -392,7 +394,7 @@ class VaultSdkSourceImpl(
userId: String,
organizationId: String,
cipherView: CipherView,
): Result<CipherView> = runCatching {
): Result<CipherView> = runCatchingWithLogs {
getClient(userId = userId)
.vault()
.ciphers()
@ -403,7 +405,7 @@ class VaultSdkSourceImpl(
userId: String,
password: String,
passwordHash: String,
): Result<Boolean> = runCatching {
): Result<Boolean> = runCatchingWithLogs {
getClient(userId = userId)
.auth()
.validatePassword(
@ -416,7 +418,7 @@ class VaultSdkSourceImpl(
userId: String,
password: String,
encryptedUserKey: String,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient(userId = userId)
.auth()
.validatePasswordUserKey(
@ -428,7 +430,7 @@ class VaultSdkSourceImpl(
override suspend fun updatePassword(
userId: String,
newPassword: String,
): Result<UpdatePasswordResponse> = runCatching {
): Result<UpdatePasswordResponse> = runCatchingWithLogs {
getClient(userId = userId)
.crypto()
.updatePassword(newPassword = newPassword)
@ -439,7 +441,7 @@ class VaultSdkSourceImpl(
folders: List<Folder>,
ciphers: List<Cipher>,
format: ExportFormat,
): Result<String> = runCatching {
): Result<String> = runCatchingWithLogs {
getClient(userId = userId)
.exporters()
.exportVault(
@ -452,7 +454,7 @@ class VaultSdkSourceImpl(
override suspend fun registerFido2Credential(
request: RegisterFido2CredentialRequest,
fido2CredentialStore: Fido2CredentialStore,
): Result<PublicKeyCredentialAuthenticatorAttestationResponse> = runCatching {
): Result<PublicKeyCredentialAuthenticatorAttestationResponse> = runCatchingWithLogs {
callbackFlow {
try {
val client = getClient(request.userId)
@ -483,11 +485,10 @@ class VaultSdkSourceImpl(
.first()
}
@Suppress("MaxLineLength")
override suspend fun authenticateFido2Credential(
request: AuthenticateFido2CredentialRequest,
fido2CredentialStore: Fido2CredentialStore,
): Result<PublicKeyCredentialAuthenticatorAssertionResponse> = runCatching {
): Result<PublicKeyCredentialAuthenticatorAssertionResponse> = runCatchingWithLogs {
callbackFlow {
try {
val client = getClient(request.userId)
@ -521,7 +522,7 @@ class VaultSdkSourceImpl(
override suspend fun decryptFido2CredentialAutofillViews(
userId: String,
vararg cipherViews: CipherView,
): Result<List<Fido2CredentialAutofillView>> = runCatching {
): Result<List<Fido2CredentialAutofillView>> = runCatchingWithLogs {
val fido2 = getClient(userId = userId).platform().fido2()
cipherViews.flatMap { fido2.decryptFido2AutofillCredentials(cipherView = it) }
}
@ -530,7 +531,7 @@ class VaultSdkSourceImpl(
userId: String,
fido2CredentialStore: Fido2CredentialStore,
relyingPartyId: String,
): Result<List<Fido2CredentialAutofillView>> = runCatching {
): Result<List<Fido2CredentialAutofillView>> = runCatchingWithLogs {
getClient(userId)
.platform()
.fido2()
@ -540,8 +541,4 @@ class VaultSdkSourceImpl(
)
.silentlyDiscoverCredentials(relyingPartyId)
}
private suspend fun getClient(
userId: String,
): Client = sdkClientManager.getOrCreateClient(userId = userId)
}