internal static Response.SecondFactorMethod ChooseSecondFactorMethod(Response.SecondFactor secondFactor, IUi ui) { var methods = secondFactor.Methods; if (methods == null || methods.Count == 0) { throw new InternalErrorException("Logical error: should be called with non empty list of methods"); } var availableMethods = new List <MfaMethod>(); foreach (var m in methods.Keys) { switch (m) { case Response.SecondFactorMethod.GoogleAuth: availableMethods.Add(MfaMethod.GoogleAuth); break; case Response.SecondFactorMethod.Email: availableMethods.Add(MfaMethod.Email); break; case Response.SecondFactorMethod.Duo: availableMethods.Add(MfaMethod.Duo); break; case Response.SecondFactorMethod.YubiKey: availableMethods.Add(MfaMethod.YubiKey); break; case Response.SecondFactorMethod.U2f: #if NETFRAMEWORK availableMethods.Add(MfaMethod.U2f); #endif break; case Response.SecondFactorMethod.RememberMe: break; case Response.SecondFactorMethod.DuoOrg: availableMethods.Add(MfaMethod.DuoOrg); break; } } // Only unsupported methods were found if (availableMethods.Count == 0) { var unsupported = string.Join(", ", methods.Keys); throw new UnsupportedFeatureException($"Seconds factor methods [{unsupported}] are not supported"); } // Cancel is always available availableMethods.Add(MfaMethod.Cancel); return(ui.ChooseMfaMethod(availableMethods.ToArray()) switch { MfaMethod.Cancel => throw MakeCancelledMfaError(), MfaMethod.GoogleAuth => Response.SecondFactorMethod.GoogleAuth, MfaMethod.Email => Response.SecondFactorMethod.Email, MfaMethod.Duo => Response.SecondFactorMethod.Duo, MfaMethod.YubiKey => Response.SecondFactorMethod.YubiKey, MfaMethod.U2f => Response.SecondFactorMethod.U2f, MfaMethod.DuoOrg => Response.SecondFactorMethod.DuoOrg, _ => throw new InternalErrorException("The user responded with invalid input") });