Knocks/BackEnd/Knoks.Api/Startup.cs

200 lines
11 KiB
C#

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<Startup>()
.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<Startup>();
}
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<IPasswordOptions>(provider => Configuration.Load<PasswordOptions>());
services.AddSingleton<IDocumentOptions>(provider => Configuration.Load<DocumentOptions>());
services.AddSingleton<IAccountTransactionsSettings>(provider => Configuration.Load<AccountTransactionsSettings>());
//-- ProcExecutor config --------------------------------------------------------------
services.AddSingleton<IProcExecutor>(provider => new ProcExecutor(Configuration.Load<Dictionary<string, string>>("DbConnections"), provider.GetRequiredService<ILogger<ProcExecutor>>()));
//-- Framework configs ----------------------------------------------------------------
services.AddSingleton<IPasswordStrength, PasswordStrength>();
services.AddSingleton<IPasswordProcess, PasswordProcess>();
services.AddSingleton<IDocumentProcess, DocumentProcess>();
services.AddSingleton<IContentGenerator, ContentGenerator>();
//-- Data configs ---------------------------------------------------------------------
services.AddSingleton<IGeneralDao, GeneralDao>();
services.AddSingleton<IUserDao, UserDao>();
services.AddSingleton<IAccountDao, AccountDao>();
services.AddSingleton<IOperatorDao, OperatorDao>();
services.AddSingleton<IApiConsumerDao, ApiConsumerDao>();
services.AddSingleton<IBackofficeDao, BackofficeDao>();
services.AddSingleton<ISystemConfigurationDao, SystemConfigurationDao>();
services.AddSingleton<IKnokDao, KnokDao>();
services.AddSingleton<IKnokPriceDao, KnokPriceDao>();
services.AddSingleton<ITagDao, TagDao>();
services.AddSingleton<IExchangeDao, ExchangeDao>();
services.AddSingleton<IAccountTransactionDao, AccountTransactionDao>();
services.AddSingleton<AccountTransactionsSettings>();
//-- Logic and Managers configs -------------------------------------------------------
services.AddSingleton<IGeneralManager, GeneralManager>();
services.AddSingleton<IKnokPriceLogic, KnokPriceLogic>();
services.AddSingleton<IKnokPricelManager, KnokPriceManager>();
services.AddSingleton<IUserManager>(provider => provider.Init<UserManager>());
services.AddSingleton<IOperatorManager, OperatorManager>();
services.AddSingleton<IApiConsumerManager>(provider => provider.Init<ApiConsumerManager>());
services.AddSingleton<IEventManager>(provider => provider.Init<EventManager>());
services.AddSingleton<IBackofficeManager, BackofficeManager>();
services.AddSingleton<IPhoneManager, PhoneManager>();
services.AddSingleton<ISystemConfigurationManager, SystemConfigurationManager>();
services.AddSingleton<IKnokSettings>(provider => Configuration.Load<KnokSettings>());
services.AddSingleton<IKnokManager>(provider => new KnokManager(Configuration.Load<CommonSettings>(),
provider.GetRequiredService<IKnokSettings>(), provider.GetRequiredService<IKnokDao>(),
provider.GetRequiredService < ITagDao>(), provider.GetRequiredService < IImageManager>(),
provider.GetRequiredService<IKnokPricelManager>(),
provider.GetRequiredService<IGeneralManager>()));
services.AddSingleton<IUidManager, UidManager>();
services.AddSingleton<IImageManager, ImageManager>();
services.AddSingleton<IUserImageManager, ImageManager>();
services.AddSingleton<IDictionary<int, IExchange>>(provider => new Dictionary<int, IExchange>() {
{ 1, new Core.Exchanges.BitfinexExchange(Configuration.Load<Core.Exchanges.ExchangeSettings>("Bitfinex")) },
{ 2, new Core.Exchanges.BittrexExchange(Configuration.Load<Core.Exchanges.ExchangeSettings>("Bittrex")) },
{ 3, new Core.Exchanges.BinanceExchange(Configuration.Load<Core.Exchanges.ExchangeSettings>("Binance")) },
{ 4, new Core.Exchanges.CexExchange(Configuration.Load<Core.Exchanges.ExchangeSettings>("Cex")) },
{ 5, new Core.Exchanges.HUOBIExchange(Configuration.Load<Core.Exchanges.ExchangeSettings>("HUOBI")) },
{ 6, new Core.Exchanges.OKExExchange(Configuration.Load<Core.Exchanges.ExchangeSettings>("OKEx")) }
});
services.AddSingleton<IExchangeManager, ExchangeManager>();
services.AddSingleton<IAccountTransactionManager, AccountTransactionManager>();
//-- Services configs -----------------------------------------------------------------
services.AddSingleton<ISmsService>(provider => new PlivoSmsService(provider.GetRequiredService<ILogger<PlivoSmsService>>(), Configuration.Load<PlivoSmsSettings>()));
services.AddSingleton<IPhoneService>(provider => new TwilioPhoneService(provider.GetRequiredService<ILogger<TwilioPhoneService>>(), Configuration.Load<TwilioPhoneSettings>()));
services.AddSingleton<IEmailService>(provider => new AwsEmailService(provider.GetRequiredService<ILogger<AwsEmailService>>(), Configuration.Load<AwsEmailSettings>()));
services.AddSingleton<ISignatureService>(provider => new DocuSigneSignatureService(provider.GetRequiredService<ILogger<DocuSigneSignatureService>>(), Configuration.Load<DocuSigneSignatureSettings>()));
services.AddSingleton<IHostedService>(provider => new RefreshExchangesHostedService(Configuration.Load<CommonSettings>(), provider.GetRequiredService<ILogger<RefreshExchangesHostedService>>(), provider.GetRequiredService<IExchangeManager>()));
//-- Swagger API documentation config -------------------------------------------------
services.AddSwaggerGen(o =>
{
//o.SchemaFilter<ApiSchemaFilter>();
o.OperationFilter<ApiSwaggerOperationFilter>();
o.SwaggerDoc(SwaggerDocumentName, Configuration.Load<Info>("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");
});
}
}
}