// Returns a valid session or throws internal static Session LoginWithOtp(string username, string password, int keyIterationCount, OtpMethod method, ClientInfo clientInfo, IUi ui, RestClient rest) { var passcode = method switch { OtpMethod.GoogleAuth => ui.ProvideGoogleAuthPasscode(), OtpMethod.MicrosoftAuth => ui.ProvideMicrosoftAuthPasscode(), OtpMethod.Yubikey => ui.ProvideYubikeyPasscode(), _ => throw new InternalErrorException("Invalid OTP method") }; if (passcode == OtpResult.Cancel) { throw new CanceledMultiFactorException("Second factor step is canceled by the user"); } var response = PerformSingleLoginRequest(username, password, keyIterationCount, new Dictionary <string, object> { ["otp"] = passcode.Passcode }, clientInfo, rest); var session = ExtractSessionFromLoginResponse(response, keyIterationCount, clientInfo); if (session == null) { throw MakeLoginError(response); } if (passcode.RememberMe) { MarkDeviceAsTrusted(session, clientInfo, rest); } return(session); }