Use enhanced enums to replace enum extensions.

This commit is contained in:
Dain Nilsson 2022-05-12 10:14:11 +02:00
parent af92068a75
commit 168429e29e
No known key found for this signature in database
GPG Key ID: F04367096FBA95E8
5 changed files with 55 additions and 101 deletions

View File

@ -11,27 +11,17 @@ const _listEquality = ListEquality();
enum Availability { enabled, disabled, unsupported }
enum Application { oath, fido, otp, piv, openpgp, hsmauth, management }
enum Application {
oath('Authenticator'),
fido('WebAuthn'),
otp('One-Time Passwords'),
piv('Certificates'),
openpgp('OpenPGP'),
hsmauth('YubiHSM Auth'),
management('Toggle Applications');
extension Applications on Application {
String get displayName {
switch (this) {
case Application.oath:
return 'Authenticator';
case Application.fido:
return 'WebAuthn';
case Application.otp:
return 'One-Time Passwords';
case Application.piv:
return 'Certificates';
case Application.openpgp:
return 'OpenPGP';
case Application.hsmauth:
return 'YubiHSM Auth';
case Application.management:
return 'Toggle applications';
}
}
final String displayName;
const Application(this.displayName);
bool _inCapabilities(int capabilities) {
switch (this) {

View File

@ -8,7 +8,33 @@ part 'models.g.dart';
enum Transport { usb, nfc }
enum UsbInterface { otp, fido, ccid }
enum UsbInterface {
otp(0x01),
fido(0x02),
ccid(0x04);
final int value;
const UsbInterface(this.value);
static int forCapabilites(int capabilities) {
var interfaces = 0;
if (capabilities & Capability.otp.value != 0) {
interfaces |= UsbInterface.otp.value;
}
if (capabilities & (Capability.u2f.value | Capability.fido2.value) != 0) {
interfaces |= UsbInterface.fido.value;
}
if (capabilities &
(Capability.openpgp.value |
Capability.piv.value |
Capability.oath.value |
Capability.hsmauth.value) !=
0) {
interfaces |= UsbInterface.ccid.value;
}
return interfaces;
}
}
@JsonEnum(alwaysCreate: true)
enum UsbPid {
@ -45,10 +71,8 @@ enum UsbPid {
@JsonValue(0x0407)
yk4OtpFidoCcid,
@JsonValue(0x0410)
ykpOtpFido,
}
ykpOtpFido;
extension UsbPids on UsbPid {
int get value => _$UsbPidEnumMap[this]!;
String get displayName {
@ -80,38 +104,6 @@ extension UsbPids on UsbPid {
}
}
extension UsbInterfaces on UsbInterface {
int get value {
switch (this) {
case UsbInterface.otp:
return 0x01;
case UsbInterface.fido:
return 0x02;
case UsbInterface.ccid:
return 0x04;
}
}
static int forCapabilites(int capabilities) {
var interfaces = 0;
if (capabilities & Capability.otp.value != 0) {
interfaces |= UsbInterface.otp.value;
}
if (capabilities & (Capability.u2f.value | Capability.fido2.value) != 0) {
interfaces |= UsbInterface.fido.value;
}
if (capabilities &
(Capability.openpgp.value |
Capability.piv.value |
Capability.oath.value |
Capability.hsmauth.value) !=
0) {
interfaces |= UsbInterface.ccid.value;
}
return interfaces;
}
}
@freezed
class Version with _$Version {
const Version._();

View File

@ -65,7 +65,7 @@ class UsbDeviceNotifier extends StateNotifier<List<UsbYubiKeyNode>> {
var scan = await _rpc.command('scan', ['usb']);
final pids = {
for (var e in (scan['pids'] as Map).entries)
UsbPids.fromValue(int.parse(e.key)): e.value as int
UsbPid.fromValue(int.parse(e.key)): e.value as int
};
final numDevices = pids.values.fold<int>(0, (a, b) => a + b);
if (_usbState != scan['state'] || state.length != numDevices) {
@ -78,7 +78,7 @@ class UsbDeviceNotifier extends StateNotifier<List<UsbYubiKeyNode>> {
final path = ['usb', id];
final deviceResult = await _rpc.command('get', path);
final deviceData = deviceResult['data'];
final pid = UsbPids.fromValue(deviceData['pid'] as int);
final pid = UsbPid.fromValue(deviceData['pid'] as int);
usbDevices.add(DeviceNode.usbYubiKey(
DevicePath(path),
deviceData['name'],

View File

@ -24,46 +24,18 @@ enum FormFactor {
usbCBio,
}
enum Capability { otp, piv, oath, openpgp, hsmauth, u2f, fido2 }
enum Capability {
otp(0x001, 'OTP'),
piv(0x010, 'PIV'),
oath(0x020, 'OATH'),
openpgp(0x008, 'OpenPGP'),
hsmauth(0x100, 'YubiHSM Auth'),
u2f(0x002, 'FIDO U2F'),
fido2(0x200, 'FIDO2');
extension CapabilityExtension on Capability {
int get value {
switch (this) {
case Capability.otp:
return 0x001;
case Capability.u2f:
return 0x002;
case Capability.openpgp:
return 0x008;
case Capability.piv:
return 0x010;
case Capability.oath:
return 0x020;
case Capability.hsmauth:
return 0x100;
case Capability.fido2:
return 0x200;
}
}
String get name {
switch (this) {
case Capability.otp:
return 'OTP';
case Capability.u2f:
return 'FIDO U2F';
case Capability.openpgp:
return 'OpenPGP';
case Capability.piv:
return 'PIV';
case Capability.oath:
return 'OATH';
case Capability.hsmauth:
return 'YubiHSM Auth';
case Capability.fido2:
return 'FIDO2';
}
}
final int value;
final String name;
const Capability(this.value, this.name);
}
@freezed

View File

@ -132,7 +132,7 @@ class _ManagementScreenState extends ConsumerState<ManagementScreen> {
void initState() {
super.initState();
_enabled = widget.deviceData.info.config.enabledCapabilities;
_interfaces = UsbInterfaces.forCapabilites(
_interfaces = UsbInterface.forCapabilites(
widget.deviceData.info.config.enabledCapabilities[Transport.usb] ?? 0);
}
@ -153,11 +153,11 @@ class _ManagementScreenState extends ConsumerState<ManagementScreen> {
final bool reboot;
if (widget.deviceData.node is UsbYubiKeyNode) {
// Reboot if USB device descriptor is changed.
final oldInterfaces = UsbInterfaces.forCapabilites(
final oldInterfaces = UsbInterface.forCapabilites(
widget.deviceData.info.config.enabledCapabilities[Transport.usb] ??
0);
final newInterfaces =
UsbInterfaces.forCapabilites(_enabled[Transport.usb] ?? 0);
UsbInterface.forCapabilites(_enabled[Transport.usb] ?? 0);
reboot = oldInterfaces != newInterfaces;
} else {
reboot = false;
@ -250,7 +250,7 @@ class _ManagementScreenState extends ConsumerState<ManagementScreen> {
} else {
_canSave = _interfaces != 0 &&
_interfaces !=
UsbInterfaces.forCapabilites(widget
UsbInterface.forCapabilites(widget
.deviceData
.info
.config