Code review

This commit is contained in:
Valere 2021-12-08 14:17:08 +01:00
parent 5d35f02abb
commit 01b8b7d57a
3 changed files with 31 additions and 26 deletions

View file

@ -437,7 +437,7 @@ internal class DefaultCryptoService @Inject constructor(
if (syncResponse.deviceUnusedFallbackKeyTypes != null && if (syncResponse.deviceUnusedFallbackKeyTypes != null &&
// Generate a fallback key only if the server does not already have an unused fallback key. // Generate a fallback key only if the server does not already have an unused fallback key.
!syncResponse.deviceUnusedFallbackKeyTypes.contains(KEY_SIGNED_CURVE_25519_TYPE)) { !syncResponse.deviceUnusedFallbackKeyTypes.contains(KEY_SIGNED_CURVE_25519_TYPE)) {
oneTimeKeysUploader.setNeedsNewFallback() oneTimeKeysUploader.needsNewFallback()
} }
oneTimeKeysUploader.maybeUploadOneTimeKeys() oneTimeKeysUploader.maybeUploadOneTimeKeys()

View file

@ -150,13 +150,26 @@ internal class MXOlmDevice @Inject constructor(
return null return null
} }
fun generateFallbackKey() { /**
* Generates a new fallback key if there is not already
* an unpublished one.
* @return true if a new key was generated
*/
fun generateFallbackKeyIfNeeded(): Boolean {
try { try {
store.getOlmAccount().generateFallbackKey() if (!hasUnpublishedFallbackKey()) {
store.saveOlmAccount() store.getOlmAccount().generateFallbackKey()
store.saveOlmAccount()
return true
}
} catch (e: Exception) { } catch (e: Exception) {
Timber.e("## generateFallbackKey() : failed") Timber.e("## generateFallbackKey() : failed")
} }
return false
}
internal fun hasUnpublishedFallbackKey(): Boolean {
return getFallbackKey()?.get(OlmAccount.JSON_KEY_ONE_TIME_KEY).orEmpty().isNotEmpty()
} }
fun forgetFallbackKey() { fun forgetFallbackKey() {

View file

@ -29,7 +29,9 @@ import javax.inject.Inject
import kotlin.math.floor import kotlin.math.floor
import kotlin.math.min import kotlin.math.min
const val FIVE_MINUTES = 5 * 60_000L // THe spec recommend a 5mn delay, but due to federation
// or server down we give it a bit more time (1 hour)
const val FALLBACK_KEY_FORGET_DELAY = 60 * 60_000L
@SessionScope @SessionScope
internal class OneTimeKeysUploader @Inject constructor( internal class OneTimeKeysUploader @Inject constructor(
@ -59,8 +61,13 @@ internal class OneTimeKeysUploader @Inject constructor(
oneTimeKeyCount = currentCount oneTimeKeyCount = currentCount
} }
fun setNeedsNewFallback() { fun needsNewFallback() {
needNewFallbackKey = true if (olmDevice.generateFallbackKeyIfNeeded()) {
// As we generated a new one, it's already forgetting one
// so we can clear the last publish time
// (in case the network calls fails after to avoid calling forgetKey)
saveLastFallbackKeyPublishTime(0L)
}
} }
/** /**
@ -120,9 +127,9 @@ internal class OneTimeKeysUploader @Inject constructor(
// Check if we need to forget a fallback key // Check if we need to forget a fallback key
val latestPublishedTime = getLastFallbackKeyPublishTime() val latestPublishedTime = getLastFallbackKeyPublishTime()
if (latestPublishedTime != 0L && System.currentTimeMillis() - latestPublishedTime > FIVE_MINUTES) { if (latestPublishedTime != 0L && System.currentTimeMillis() - latestPublishedTime > FALLBACK_KEY_FORGET_DELAY) {
// This should be called once you are reasonably certain that you will not receive any more messages // This should be called once you are reasonably certain that you will not receive any more messages
// that use the old fallback key (e.g. 5 minutes after the new fallback key has been published) // that use the old fallback key
Timber.d("## forgetFallbackKey()") Timber.d("## forgetFallbackKey()")
olmDevice.forgetFallbackKey() olmDevice.forgetFallbackKey()
} }
@ -155,20 +162,9 @@ internal class OneTimeKeysUploader @Inject constructor(
keysThisLoop = min(keyLimit - keyCount, ONE_TIME_KEY_GENERATION_MAX_NUMBER) keysThisLoop = min(keyLimit - keyCount, ONE_TIME_KEY_GENERATION_MAX_NUMBER)
olmDevice.generateOneTimeKeys(keysThisLoop) olmDevice.generateOneTimeKeys(keysThisLoop)
} }
if (needNewFallbackKey && !hasUnpublishedFallbackKey()) {
// if there is already fallback key, but that hasn't been published yet, we
// can use that instead of generating a new one
olmDevice.generateFallbackKey()
Timber.d("maybeUploadOneTimeKeys: Fallback key generated")
// As we generated a new one, it's already forgetting one
// so we can clear the last publish time
// (in case the network calls fails after to avoid calling forgetKey)
saveLastFallbackKeyPublishTime(0L)
}
// not copy paste error we check before sending if there is // We check before sending if there is an unpublished key in order to saveLastFallbackKeyPublishTime if needed
// an unpublished key in order to saveLastFallbackKeyPublishTime if needed val hadUnpublishedFallbackKey = olmDevice.hasUnpublishedFallbackKey()
val hadUnpublishedFallbackKey = hasUnpublishedFallbackKey()
val response = uploadOneTimeKeys(olmDevice.getOneTimeKeys()) val response = uploadOneTimeKeys(olmDevice.getOneTimeKeys())
olmDevice.markKeysAsPublished() olmDevice.markKeysAsPublished()
if (hadUnpublishedFallbackKey) { if (hadUnpublishedFallbackKey) {
@ -189,10 +185,6 @@ internal class OneTimeKeysUploader @Inject constructor(
} }
} }
private fun hasUnpublishedFallbackKey(): Boolean {
return olmDevice.getFallbackKey()?.get(OlmAccount.JSON_KEY_ONE_TIME_KEY).orEmpty().isNotEmpty()
}
private fun saveLastFallbackKeyPublishTime(timeMillis: Long) { private fun saveLastFallbackKeyPublishTime(timeMillis: Long) {
storage.edit().putLong("last_fb_key_publish", timeMillis).apply() storage.edit().putLong("last_fb_key_publish", timeMillis).apply()
} }