mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 08:22:16 +03:00
Add enable EA
This commit is contained in:
parent
c90ba130ce
commit
bb0c9480b6
@ -22,7 +22,7 @@ from .base import (
|
||||
PinComplexityException,
|
||||
)
|
||||
from fido2.ctap import CtapError
|
||||
from fido2.ctap2 import Ctap2, ClientPin
|
||||
from fido2.ctap2 import Ctap2, ClientPin, Config
|
||||
from fido2.ctap2.credman import CredentialManagement
|
||||
from fido2.ctap2.bio import BioEnrollment, FPBioEnrollment, CaptureError
|
||||
from fido2.pcsc import CtapPcscDevice
|
||||
@ -199,6 +199,8 @@ class Ctap2Node(RpcNode):
|
||||
permissions |= ClientPin.PERMISSION.CREDENTIAL_MGMT
|
||||
if BioEnrollment.is_supported(self._info):
|
||||
permissions |= ClientPin.PERMISSION.BIO_ENROLL
|
||||
if Config.is_supported(self._info):
|
||||
permissions |= ClientPin.PERMISSION.AUTHENTICATOR_CFG
|
||||
try:
|
||||
if permissions:
|
||||
self._token = self.client_pin.get_pin_token(pin, permissions)
|
||||
@ -228,6 +230,14 @@ class Ctap2Node(RpcNode):
|
||||
except CtapError as e:
|
||||
return _handle_pin_error(e, self.client_pin)
|
||||
|
||||
@action(condition=lambda self: Config.is_supported(self._info))
|
||||
def enable_ep_attestation(self, params, event, signal):
|
||||
if self._info.options["clientPin"] and not self._token:
|
||||
raise AuthRequiredException()
|
||||
config = Config(self.ctap, self.client_pin.protocol, self._token)
|
||||
config._call(Config.CMD.ENABLE_ENTERPRISE_ATT)
|
||||
return dict()
|
||||
|
||||
@child(condition=lambda self: BioEnrollment.is_supported(self._info))
|
||||
def fingerprints(self):
|
||||
if not self._token:
|
||||
|
@ -161,6 +161,12 @@ class _FidoStateNotifier extends FidoStateNotifier {
|
||||
throw decodedException;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> enableEnterpriseAttestation() {
|
||||
// TODO: implement enableEnterpriseAttestation
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
final androidFingerprintProvider = AsyncNotifierProvider.autoDispose
|
||||
|
@ -184,6 +184,12 @@ class _DesktopFidoStateNotifier extends FidoStateNotifier {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> enableEnterpriseAttestation() async {
|
||||
await _session.command('enable_ep_attestation');
|
||||
ref.invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
final desktopFingerprintProvider = AsyncNotifierProvider.autoDispose
|
||||
|
@ -21,6 +21,8 @@ final actions = fido.feature('actions');
|
||||
final actionsPin = actions.feature('pin');
|
||||
final actionsAddFingerprint = actions.feature('addFingerprint');
|
||||
final actionsReset = actions.feature('reset');
|
||||
final enableEnterpriseAttestation =
|
||||
actions.feature('enableEnterpriseAttestation');
|
||||
|
||||
final credentials = fido.feature('credentials');
|
||||
|
||||
|
@ -25,6 +25,8 @@ const _credentialInfo = '$_prefix.credential.info';
|
||||
// Key actions
|
||||
const managePinAction = Key('$_keyAction.manage_pin');
|
||||
const addFingerprintAction = Key('$_keyAction.add_fingerprint');
|
||||
const enableEnterpriseAttestation =
|
||||
Key('$_keyAction.enable_enterprise_attestation');
|
||||
const newPin = Key('$_keyAction.new_pin');
|
||||
const confirmPin = Key('$_keyAction.confirm_pin');
|
||||
const currentPin = Key('$_keyAction.current_pin');
|
||||
|
@ -50,6 +50,8 @@ class FidoState with _$FidoState {
|
||||
bool get forcePinChange => info['force_pin_change'] == true;
|
||||
|
||||
bool get pinBlocked => pinRetries == 0;
|
||||
|
||||
bool? get enterpriseAttestation => info['options']['ep'];
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -41,6 +41,7 @@ abstract class FidoStateNotifier extends ApplicationStateNotifier<FidoState> {
|
||||
Stream<InteractionEvent> reset();
|
||||
Future<PinResult> setPin(String newPin, {String? oldPin});
|
||||
Future<PinResult> unlock(String pin);
|
||||
Future<void> enableEnterpriseAttestation();
|
||||
}
|
||||
|
||||
final fingerprintProvider = AsyncNotifierProvider.autoDispose
|
||||
|
50
lib/fido/views/enterprise_attestation_dialog.dart
Normal file
50
lib/fido/views/enterprise_attestation_dialog.dart
Normal file
@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../app/message.dart';
|
||||
import '../../app/models.dart';
|
||||
import '../../app/state.dart';
|
||||
import '../../widgets/responsive_dialog.dart';
|
||||
import '../state.dart';
|
||||
|
||||
class EnableEnterpriseAttestationDialog extends ConsumerWidget {
|
||||
final DevicePath devicePath;
|
||||
const EnableEnterpriseAttestationDialog(this.devicePath, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return ResponsiveDialog(
|
||||
title: Text(l10n.s_enable_ep_attestation),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(fidoStateProvider(devicePath).notifier)
|
||||
.enableEnterpriseAttestation();
|
||||
await ref.read(withContextProvider)((context) async {
|
||||
Navigator.of(context).pop();
|
||||
showMessage(context, l10n.s_ep_attestation_enabled);
|
||||
});
|
||||
},
|
||||
child: Text(l10n.s_enable),
|
||||
),
|
||||
],
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(l10n.p_enable_ep_attestation_desc),
|
||||
]
|
||||
.map((e) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: e,
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ import '../features.dart' as features;
|
||||
import '../keys.dart' as keys;
|
||||
import '../models.dart';
|
||||
import 'add_fingerprint_dialog.dart';
|
||||
import 'enterprise_attestation_dialog.dart';
|
||||
import 'pin_dialog.dart';
|
||||
|
||||
bool passkeysShowActionsNotifier(FidoState state) {
|
||||
@ -50,6 +51,12 @@ Widget _fidoBuildActions(BuildContext context, DeviceNode node, FidoState state,
|
||||
Theme.of(context).colorScheme;
|
||||
final authBlocked = state.pinBlocked;
|
||||
|
||||
final enterpriseAttestation = state.enterpriseAttestation;
|
||||
|
||||
final canEnableEnterpriseAttestation = state.enterpriseAttestation == false &&
|
||||
!(state.alwaysUv && !state.hasPin) &&
|
||||
!(!state.unlocked && state.hasPin);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
if (fingerprints != null)
|
||||
@ -115,8 +122,27 @@ Widget _fidoBuildActions(BuildContext context, DeviceNode node, FidoState state,
|
||||
}
|
||||
: null,
|
||||
),
|
||||
],
|
||||
if (enterpriseAttestation != null)
|
||||
ActionListItem(
|
||||
key: keys.enableEnterpriseAttestation,
|
||||
feature: features.enableEnterpriseAttestation,
|
||||
icon: const Icon(Symbols.local_police),
|
||||
title: l10n.s_ep_attestation,
|
||||
subtitle:
|
||||
enterpriseAttestation ? l10n.s_enabled : l10n.s_disabled,
|
||||
onTap: canEnableEnterpriseAttestation
|
||||
? (context) {
|
||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||
showBlurDialog(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
EnableEnterpriseAttestationDialog(node.path),
|
||||
);
|
||||
}
|
||||
: null,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -30,6 +30,9 @@
|
||||
"s_delete": "Löschen",
|
||||
"s_move": null,
|
||||
"s_quit": "Beenden",
|
||||
"s_enable": null,
|
||||
"s_enabled": null,
|
||||
"s_disabled": null,
|
||||
"s_status": null,
|
||||
"s_unlock": "Entsperren",
|
||||
"s_calculate": "Berechnen",
|
||||
@ -301,6 +304,10 @@
|
||||
"common_pin": {}
|
||||
}
|
||||
},
|
||||
"s_ep_attestation": null,
|
||||
"s_ep_attestation_enabled": null,
|
||||
"s_enable_ep_attestation": null,
|
||||
"p_enable_ep_attestation_desc": null,
|
||||
"s_pin_required": null,
|
||||
"p_pin_required_desc": null,
|
||||
"l_piv_pin_blocked": null,
|
||||
|
@ -30,6 +30,9 @@
|
||||
"s_delete": "Delete",
|
||||
"s_move": "Move",
|
||||
"s_quit": "Quit",
|
||||
"s_enable": "Enable",
|
||||
"s_enabled": "Enabled",
|
||||
"s_disabled": "Disabled",
|
||||
"s_status": "Status",
|
||||
"s_unlock": "Unlock",
|
||||
"s_calculate": "Calculate",
|
||||
@ -301,6 +304,10 @@
|
||||
"common_pin": {}
|
||||
}
|
||||
},
|
||||
"s_ep_attestation": "Enterprise Attestation",
|
||||
"s_ep_attestation_enabled": "Enterprise Attestation enabled",
|
||||
"s_enable_ep_attestation": "Enable Enterprise Attestation",
|
||||
"p_enable_ep_attestation_desc": "This will enable Enterprise Attestation, allowing authorized domains to uniquely identify your YubiKey.",
|
||||
"s_pin_required": "PIN required",
|
||||
"p_pin_required_desc": "The action you are about to perform requires the PIV PIN to be entered.",
|
||||
"l_piv_pin_blocked": "Blocked, use PUK to reset",
|
||||
|
@ -30,6 +30,9 @@
|
||||
"s_delete": "Supprimer",
|
||||
"s_move": "Déplacer",
|
||||
"s_quit": "Quitter",
|
||||
"s_enable": null,
|
||||
"s_enabled": null,
|
||||
"s_disabled": null,
|
||||
"s_status": "État",
|
||||
"s_unlock": "Déverrouiller",
|
||||
"s_calculate": "Calculer",
|
||||
@ -301,6 +304,10 @@
|
||||
"common_pin": {}
|
||||
}
|
||||
},
|
||||
"s_ep_attestation": null,
|
||||
"s_ep_attestation_enabled": null,
|
||||
"s_enable_ep_attestation": null,
|
||||
"p_enable_ep_attestation_desc": null,
|
||||
"s_pin_required": "PIN requis",
|
||||
"p_pin_required_desc": "L'action que vous allez effectuer nécessite la saisie du PIN PIV.",
|
||||
"l_piv_pin_blocked": "Bloqué, utilisez PUK pour réinitialiser",
|
||||
|
@ -30,6 +30,9 @@
|
||||
"s_delete": "削除",
|
||||
"s_move": "移動",
|
||||
"s_quit": "終了",
|
||||
"s_enable": null,
|
||||
"s_enabled": null,
|
||||
"s_disabled": null,
|
||||
"s_status": "ステータス",
|
||||
"s_unlock": "ロック解除",
|
||||
"s_calculate": "計算",
|
||||
@ -301,6 +304,10 @@
|
||||
"common_pin": {}
|
||||
}
|
||||
},
|
||||
"s_ep_attestation": null,
|
||||
"s_ep_attestation_enabled": null,
|
||||
"s_enable_ep_attestation": null,
|
||||
"p_enable_ep_attestation_desc": null,
|
||||
"s_pin_required": "PINが必要",
|
||||
"p_pin_required_desc": "実行しようとしているアクションでは、PIV PINを入力する必要があります。",
|
||||
"l_piv_pin_blocked": "ブロックされています。リセットするにはPUKを使用してください",
|
||||
|
@ -30,6 +30,9 @@
|
||||
"s_delete": "Usuń",
|
||||
"s_move": null,
|
||||
"s_quit": "Wyjdź",
|
||||
"s_enable": null,
|
||||
"s_enabled": null,
|
||||
"s_disabled": null,
|
||||
"s_status": "Status",
|
||||
"s_unlock": "Odblokuj",
|
||||
"s_calculate": "Oblicz",
|
||||
@ -301,6 +304,10 @@
|
||||
"common_pin": {}
|
||||
}
|
||||
},
|
||||
"s_ep_attestation": null,
|
||||
"s_ep_attestation_enabled": null,
|
||||
"s_enable_ep_attestation": null,
|
||||
"p_enable_ep_attestation_desc": null,
|
||||
"s_pin_required": "Wymagany PIN",
|
||||
"p_pin_required_desc": "Czynność, którą zamierzasz wykonać, wymaga wprowadzenia kodu PIN PIV.",
|
||||
"l_piv_pin_blocked": "Zablokowano, użyj PUK, aby zresetować",
|
||||
|
Loading…
Reference in New Issue
Block a user