public async Task ThenAnAuthorisedResponseIsReturnedForAValidUser() { authRepository = new Mock <IAuthRecordRepository>(MockBehavior.Strict); gatewayRepository = new Mock <IGatewayRepository>(MockBehavior.Strict); GatewayUser gatewayUser = new GatewayUser() { Id = "1", EmpRef = empRef, GatewayId = gatewayId, Name = "Test", Password = string.Empty, Require2SV = true }; gatewayRepository.Setup(x => x.GetGatewayRecordsForId(gatewayId)) .ReturnsAsync(new List <GatewayUser> { gatewayUser }) ; var sut = new AuthenticationService(authRepository.Object, gatewayRepository.Object); var result = await sut.IsAuthorized(gatewayId, empRef); result.Should().BeTrue(); }
public async Task <IActionResult> CreateAccountAndBind(SignInViewModel model) { var app = (await _apiService.AppInfoAsync(model.AppId)).App; bool exists = _dbContext.UserEmails.Any(t => t.EmailAddress == model.UserDetail.Email.ToLower()); if (exists) { ModelState.AddModelError(string.Empty, $"An user with email '{model.UserDetail.Email}' already exists!"); model.AppImageUrl = app.IconPath; model.CanFindAnAccountWithEmail = false; model.Provider = _authProviders.SingleOrDefault(t => t.GetName().ToLower() == model.ProviderName.ToLower()); return(View(nameof(SignIn), model)); } var user = new GatewayUser { UserName = model.UserDetail.Email + $".from.{model.ProviderName}.com", Email = model.UserDetail.Email, NickName = model.UserDetail.Name, PreferedLanguage = model.PreferedLanguage, IconFilePath = Values.DefaultImagePath, RegisterIPAddress = HttpContext.Connection.RemoteIpAddress.ToString() }; var result = await _userManager.CreateAsync(user); if (result.Succeeded) { var primaryMail = new UserEmail { EmailAddress = model.UserDetail.Email.ToLower(), OwnerId = user.Id, ValidateToken = Guid.NewGuid().ToString("N") }; _dbContext.UserEmails.Add(primaryMail); await _dbContext.SaveChangesAsync(); var link = new ThirdPartyAccount { OwnerId = user.Id, ProviderName = model.ProviderName, OpenId = model.UserDetail.Id }; _dbContext.ThirdPartyAccounts.Add(link); await _dbContext.SaveChangesAsync(); await _signInManager.SignInAsync(user, isPersistent : true); await _authLogger.LogAuthRecord(user.Id, HttpContext, true, model.AppId); return(await _authManager.FinishAuth(user, model, app.ForceConfirmation)); } else { model.AppImageUrl = app.IconPath; model.CanFindAnAccountWithEmail = await _dbContext.UserEmails.AnyAsync(t => t.EmailAddress.ToLower() == model.UserDetail.Email.ToLower()); model.Provider = _authProviders.SingleOrDefault(t => t.GetName().ToLower() == model.ProviderName.ToLower()); ModelState.AddModelError(string.Empty, result.Errors.First().Description); return(View(nameof(SignIn), model)); } }
public async Task <IActionResult> FinishAuth(GatewayUser user, FinishAuthInfo model, bool forceGrant, bool trusted) { var authorized = await HasAuthorizedApp(user, model.AppId); if (!authorized && trusted) { // Unauthorized. But viewing a trusted app. Just auto auth him. await GrantTargetApp(user, model.AppId); authorized = true; } if (authorized && forceGrant != true) { // Dont need to auth, and the user don't force to auth. var pack = await GeneratePack(user, model.AppId); var url = new AiurUrl(GetRegexRedirectUri(model.RedirectUri), new AuthResultAddressModel { Code = pack.Code, State = model.State }); return(new RedirectResult(url.ToString())); } else { // Need to do the auth logic. var url = new AiurUrl(string.Empty, "OAuth", nameof(OAuthController.AuthorizeConfirm), new FinishAuthInfo { AppId = model.AppId, RedirectUri = model.RedirectUri, State = model.State }); return(new RedirectResult(url.ToString())); } }
public Task <bool> HasAuthorizedApp(GatewayUser user, string appId) { return(_dbContext .LocalAppGrant .Where(t => t.AppId == appId) .AnyAsync(t => t.GatewayUserId == user.Id)); }
public async Task <IActionResult> CreateAccountAndBind(SignInViewModel model) { if (string.IsNullOrWhiteSpace(model.UserDetail.Email)) { model.UserDetail.Email = model.UserDetail.Name + $"@from.{model.ProviderName}.com"; } bool exists = _dbContext.UserEmails.Any(t => t.EmailAddress == model.UserDetail.Email.ToLower()); if (exists) { // TODO: Handle. throw new AiurAPIModelException(ErrorType.HasDoneAlready, $"An user with email '{model.UserDetail.Email}' already exists!"); } var app = (await _apiService.AppInfoAsync(model.AppId)).App; var user = new GatewayUser { UserName = model.UserDetail.Email + $".from.{model.ProviderName}.com", Email = model.UserDetail.Email, NickName = model.UserDetail.Name, PreferedLanguage = model.PreferedLanguage, IconFilePath = Values.DefaultImagePath, RegisterIPAddress = HttpContext.Connection.RemoteIpAddress.ToString() }; var result = await _userManager.CreateAsync(user); if (result.Succeeded) { var primaryMail = new UserEmail { EmailAddress = model.UserDetail.Email.ToLower(), OwnerId = user.Id, ValidateToken = Guid.NewGuid().ToString("N") }; _dbContext.UserEmails.Add(primaryMail); await _dbContext.SaveChangesAsync(); var link = new ThirdPartyAccount { OwnerId = user.Id, ProviderName = model.ProviderName, OpenId = model.UserDetail.Id }; _dbContext.ThirdPartyAccounts.Add(link); await _dbContext.SaveChangesAsync(); await _signInManager.SignInAsync(user, isPersistent : true); await _authLogger.LogAuthRecord(user.Id, HttpContext, true, model.AppId); return(await _authManager.FinishAuth(user, model, app.ForceConfirmation)); } else { // TODO: Handle throw new AiurAPIModelException(ErrorType.HasDoneAlready, result.Errors.First().Description); } }
public Gateway(GatewayUser p_gatewayUser, double p_accountMaxTradeValueInCurrency = Double.NaN, double p_accountMaxEstimatedValueSumRecentlyAllowed = Double.NaN) // gateWayUser will be fixed. We don't allow to change it later. { IsConnected = false; GatewayUser = p_gatewayUser; if (!Double.IsNaN(p_accountMaxTradeValueInCurrency)) m_IbAccountMaxTradeValueInCurrency = p_accountMaxTradeValueInCurrency; if (!Double.IsNaN(p_accountMaxEstimatedValueSumRecentlyAllowed)) m_IbAccountMaxEstimatedValueSumRecentlyAllowed = p_accountMaxEstimatedValueSumRecentlyAllowed; }
public async Task <IActionResult> Register(RegisterViewModel model) { if (!_captcha.ValidateCaptchaCode(model.CaptchaCode, HttpContext.Session)) { ModelState.AddModelError(string.Empty, "Invalid captacha code!"); } var app = (await _apiService.AppInfoAsync(model.AppId)).App; if (!ModelState.IsValid) { model.Recover(app.AppName, app.IconPath); return(View(model)); } bool exists = _dbContext.UserEmails.Any(t => t.EmailAddress == model.Email.ToLower()); if (exists) { ModelState.AddModelError(string.Empty, $"An user with email '{model.Email}' already exists!"); model.Recover(app.AppName, app.IconPath); return(View(model)); } var user = new GatewayUser { UserName = model.Email, Email = model.Email, NickName = model.Email.Split('@')[0], PreferedLanguage = model.PreferedLanguage, IconFilePath = Values.DefaultImagePath, RegisterIPAddress = HttpContext.Connection.RemoteIpAddress.ToString() }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { var primaryMail = new UserEmail { EmailAddress = model.Email.ToLower(), OwnerId = user.Id, ValidateToken = Guid.NewGuid().ToString("N") }; _dbContext.UserEmails.Add(primaryMail); await _dbContext.SaveChangesAsync(); // Send him an confirmation email here: await _emailSender.SendConfirmation(user.Id, primaryMail.EmailAddress, primaryMail.ValidateToken); await _authLogger.LogAuthRecord(user.Id, HttpContext.Connection.RemoteIpAddress.ToString(), true, app.AppId); await _signInManager.SignInAsync(user, isPersistent : true); return(await _authManager.FinishAuth(user, model, app.ForceConfirmation)); } AddErrors(result); model.Recover(app.AppName, app.IconPath); return(View(model)); }
public async Task GrantTargetApp(GatewayUser user, string appId) { if (!await HasAuthorizedApp(user, appId)) { var appGrant = new AppGrant { AppID = appId, GatewayUserId = user.Id }; _dbContext.LocalAppGrant.Add(appGrant); await _dbContext.SaveChangesAsync(); } }
private async Task <OAuthPack> GeneratePack(GatewayUser user, string appId) { var pack = new OAuthPack { Code = Math.Abs(Guid.NewGuid().GetHashCode()), UserId = user.Id, ApplyAppId = appId }; await _dbContext.OAuthPack.AddAsync(pack); await _dbContext.SaveChangesAsync(); return(pack); }
public async Task <(string, string)> LoadSharedKeyAndQrCodeUriAsync(GatewayUser user) { var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); if (string.IsNullOrEmpty(unformattedKey)) { await _userManager.ResetAuthenticatorKeyAsync(user); unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); } var twoFAKey = string.Join(' ', unformattedKey.SplitInParts(4)); var twoFAQRUri = GenerateQrCodeUri(user.Email, unformattedKey); return(twoFAKey, twoFAQRUri); }
public async Task <IActionResult> FinishAuth(GatewayUser user, FinishAuthInfo model, bool forceGrant) { if (await HasAuthorizedApp(user, model.AppId) && forceGrant == false) { var pack = await GeneratePack(user, model.AppId); var url = new AiurUrl(GetRegexRedirectUri(model.RedirectUri), new AuthResultAddressModel { Code = pack.Code, State = model.State }); return(new RedirectResult(url.ToString())); } else { var url = new AiurUrl("", "OAuth", nameof(OAuthController.AuthorizeConfirm), new FinishAuthInfo { AppId = model.AppId, RedirectUri = model.RedirectUri, State = model.State }); return(new RedirectResult(url.ToString())); } }
internal bool IsGatewayConnected(GatewayUser p_ibGatewayUserToTrade) { var gateway = m_gateways.FirstOrDefault(r => r.GatewayUser == p_ibGatewayUserToTrade); if (gateway == null) return false; return (gateway.IsConnected); }
public async Task <bool> HasAuthorizedApp(GatewayUser user, string appId) { return(await _dbContext.LocalAppGrant.AnyAsync(t => t.AppID == appId && t.GatewayUserId == user.Id)); }
public async Task <IActionResult> Register(RegisterViewModel model) { if (!_allowRegistering) { return(Unauthorized()); } if (!_captcha.Validate(model.CaptchaCode, HttpContext.Session)) { ModelState.AddModelError(string.Empty, "Invalid captcha code!"); } var app = (await _apiService.AppInfoAsync(model.AppId)).App; if (!ModelState.IsValid) { model.Recover(app.AppName, app.IconPath); return(View(model)); } bool exists = _dbContext.UserEmails.Any(t => t.EmailAddress == model.Email.ToLower()); if (exists) { ModelState.AddModelError(string.Empty, $"An user with email '{model.Email}' already exists!"); model.Recover(app.AppName, app.IconPath); return(View(model)); } var countStart = DateTime.UtcNow - TimeSpan.FromDays(1); var requestIp = HttpContext.Connection.RemoteIpAddress?.ToString(); if (await _dbContext.Users .Where(t => t.RegisterIPAddress == requestIp) .Where(t => t.AccountCreateTime > countStart) .CountAsync() > 5) { ModelState.AddModelError(string.Empty, "You can't create more than 5 accounts in one day!"); model.Recover(app.AppName, app.IconPath); return(View(model)); } var user = new GatewayUser { UserName = model.Email, Email = model.Email, NickName = model.Email.Split('@')[0], PreferedLanguage = model.PreferedLanguage, IconFilePath = AuthValues.DefaultImagePath, RegisterIPAddress = requestIp }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { var primaryMail = new UserEmail { EmailAddress = model.Email.ToLower(), OwnerId = user.Id, ValidateToken = Guid.NewGuid().ToString("N"), LastSendTime = DateTime.UtcNow }; await _dbContext.UserEmails.AddAsync(primaryMail); await _dbContext.SaveChangesAsync(); // Send him an confirmation email here: _cannonService.FireAsync <ConfirmationEmailSender>(async(sender) => { await sender.SendConfirmation(user.Id, primaryMail.EmailAddress, primaryMail.ValidateToken); }); await _authLogger.LogAuthRecord(user.Id, HttpContext, true, app.AppId); await _signInManager.SignInAsync(user, isPersistent : true); return(await _authManager.FinishAuth(user, model, app.ForceConfirmation, app.TrustedApp)); } AddErrors(result); model.Recover(app.AppName, app.IconPath); return(View(model)); }
internal int PlaceOrder(GatewayUser p_gatewayUserToTrade, double p_portfolioMaxTradeValueInCurrency, double p_portfolioMinTradeValueInCurrency, Contract p_contract, TransactionType p_transactionType, double p_volume, OrderExecution p_orderExecution, OrderTimeInForce p_orderTif, double? p_limitPrice, double? p_stopPrice, bool p_isSimulatedTrades, StringBuilder p_detailedReportSb) { if (!m_isReady) return -1; Gateway userGateway = m_gateways.FirstOrDefault(r => r.GatewayUser == p_gatewayUserToTrade); if (userGateway == null) { Utils.Logger.Error($"ERROR. PlacingOrder(). GatewayUserToTrade {p_gatewayUserToTrade} is not found among connected Gateways."); return -1; } var rtPrices = new Dictionary<int, PriceAndTime>() { { TickType.MID, new PriceAndTime() } }; // MID is the most honest price. LAST may happened 1 hours ago m_mainGateway.BrokerWrapper.GetMktDataSnapshot(p_contract, ref rtPrices); int virtualOrderId = userGateway.PlaceOrder(p_portfolioMaxTradeValueInCurrency, p_portfolioMinTradeValueInCurrency, p_contract, p_transactionType, p_volume, p_orderExecution, p_orderTif, p_limitPrice, p_stopPrice, rtPrices[TickType.MID].Price, p_isSimulatedTrades, p_detailedReportSb); return virtualOrderId; }
internal bool WaitOrder(GatewayUser p_gatewayUserToTrade, int p_virtualOrderId, bool p_isSimulatedTrades) { if (!m_isReady) return false; Gateway userGateway = m_gateways.FirstOrDefault(r => r.GatewayUser == p_gatewayUserToTrade); if (userGateway == null) return false; return userGateway.WaitOrder(p_virtualOrderId, p_isSimulatedTrades); }
async void ReconnectToGateways() { Utils.Logger.Info("GatewaysWatcher:ReconnectToGateways() BEGIN"); m_mainGateway = null; try { Gateway gateway1, gateway2; if (!Controller.IsRunningAsLocalDevelopment()) { gateway1 = new Gateway(GatewayUser.GyantalMain) { VbAccountsList = "U407941", SocketPort = (int)GatewayUserPort.GyantalMain, BrokerConnectionClientID = 41}; gateway2 = new Gateway(GatewayUser.CharmatSecondary, 200000.0 /* HarryLong is played 100K, double it */, 1000000.0 /* 1M */ ) { VbAccountsList = "U988767", SocketPort = (int)GatewayUserPort.CharmatSecondary, BrokerConnectionClientID = 42}; //Gateway gateway2 = new Gateway() { GatewayUser = GatewayUser.CharmatWifeMain, VbAccountsList = "U1034066", SocketPort = 7302 }; m_mainGatewayUser = GatewayUser.CharmatSecondary; } else { gateway1 = new Gateway(GatewayUser.GyantalMain) { VbAccountsList = "U407941", SocketPort = 7301 }; // correct one gateway2 = null; m_mainGatewayUser = GatewayUser.GyantalMain; } m_gateways = new List<Gateway>(); // delete previous Gateway connections m_gateways.Add(gateway1); if (gateway2 != null) // sometimes (for development), 1 gateway is used only m_gateways.Add(gateway2); //Task connectTask1 = Task.Factory.StartNew(ReconnectToGateway, gateway1, TaskCreationOptions.LongRunning); //Task connectTask2 = Task.Factory.StartNew(ReconnectToGateway, gateway2, TaskCreationOptions.LongRunning); var reconnectTasks = m_gateways.Select(r => Task.Factory.StartNew(ReconnectToGateway, r, TaskCreationOptions.LongRunning)); Utils.Logger.Info("GatewaysWatcher:ReconnectToGateways() reconnectTasks BEGIN"); // At the beginning: Linux had a problem to Connect sequentially on 2 separate threads. Maybe Linux DotNetCore 'Beta' implementation synchronization problem. Temporary connect sequentally. maybe doing Connection sequentially, not parallel would help foreach (var task in reconnectTasks) { Thread.Sleep(TimeSpan.FromSeconds(1)); // just for synch safety. However, if Linux has synch problem, we can have problems at order execution...!! //task.Wait(); // this gives Compiler Warning that the method is async, but there is no await in it await task; // this doesn't give Compiler Warning. } //await Task.WhenAll(reconnectTasks); // async. This threadpool thread will return to the threadpool for temporary reuse, and when tasks are ready, it will be recallade ////Task.WaitAll(connectTask1, connectTask2); // blocking wait. This thread will wait forever if needed, but we don't want to starve the threadpool Utils.Logger.Info("GatewaysWatcher:ReconnectToGateways() reconnectTasks END"); bool isAllConnected = true; foreach (var gateway in m_gateways) { if (!gateway.IsConnected) isAllConnected = false; if (gateway.GatewayUser == m_mainGatewayUser) { m_mainGateway = gateway; } } StrongAssert.True(isAllConnected, Severity.ThrowException, $"Some Gateways are not connected."); StrongAssert.True(m_mainGateway != null, Severity.ThrowException, $"Gateway for main user { m_mainGatewayUser} is not found."); Utils.Logger.Info("GatewaysWatcher is ready. Connections were successful."); m_isReady = true; // GatewaysWatcher is ready // getting prices of SPY (has dividend, but liquid) or VXX (no dividend, but less liquids) is always a must. An Agent would always look that price. So, subscribe to that on the MainGateway // see what is possible to call: // "g:\temp\_programmingTemp\TWS API_972.12(2016-02-26)\samples\CSharp\IBSamples\IBSamples.sln" //m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "VXX", SecType = "STK", Currency = "USD", Exchange = "SMART" }); //m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "SVXY", SecType = "STK", Currency = "USD", Exchange = "SMART" }); ////m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "SPY", SecType = "STK", Currency = "USD", Exchange = "SMART" }); // for TotM forecast, but it is not needed just yet //m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "RUT", SecType = "IND", Currency = "USD", Exchange = "RUSSELL", LocalSymbol="RUT" }); //m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "UWM", SecType = "STK", Currency = "USD", Exchange = "SMART" }); //m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "TWM", SecType = "STK", Currency = "USD", Exchange = "SMART" }); // for NeuralSniffer m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("^RUT")); m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("UWM")); m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("TWM")); // for UberVXX m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("VXX")); m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("SVXY")); //m_mainGateway.BrokerWrapper.ReqMktDataStream(new Contract() { Symbol = "SPY", SecType = "STK", Currency = "USD", Exchange = "SMART" }); // for TotM forecast, but it is not needed just yet // for HarryLong m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("UVXY")); m_mainGateway.BrokerWrapper.ReqMktDataStream(VBrokerUtils.ParseSqTickerToContract("TMV")); } catch (Exception e) { Utils.Logger.Info("GatewaysWatcher:ReconnectToGateways() in catching exception."); HealthMonitorMessage.SendException("ReConnectToGateways Thread", e, HealthMonitorMessageID.ReportErrorFromVirtualBroker); } Utils.Logger.Info("GatewaysWatcher:ReconnectToGateways() END"); }
internal bool GetVirtualOrderExecutionInfo(GatewayUser p_gatewayUserToTrade, int p_virtualOrderId, ref OrderStatus orderStatus, ref double executedVolume, ref double executedAvgPrice, ref DateTime executionTime, bool p_isSimulatedTrades) { if (!m_isReady) return false; Gateway userGateway = m_gateways.FirstOrDefault(r => r.GatewayUser == p_gatewayUserToTrade); if (userGateway == null) return false; return userGateway.GetVirtualOrderExecutionInfo(p_virtualOrderId, ref orderStatus, ref executedVolume, ref executedAvgPrice, ref executionTime, p_isSimulatedTrades); }