Skip to content

Commit

Permalink
Collect device selecting logic
Browse files Browse the repository at this point in the history
  • Loading branch information
DennisDyallo committed Aug 7, 2024
1 parent 7db54c5 commit 8ce0fde
Showing 1 changed file with 50 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ public static IYubiKeyDevice RenewDeviceEnumeration(int serialNumber)

try
{
return TestDev
.GetTestDevices()
.Single(d => d.SerialNumber == serialNumber);
return TestDev.GetBySerial(serialNumber);
}
catch (InvalidOperationException)
{
Expand All @@ -61,12 +59,12 @@ public static IYubiKeyDevice RenewDeviceEnumeration(int serialNumber)
/// <exception cref="InvalidOperationException">
/// Thrown when the input sequence did not contain a valid test device.
/// </exception>
public static IYubiKeyDevice SelectRequiredTestDevice(
public static IYubiKeyDevice SelectByStandardTestDevice(
this IEnumerable<IYubiKeyDevice> yubiKeys,
StandardTestDevice testDevice)
{
IEnumerable<IYubiKeyDevice> yubiKeyDevices = yubiKeys as IYubiKeyDevice[] ?? yubiKeys.ToArray();
if (!yubiKeyDevices.Any())
var devices = yubiKeys as IYubiKeyDevice[] ?? yubiKeys.ToArray();
if (!devices.Any())
{
throw new InvalidOperationException("Could not find any connected Yubikeys");
}
Expand All @@ -75,32 +73,67 @@ public static IYubiKeyDevice SelectRequiredTestDevice(
{
StandardTestDevice.Fw3 => SelectDevice(3),
StandardTestDevice.Fw4Fips => SelectDevice(4, isFipsSeries: true),
StandardTestDevice.Fw5 => SelectDevice(5, formFactor: null),
StandardTestDevice.Fw5 => SelectDevice(5),
StandardTestDevice.Fw5Fips => SelectDevice(5, formFactor: FormFactor.UsbAKeychain, isFipsSeries: true),
StandardTestDevice.Fw5Bio => SelectDevice(5, formFactor: FormFactor.UsbABiometricKeychain),
_ => throw new ArgumentException("Invalid test device value.", nameof(testDevice)),
};

IYubiKeyDevice SelectDevice(int majorVersion, FormFactor? formFactor = null, bool isFipsSeries = false)
{
IYubiKeyDevice device = null!;
try
{
return yubiKeyDevices.First(d =>
d.FirmwareVersion.Major == majorVersion &&
(formFactor is null || d.FormFactor == formFactor) &&
d.IsFipsSeries == isFipsSeries);
bool MatchingDeviceSelector(IYubiKeyDevice d) =>
d.FirmwareVersion.Major == majorVersion &&
(formFactor is null || d.FormFactor == formFactor) &&
d.IsFipsSeries == isFipsSeries;

device = devices.First(MatchingDeviceSelector);
}
catch (InvalidOperationException)
{
string connectedDevices = yubiKeyDevices.Any()
? "Connected devices: " + string.Join(", ",
yubiKeyDevices.Select(y => $"{{{y.FirmwareVersion}, {y.FormFactor}}}"))
: string.Empty;
throw new DeviceNotFoundException(
$"Target test device not found ({testDevice}). ({connectedDevices})");
ThrowDeviceNotFoundException($"Target test device not found ({testDevice})", devices);
}

return device;
}
}

public static IYubiKeyDevice SelectByMinimumVersion(
this IEnumerable<IYubiKeyDevice> yubiKeys,
FirmwareVersion minimumFirmwareVersion)
{
var devices = yubiKeys as IYubiKeyDevice[] ?? yubiKeys.ToArray();
if (!devices.Any())
{
throw new InvalidOperationException("Could not find any connected Yubikeys");
}

var device = devices.FirstOrDefault(d => d.FirmwareVersion >= minimumFirmwareVersion);
if (device is null)
{
ThrowDeviceNotFoundException("No matching YubiKey found", devices);
}

return device!;
}

private static void ThrowDeviceNotFoundException(string errorMessage,IYubiKeyDevice[] devices)
{
var connectedDevicesText = FormatConnectedDevices(devices);
throw new DeviceNotFoundException($"{errorMessage}. {connectedDevicesText}");
}

private static string FormatConnectedDevices(IReadOnlyCollection<IYubiKeyDevice> devices)
{
var deviceText =
devices.Select(y => $"{{{y.FirmwareVersion}, {y.FormFactor}, IsFipsSeries: {y.IsFipsSeries}}}");

return devices.Any()
? $"Connected devices: {string.Join(", ", deviceText)}"
: string.Empty;
}
}

// Custom test exception inheriting from InvalidOperationException as some test code depends on InvalidOperationExceptions
Expand Down

0 comments on commit 8ce0fde

Please sign in to comment.