mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-25 05:52:40 +03:00
schedule device info update in fido and oath
This commit is contained in:
parent
3873ec4514
commit
fb2bec0b5e
@ -30,9 +30,7 @@ import com.yubico.yubikit.core.YubiKeyDevice
|
|||||||
import com.yubico.yubikit.core.smartcard.scp.ScpKeyParams
|
import com.yubico.yubikit.core.smartcard.scp.ScpKeyParams
|
||||||
import com.yubico.yubikit.management.Capability
|
import com.yubico.yubikit.management.Capability
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import kotlin.coroutines.suspendCoroutine
|
|
||||||
|
|
||||||
interface DeviceListener {
|
interface DeviceListener {
|
||||||
// a USB device is connected
|
// a USB device is connected
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.yubico.authenticator.fido
|
package com.yubico.authenticator.fido
|
||||||
|
|
||||||
import com.yubico.authenticator.device.DeviceManager
|
import com.yubico.authenticator.device.DeviceManager
|
||||||
|
import com.yubico.authenticator.device.Info
|
||||||
import com.yubico.authenticator.fido.data.YubiKitFidoSession
|
import com.yubico.authenticator.fido.data.YubiKitFidoSession
|
||||||
import com.yubico.authenticator.yubikit.DeviceInfoHelper.Companion.getDeviceInfo
|
import com.yubico.authenticator.yubikit.DeviceInfoHelper.Companion.getDeviceInfo
|
||||||
import com.yubico.authenticator.yubikit.withConnection
|
import com.yubico.authenticator.yubikit.withConnection
|
||||||
@ -24,11 +25,15 @@ import com.yubico.yubikit.android.transport.usb.UsbYubiKeyDevice
|
|||||||
import com.yubico.yubikit.core.fido.FidoConnection
|
import com.yubico.yubikit.core.fido.FidoConnection
|
||||||
import com.yubico.yubikit.core.util.Result
|
import com.yubico.yubikit.core.util.Result
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import java.util.Timer
|
||||||
|
import java.util.TimerTask
|
||||||
import kotlin.coroutines.cancellation.CancellationException
|
import kotlin.coroutines.cancellation.CancellationException
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
import kotlin.concurrent.schedule
|
||||||
|
|
||||||
class FidoConnectionHelper(private val deviceManager: DeviceManager) {
|
class FidoConnectionHelper(private val deviceManager: DeviceManager) {
|
||||||
private var pendingAction: FidoAction? = null
|
private var pendingAction: FidoAction? = null
|
||||||
|
private var deviceInfoTimer: TimerTask? = null
|
||||||
|
|
||||||
fun invokePending(fidoSession: YubiKitFidoSession) {
|
fun invokePending(fidoSession: YubiKitFidoSession) {
|
||||||
pendingAction?.let { action ->
|
pendingAction?.let { action ->
|
||||||
@ -38,6 +43,7 @@ class FidoConnectionHelper(private val deviceManager: DeviceManager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun cancelPending() {
|
fun cancelPending() {
|
||||||
|
deviceInfoTimer?.cancel()
|
||||||
pendingAction?.let { action ->
|
pendingAction?.let { action ->
|
||||||
action.invoke(Result.failure(CancellationException()))
|
action.invoke(Result.failure(CancellationException()))
|
||||||
pendingAction = null
|
pendingAction = null
|
||||||
@ -67,7 +73,7 @@ class FidoConnectionHelper(private val deviceManager: DeviceManager) {
|
|||||||
block(YubiKitFidoSession(it))
|
block(YubiKitFidoSession(it))
|
||||||
}.also {
|
}.also {
|
||||||
if (updateDeviceInfo) {
|
if (updateDeviceInfo) {
|
||||||
deviceManager.setDeviceInfo(getDeviceInfo(device))
|
scheduleDeviceInfoUpdate(getDeviceInfo(device))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +97,14 @@ class FidoConnectionHelper(private val deviceManager: DeviceManager) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun scheduleDeviceInfoUpdate(deviceInfo: Info?) {
|
||||||
|
deviceInfoTimer?.cancel()
|
||||||
|
deviceInfoTimer = Timer("update-device-info", false).schedule(500) {
|
||||||
|
logger.debug("Updating device info")
|
||||||
|
deviceManager.setDeviceInfo(deviceInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val logger = LoggerFactory.getLogger(FidoConnectionHelper::class.java)
|
private val logger = LoggerFactory.getLogger(FidoConnectionHelper::class.java)
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ class FidoManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (updateDeviceInfo.getAndSet(false)) {
|
if (updateDeviceInfo.getAndSet(false)) {
|
||||||
deviceManager.setDeviceInfo(getDeviceInfo(device))
|
connectionHelper.scheduleDeviceInfoUpdate(getDeviceInfo(device))
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// something went wrong, try to get DeviceInfo from any available connection type
|
// something went wrong, try to get DeviceInfo from any available connection type
|
||||||
|
@ -26,6 +26,7 @@ import com.yubico.authenticator.*
|
|||||||
import com.yubico.authenticator.device.Capabilities
|
import com.yubico.authenticator.device.Capabilities
|
||||||
import com.yubico.authenticator.device.DeviceListener
|
import com.yubico.authenticator.device.DeviceListener
|
||||||
import com.yubico.authenticator.device.DeviceManager
|
import com.yubico.authenticator.device.DeviceManager
|
||||||
|
import com.yubico.authenticator.device.Info
|
||||||
import com.yubico.authenticator.device.UnknownDevice
|
import com.yubico.authenticator.device.UnknownDevice
|
||||||
import com.yubico.authenticator.oath.data.Code
|
import com.yubico.authenticator.oath.data.Code
|
||||||
import com.yubico.authenticator.oath.data.CodeType
|
import com.yubico.authenticator.oath.data.CodeType
|
||||||
@ -63,10 +64,12 @@ import kotlinx.serialization.encodeToString
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import java.util.Timer
|
||||||
|
import java.util.TimerTask
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
import kotlin.random.Random
|
import kotlin.concurrent.schedule
|
||||||
|
|
||||||
typealias OathAction = (Result<YubiKitOathSession, Exception>) -> Unit
|
typealias OathAction = (Result<YubiKitOathSession, Exception>) -> Unit
|
||||||
|
|
||||||
@ -108,8 +111,10 @@ class OathManager(
|
|||||||
private var refreshJob: Job? = null
|
private var refreshJob: Job? = null
|
||||||
private var addToAny = false
|
private var addToAny = false
|
||||||
private val updateDeviceInfo = AtomicBoolean(false)
|
private val updateDeviceInfo = AtomicBoolean(false)
|
||||||
|
private var deviceInfoTimer: TimerTask? = null
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
deviceInfoTimer?.cancel()
|
||||||
// cancel any pending actions, except for addToAny
|
// cancel any pending actions, except for addToAny
|
||||||
if (!addToAny) {
|
if (!addToAny) {
|
||||||
pendingAction?.let {
|
pendingAction?.let {
|
||||||
@ -294,7 +299,7 @@ class OathManager(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (updateDeviceInfo.getAndSet(false)) {
|
if (updateDeviceInfo.getAndSet(false)) {
|
||||||
deviceManager.setDeviceInfo(getDeviceInfo(device))
|
scheduleDeviceInfoUpdate(getDeviceInfo(device))
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// OATH not enabled/supported, try to get DeviceInfo over other USB interfaces
|
// OATH not enabled/supported, try to get DeviceInfo over other USB interfaces
|
||||||
@ -675,6 +680,14 @@ class OathManager(
|
|||||||
return credential.data
|
return credential.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun scheduleDeviceInfoUpdate(deviceInfo: Info?) {
|
||||||
|
deviceInfoTimer?.cancel()
|
||||||
|
deviceInfoTimer = Timer("update-device-info", false).schedule(500) {
|
||||||
|
logger.debug("Updating device info")
|
||||||
|
deviceManager.setDeviceInfo(deviceInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun <T> useOathSession(
|
private suspend fun <T> useOathSession(
|
||||||
unlock: Boolean = true,
|
unlock: Boolean = true,
|
||||||
updateDeviceInfo: Boolean = false,
|
updateDeviceInfo: Boolean = false,
|
||||||
@ -702,7 +715,7 @@ class OathManager(
|
|||||||
block(getOathSession(it))
|
block(getOathSession(it))
|
||||||
}.also {
|
}.also {
|
||||||
if (updateDeviceInfo) {
|
if (updateDeviceInfo) {
|
||||||
deviceManager.setDeviceInfo(getDeviceInfo(device))
|
scheduleDeviceInfoUpdate(getDeviceInfo(device))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,8 +393,7 @@ class _FidoMethodChannelNotifier extends MethodChannelNotifier {
|
|||||||
|
|
||||||
Future<dynamic> reset() async => invoke('reset', {
|
Future<dynamic> reset() async => invoke('reset', {
|
||||||
'operationSuccess': l10n.s_nfc_fido_reset_success,
|
'operationSuccess': l10n.s_nfc_fido_reset_success,
|
||||||
'operationFailure': l10n.s_nfc_fido_reset_failure,
|
'operationFailure': l10n.s_nfc_fido_reset_failure
|
||||||
'showSuccess': true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<dynamic> setPin(String newPin, {String? oldPin}) async =>
|
Future<dynamic> setPin(String newPin, {String? oldPin}) async =>
|
||||||
@ -405,8 +404,7 @@ class _FidoMethodChannelNotifier extends MethodChannelNotifier {
|
|||||||
: l10n.s_pin_set,
|
: l10n.s_pin_set,
|
||||||
'operationFailure': oldPin != null
|
'operationFailure': oldPin != null
|
||||||
? l10n.s_nfc_fido_change_pin_failure
|
? l10n.s_nfc_fido_change_pin_failure
|
||||||
: l10n.s_nfc_fido_set_pin_failure,
|
: l10n.s_nfc_fido_set_pin_failure
|
||||||
'showSuccess': true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<dynamic> unlock(String pin) async => invoke('unlock', {
|
Future<dynamic> unlock(String pin) async => invoke('unlock', {
|
||||||
|
Loading…
Reference in New Issue
Block a user