public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime, IRuntimeConfigLoader runtimeConfigLoader) { applicationLifetime.ApplicationStopping.Register(OnServerStopRequested); applicationLifetime.ApplicationStopped.Register(OnServerStopped); // globlization app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture(System.Globalization.CultureInfo.InvariantCulture), SupportedCultures = new List <System.Globalization.CultureInfo> { System.Globalization.CultureInfo.InvariantCulture }, SupportedUICultures = new List <System.Globalization.CultureInfo> { System.Globalization.CultureInfo.InvariantCulture }, }); // config loader _runtimeConfigHolder.SetLoader(runtimeConfigLoader); // setup ms logger // app.ApplicationServices.GetRequiredService<Microsoft.Extensions.Logging.ILoggerFactory>().AddNLog(); // nginx proxy { var forwardingOptions = new ForwardedHeadersOptions() { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, RequireHeaderSymmetry = false, ForwardLimit = null, }; forwardingOptions.KnownNetworks.Clear(); forwardingOptions.KnownProxies.Clear(); app.UseForwardedHeaders(forwardingOptions); } // 503: response on exception app.UseExceptionHandler(builder => { builder.Run(async context => { var error = context.Features.Get <IExceptionHandlerFeature>(); context.RequestServices?.GetService <ILogger>()?.ForContext(this.GetType())?.Error(error?.Error ?? new Exception("No extra data"), "Service failure"); var resp = APIResponse.GeneralInternalFailure(error?.Error, !_environment.IsProduction()); await resp.WriteResponse(context).ConfigureAwait(false); }); }); // 403: always write body if unathorized app.Use(async(context, next) => { await next(); if (context.Response.StatusCode == 403) { var resp = APIResponse.BadRequest(APIErrorCode.Unauthorized); await resp.WriteResponse(context).ConfigureAwait(false); } }); // check content type app.Use(async(context, next) => { var flatPath = context.Request.Path.ToString(); if (context.Request.Method == "POST" && flatPath.StartsWith("/api/") && !flatPath.Contains("/callback/")) { if (!(context.Request.ContentType?.StartsWith("application/json") ?? false)) { var resp = APIResponse.BadRequest(APIErrorCode.InvalidContentType, "Json format is only allowed"); await resp.WriteResponse(context).ConfigureAwait(false); return; } } await next(); }); // swagger if (!_environment.IsProduction()) { app.UseSwagger(opts => { }); app.UseSwaggerUI(opts => { opts.SwaggerEndpoint("/" + ((_appConfig.Apps.RelativeApiPath).Trim('/') + "/swagger/api/swagger.json").Trim('/'), "API"); }); } // 404: redirect to index: not found, not a file, not api request app.Use(async(context, next) => { await next(); if (context.Response.StatusCode == 404) { var resp = APIResponse.BadRequest(APIErrorCode.MethodNotFound); await resp.WriteResponse(context).ConfigureAwait(false); } }); app.UseAuthentication(); app.UseCors(opts => { opts.WithMethods("GET", "POST", "OPTIONS"); opts.AllowAnyHeader(); opts.AllowAnyOrigin(); } ); app.UseMvc(); RunServices(); }
public async Task <APIResponse> LiteWallet([FromBody] LiteWalletModel model) { // validate if (BaseValidableModel.IsInvalid(model, out var errFields)) { return(APIResponse.BadRequest(errFields)); } var user = await GetUserFromDb(); var userTier = CoreLogic.User.GetTier(user); var userLocale = GetUserLocale(); var agent = GetUserAgentInfo(); if (userTier < UserTier.Tier2) { return(APIResponse.BadRequest(APIErrorCode.AccountNotVerified)); } if (model.Amount <= 0.001m || user.UserSumusWallet.BalanceGold < model.Amount) { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } // --- var timeNow = DateTime.UtcNow; // charge using (var scope = HttpContext.RequestServices.CreateScope()) { if (await CoreLogic.Finance.SumusWallet.Charge(scope.ServiceProvider, user.Id, model.Amount, SumusToken.Gold)) { try { var finHistory = new UserFinHistory() { Status = UserFinHistoryStatus.Processing, Type = UserFinHistoryType.GoldWithdraw, Source = "GOLD", SourceAmount = TextFormatter.FormatTokenAmountFixed(model.Amount), Destination = "", DestinationAmount = "", Comment = "", TimeCreated = timeNow, UserId = user.Id, }; DbContext.UserFinHistory.Add(finHistory); await DbContext.SaveChangesAsync(); var request = new WithdrawGold() { Status = EmissionRequestStatus.Requested, SumAddress = model.SumusAddress, Amount = model.Amount, TimeCreated = timeNow, UserId = user.Id, RelFinHistoryId = finHistory.Id, }; DbContext.WithdrawGold.Add(request); await DbContext.SaveChangesAsync(); // mint-sender service { var reply = await Bus.Request( MintSender.Subject.Sender.Request.Send, new MintSender.Sender.Request.Send() { Id = request.Id.ToString(), Amount = model.Amount.ToString("F18"), PublicKey = model.SumusAddress, Service = "core_gold_withdrawer", Token = "GOLD", }, MintSender.Sender.Request.SendReply.Parser, 3000 ); if (!reply.Success) { throw new Exception(reply.Error); } } return(APIResponse.Success( new LiteWalletView() { } )); } catch (Exception e) { try { await CoreLogic.Finance.SumusWallet.Refill(scope.ServiceProvider, user.Id, model.Amount, SumusToken.Gold); } catch { } Logger.Error(e, $"Failed to withdraw user {model.Amount} GOLD"); return(APIResponse.GeneralInternalFailure(e)); } } else { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } } }