using Knoks.Api.Authentication; using Knoks.Api.Constraints; using Knoks.Api.Data.Dao; using Knoks.Api.Data.Interfaces; using Knoks.Api.Filters; using Knoks.Api.Logic.Interfaces; using Knoks.Api.Logic.Managers; using Knoks.Api.Specification; using Knoks.Core.Data.Dao; //using Knoks.Core.Data.Dao.Interfaces; using Knoks.Core.Data.Interfaces; using Knoks.Core.Logic.Interfaces; using Knoks.Core.Logic.Managers; using Knoks.Framework.Cryptography; using Knoks.Framework.DataAccess; using Knoks.Framework.Document; using Knoks.Framework.Security; using Knoks.Framework.Services; using Knoks.Framework.Content; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Swashbuckle.AspNetCore.Swagger; using System.Collections.Generic; using System.IO; using System.Text; using static Knoks.Api.Authentication.IdentityConsts; using Microsoft.Extensions.Hosting; namespace Knoks.Api { public class Startup { public static void Main(string[] args) { new WebHostBuilder() .UseKestrel(o => o.AddServerHeader = false) .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup() .Build() .Run(); } private const string MySecret = "MySecret"; private readonly SymmetricSecurityKey SecurityKey; public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); if (env.IsEnvironment("Development")) { // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. builder.AddApplicationInsightsSettings(developerMode: true); builder.AddUserSecrets(); } builder.AddEnvironmentVariables(); Configuration = builder.Build(); //On exception case go to project folder and run the command: ".....\Knoks.Api>dotnet user-secrets set MySecret MySuperLongAndSecuritySecret" //For EC2 dev machine example: dotnet user-secrets set MySecret 3f2977b8-1184-4f81-95f8-466f503d6086" SecurityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration[MySecret] ?? $"{MySecret} - 3f2977b8-1184-4f81-95f8-466f503d6086")); } public IConfigurationRoot Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container public void ConfigureServices(IServiceCollection services) { // Add framework services. services .AddApplicationInsightsTelemetry(Configuration) .AddCors() .AddJwtAuthentication(Configuration, SecurityKey) .AddMvc() .AddMvcOptions(o => { o.Filters.Add(typeof(GlobalExceptionFilter)); o.Filters.Add(typeof(ApiResponseResultFilter)); }); //.AddJsonOptions(o => o.SerializerSettings.ContractResolver = new JsonPropertiesResolver()); services.AddAuthorization(options => { options.AddPolicy(ApiConsumerPolicy, policy => policy.RequireClaim(ApiIdentifierClaim)); options.AddPolicy(ApiUserPolicy, policy => policy.RequireClaim(ApiIdentifierClaim).RequireClaim(UserIdClaim)); options.AddPolicy(ApiOperatorPolicy, policy => policy.RequireClaim(ApiIdentifierClaim).RequireClaim(OperatorIdClaim)); }); //-- Options configs ------------------------------------------------------------------ services.AddSingleton(provider => Configuration.Load(new JwtIssuerOptions { SigningCredentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256) })); services.AddSingleton(provider => Configuration.Load()); services.AddSingleton(provider => Configuration.Load()); services.AddSingleton(provider => Configuration.Load()); //-- ProcExecutor config -------------------------------------------------------------- services.AddSingleton(provider => new ProcExecutor(Configuration.Load>("DbConnections"), provider.GetRequiredService>())); //-- Framework configs ---------------------------------------------------------------- services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); //-- Data configs --------------------------------------------------------------------- services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); //-- Logic and Managers configs ------------------------------------------------------- services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(provider => provider.Init()); services.AddSingleton(); services.AddSingleton(provider => provider.Init()); services.AddSingleton(provider => provider.Init()); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(provider => Configuration.Load()); services.AddSingleton(provider => new KnokManager(Configuration.Load(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService < ITagDao>(), provider.GetRequiredService < IImageManager>(), provider.GetRequiredService(), provider.GetRequiredService())); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton>(provider => new Dictionary() { { 1, new Core.Exchanges.BitfinexExchange(Configuration.Load("Bitfinex")) }, { 2, new Core.Exchanges.BittrexExchange(Configuration.Load("Bittrex")) }, { 3, new Core.Exchanges.BinanceExchange(Configuration.Load("Binance")) }, { 4, new Core.Exchanges.CexExchange(Configuration.Load("Cex")) }, { 5, new Core.Exchanges.HUOBIExchange(Configuration.Load("HUOBI")) }, { 6, new Core.Exchanges.OKExExchange(Configuration.Load("OKEx")) } }); services.AddSingleton(); services.AddSingleton(); //-- Services configs ----------------------------------------------------------------- services.AddSingleton(provider => new PlivoSmsService(provider.GetRequiredService>(), Configuration.Load())); services.AddSingleton(provider => new TwilioPhoneService(provider.GetRequiredService>(), Configuration.Load())); services.AddSingleton(provider => new AwsEmailService(provider.GetRequiredService>(), Configuration.Load())); services.AddSingleton(provider => new DocuSigneSignatureService(provider.GetRequiredService>(), Configuration.Load())); services.AddSingleton(provider => new RefreshExchangesHostedService(Configuration.Load(), provider.GetRequiredService>(), provider.GetRequiredService())); //-- Swagger API documentation config ------------------------------------------------- services.AddSwaggerGen(o => { //o.SchemaFilter(); o.OperationFilter(); o.SwaggerDoc(SwaggerDocumentName, Configuration.Load("SwaggerInfo")); }); //TODO: services.AddCustomHeaders(); //https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders //https://jeremylindsayni.wordpress.com/author/jeremylindsayni/ } private const string SwaggerDocumentName = "v1"; // This method gets called by the runtime. Use this method to configure the HTTP request pipeline public void Configure(ILoggerFactory loggerFactory, IApplicationBuilder app) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); //app.UseApiJwt(Configuration, SecurityKey); app.UseAuthentication(); app.UseMvc(); app.UseSwagger(o => o.RouteTemplate = "spec/{documentName}/swagger.json"); app.UseSwaggerUI(o => { o.RoutePrefix = "spec/swagger"; o.SwaggerEndpoint($"/spec/{SwaggerDocumentName}/swagger.json", "Knoks API"); }); } } }