roadie/Roadie.Api/Startup.cs

308 lines
13 KiB
C#
Raw Normal View History

2019-07-07 03:16:33 +00:00
#region Usings
using Mapster;
2018-11-02 21:04:49 +00:00
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
2018-12-15 16:53:14 +00:00
using Microsoft.AspNetCore.Identity;
2019-01-08 15:51:26 +00:00
using Microsoft.AspNetCore.Identity.UI.Services;
2018-11-02 21:04:49 +00:00
using Microsoft.AspNetCore.Mvc;
2018-11-06 21:55:31 +00:00
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
2018-11-02 21:04:49 +00:00
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
2019-07-03 16:21:29 +00:00
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
2018-11-17 02:44:08 +00:00
using Roadie.Api.Hubs;
2018-11-23 04:18:48 +00:00
using Roadie.Api.ModelBinding;
2018-11-02 21:04:49 +00:00
using Roadie.Api.Services;
using Roadie.Library.Caching;
2018-11-06 21:55:31 +00:00
using Roadie.Library.Configuration;
2018-11-02 21:04:49 +00:00
using Roadie.Library.Data;
2018-11-05 00:08:37 +00:00
using Roadie.Library.Encoding;
2019-07-07 03:16:33 +00:00
using Roadie.Library.Engines;
2018-11-02 21:04:49 +00:00
using Roadie.Library.Identity;
2018-11-11 16:20:33 +00:00
using Roadie.Library.Imaging;
2019-07-07 03:16:33 +00:00
using Roadie.Library.MetaData.Audio;
using Roadie.Library.MetaData.FileName;
using Roadie.Library.MetaData.ID3Tags;
using Roadie.Library.MetaData.LastFm;
using Roadie.Library.MetaData.MusicBrainz;
using Roadie.Library.Processors;
using Roadie.Library.Scrobble;
2019-07-07 03:16:33 +00:00
using Roadie.Library.SearchEngines.Imaging;
using Roadie.Library.SearchEngines.MetaData.Discogs;
using Roadie.Library.SearchEngines.MetaData.Spotify;
using Roadie.Library.SearchEngines.MetaData.Wikipedia;
2018-11-06 21:55:31 +00:00
using Roadie.Library.Utility;
2018-11-02 21:04:49 +00:00
using System;
2019-07-03 16:21:29 +00:00
using System.Collections.Generic;
using System.Text;
2019-07-07 03:16:33 +00:00
#endregion
2018-11-02 21:04:49 +00:00
namespace Roadie.Api
{
public class Startup
{
private readonly IConfiguration _configuration;
private readonly ILoggerFactory _loggerFactory;
2019-01-12 00:27:49 +00:00
private ILogger Logger { get; }
2018-11-02 21:04:49 +00:00
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
{
2019-07-03 16:21:29 +00:00
_configuration = configuration;
_loggerFactory = loggerFactory;
2018-11-06 21:55:31 +00:00
2019-07-03 16:21:29 +00:00
Logger = _loggerFactory.CreateLogger<Startup>();
2019-01-12 00:27:49 +00:00
2019-07-07 03:16:33 +00:00
TypeAdapterConfig<Library.Data.Image, Library.Models.Image>
2018-11-11 01:11:58 +00:00
.NewConfig()
.Map(i => i.ArtistId,
2019-07-03 16:21:29 +00:00
src => src.Artist == null ? null : (Guid?)src.Artist.RoadieId)
2018-11-11 01:11:58 +00:00
.Map(i => i.ReleaseId,
2019-07-03 16:21:29 +00:00
src => src.Release == null ? null : (Guid?)src.Release.RoadieId)
2018-11-11 01:11:58 +00:00
.Compile();
2018-11-06 21:55:31 +00:00
2018-11-11 01:11:58 +00:00
TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
2018-11-02 21:04:49 +00:00
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env)
{
2019-07-03 16:21:29 +00:00
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
2018-11-02 21:04:49 +00:00
app.UseCors("CORSPolicy");
2018-11-02 21:04:49 +00:00
app.UseAuthentication();
//app.UseSwagger();
//app.UseSwaggerUI(c =>
//{
// c.SwaggerEndpoint("/swagger/swagger.json", "Roadie API");
2018-11-02 21:04:49 +00:00
// c.RoutePrefix = string.Empty;
//});
app.UseStaticFiles();
2018-11-17 02:44:08 +00:00
app.UseSignalR(routes =>
{
routes.MapHub<PlayActivityHub>("/playActivityHub");
2018-12-14 03:52:14 +00:00
routes.MapHub<ScanActivityHub>("/scanActivityHub");
2018-11-17 02:44:08 +00:00
});
2018-12-03 04:12:47 +00:00
app.UseMvc();
2018-11-02 21:04:49 +00:00
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ITokenService, TokenService>();
2018-11-03 21:21:36 +00:00
services.AddSingleton<IHttpEncoder, HttpEncoder>();
2019-01-08 15:51:26 +00:00
services.AddSingleton<IEmailSender, EmailSenderService>();
2018-11-03 21:21:36 +00:00
2019-07-03 16:21:29 +00:00
var cacheManager = new DictionaryCacheManager(_loggerFactory.CreateLogger<DictionaryCacheManager>(),
new CachePolicy(TimeSpan.FromHours(4)));
2018-11-02 21:04:49 +00:00
services.AddSingleton<ICacheManager>(cacheManager);
services.AddDbContextPool<ApplicationUserDbContext>(
2019-07-03 16:21:29 +00:00
options => options.UseMySql(_configuration.GetConnectionString("RoadieDatabaseConnection"),
mySqlOptions =>
{
mySqlOptions.ServerVersion(new Version(5, 5), ServerType.MariaDb);
mySqlOptions.EnableRetryOnFailure(
10,
TimeSpan.FromSeconds(30),
null);
}
));
2018-11-02 21:04:49 +00:00
2018-11-11 01:11:58 +00:00
services.AddDbContextPool<IRoadieDbContext, RoadieDbContext>(
2019-07-03 16:21:29 +00:00
options => options.UseMySql(_configuration.GetConnectionString("RoadieDatabaseConnection"),
mySqlOptions =>
{
mySqlOptions.ServerVersion(new Version(5, 5), ServerType.MariaDb);
mySqlOptions.EnableRetryOnFailure(
10,
TimeSpan.FromSeconds(30),
null);
}
));
2018-11-02 21:04:49 +00:00
services.AddIdentity<ApplicationUser, ApplicationRole>()
2018-11-10 23:26:04 +00:00
.AddRoles<ApplicationRole>()
2019-01-08 15:51:26 +00:00
.AddEntityFrameworkStores<ApplicationUserDbContext>()
.AddDefaultTokenProviders();
2018-11-02 21:04:49 +00:00
services.AddAuthorization(options =>
{
2018-11-10 23:26:04 +00:00
options.AddPolicy("Admin", policy => policy.RequireRole("Admin"));
2018-12-14 03:52:14 +00:00
options.AddPolicy("Editor", policy => policy.RequireRole("Admin", "Editor"));
2018-11-02 21:04:49 +00:00
});
2019-07-03 16:21:29 +00:00
services.Configure<IConfiguration>(_configuration);
var corsOrigins = (_configuration["CORSOrigins"] ?? "http://localhost:8080").Split('|');
Logger.LogDebug("Setting Up CORS Policy [{0}]", string.Join(", ", corsOrigins));
2019-01-12 00:27:49 +00:00
services.AddCors(options => options.AddPolicy("CORSPolicy", builder =>
{
builder
2019-07-03 16:21:29 +00:00
.WithOrigins(corsOrigins)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
2019-01-12 00:27:49 +00:00
}));
2018-11-02 21:04:49 +00:00
2018-11-06 21:55:31 +00:00
services.AddSingleton<IRoadieSettings, RoadieSettings>(ctx =>
{
var settings = new RoadieSettings();
var configuration = ctx.GetService<IConfiguration>();
configuration.GetSection("RoadieSettings").Bind(settings);
var hostingEnvironment = ctx.GetService<IHostingEnvironment>();
settings.ContentPath = hostingEnvironment.WebRootPath;
2019-07-03 16:21:29 +00:00
settings.ConnectionString = _configuration.GetConnectionString("RoadieDatabaseConnection");
2018-12-14 03:52:14 +00:00
2019-02-03 17:50:17 +00:00
// This is so 'User Secrets' can be used in Debugging
2019-07-03 16:21:29 +00:00
var integrationKeys = _configuration.GetSection("IntegrationKeys")
.Get<IntegrationKey>();
2019-02-03 17:50:17 +00:00
if (integrationKeys != null)
2019-07-03 16:21:29 +00:00
settings.Integrations.ApiKeys = new List<ApiKey>
2018-12-14 03:52:14 +00:00
{
new ApiKey
{
ApiName = "LastFMApiKey",
Key = integrationKeys.LastFMApiKey,
KeySecret = integrationKeys.LastFMSecret
},
new ApiKey
{
ApiName = "DiscogsConsumerKey",
Key = integrationKeys.DiscogsConsumerKey,
KeySecret = integrationKeys.DiscogsConsumerSecret
},
new ApiKey
{
ApiName = "BingImageSearch",
Key = integrationKeys.BingImageSearch
}
};
2018-11-06 21:55:31 +00:00
return settings;
});
2018-12-03 04:12:47 +00:00
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
2018-11-11 16:20:33 +00:00
services.AddSingleton<IDefaultNotFoundImages, DefaultNotFoundImages>();
2019-07-07 03:16:33 +00:00
services.AddSingleton<IImageSearchManager, ImageSearchManager>();
services.AddSingleton<IITunesSearchEngine, ITunesSearchEngine>();
services.AddSingleton<IBingImageSearchEngine, BingImageSearchEngine>();
services.AddSingleton<IMusicBrainzProvider, MusicBrainzProvider>();
services.AddSingleton<ISpotifyHelper, SpotifyHelper>();
services.AddSingleton<IDiscogsHelper, DiscogsHelper>();
services.AddSingleton<IWikipediaHelper, WikipediaHelper>();
services.AddSingleton<IFileNameHelper, FileNameHelper>();
services.AddSingleton<IID3TagsHelper, ID3TagsHelper>();
services.AddScoped<ILastFmHelper, LastFmHelper>();
services.AddScoped<IRoadieScrobbler, RoadieScrobbler>();
services.AddScoped<ILastFMScrobbler, LastFMScrobbler>();
2018-11-12 00:28:37 +00:00
services.AddScoped<IStatisticsService, StatisticsService>();
2018-11-07 04:33:22 +00:00
services.AddScoped<ICollectionService, CollectionService>();
services.AddScoped<IPlaylistService, PlaylistService>();
services.AddScoped<IBookmarkService, BookmarkService>();
2019-07-07 03:16:33 +00:00
services.AddScoped<IArtistLookupEngine, ArtistLookupEngine>();
services.AddScoped<IReleaseLookupEngine, ReleaseLookupEngine>();
services.AddScoped<ILabelLookupEngine, LabelLookupEngine>();
services.AddScoped<IAudioMetaDataHelper, AudioMetaDataHelper>();
services.AddScoped<IFileProcessor, FileProcessor>();
services.AddScoped<IFileDirectoryProcessorService, FileDirectoryProcessorService>();
2018-11-06 21:55:31 +00:00
services.AddScoped<IArtistService, ArtistService>();
2018-11-11 01:11:58 +00:00
services.AddScoped<IImageService, ImageService>();
2018-11-12 00:28:37 +00:00
services.AddScoped<IReleaseService, ReleaseService>();
services.AddScoped<ITrackService, TrackService>();
services.AddScoped<ILabelService, LabelService>();
2018-11-15 00:16:25 +00:00
services.AddScoped<IPlaylistService, PlaylistService>();
services.AddScoped<IPlayActivityService, PlayActivityService>();
services.AddScoped<IScrobbleHandler, ScrobbleHandler>();
2018-11-15 04:25:40 +00:00
services.AddScoped<IGenreService, GenreService>();
services.AddScoped<ISubsonicService, SubsonicService>();
services.AddScoped<IUserService, UserService>();
2018-12-14 03:52:14 +00:00
services.AddScoped<IAdminService, AdminService>();
2018-12-22 20:33:23 +00:00
services.AddScoped<ILookupService, LookupService>();
2019-06-28 21:24:32 +00:00
services.AddScoped<ICommentService, CommentService>();
2018-11-06 21:55:31 +00:00
2019-07-03 16:21:29 +00:00
var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(_configuration["Tokens:PrivateKey"]));
2018-12-02 15:51:54 +00:00
2018-11-02 21:04:49 +00:00
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(config =>
{
config.RequireHttpsMetadata = false;
config.SaveToken = true;
2019-07-03 16:21:29 +00:00
config.TokenValidationParameters = new TokenValidationParameters
2018-11-02 21:04:49 +00:00
{
IssuerSigningKey = securityKey,
2018-12-01 03:22:35 +00:00
2018-11-02 21:04:49 +00:00
ValidateAudience = true,
2019-07-03 16:21:29 +00:00
ValidAudience = _configuration["Tokens:Audience"],
2018-11-02 21:04:49 +00:00
ValidateIssuer = true,
2019-07-03 16:21:29 +00:00
ValidIssuer = _configuration["Tokens:Issuer"],
2018-11-02 21:04:49 +00:00
ValidateLifetime = true,
ValidateIssuerSigningKey = true
};
});
//services.AddSwaggerGen(c =>
//{
// c.SwaggerDoc("v1", new Info
// {
// Title = "Roadie API",
// Version = "v1"
// });
//});
2018-11-17 02:44:08 +00:00
services.AddSignalR();
services.AddMvc(options =>
2019-07-03 16:21:29 +00:00
{
options.RespectBrowserAcceptHeader = true; // false by default
options.ModelBinderProviders.Insert(0, new SubsonicRequestBinderProvider());
})
.AddJsonOptions(options =>
{
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
})
.AddXmlSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
2018-11-06 21:55:31 +00:00
2018-12-15 16:53:14 +00:00
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
});
services.AddHttpContextAccessor();
2018-11-06 21:55:31 +00:00
services.AddScoped<IHttpContext>(factory =>
{
var actionContext = factory.GetService<IActionContextAccessor>()
2019-07-03 16:21:29 +00:00
.ActionContext;
2019-01-12 00:27:49 +00:00
return new HttpContext(factory.GetService<IRoadieSettings>(), new UrlHelper(actionContext));
2018-11-06 21:55:31 +00:00
});
2018-11-02 21:04:49 +00:00
}
2018-12-14 03:52:14 +00:00
private class IntegrationKey
{
public string BingImageSearch { get; set; }
public string DiscogsConsumerKey { get; set; }
public string DiscogsConsumerSecret { get; set; }
2019-01-06 21:45:52 +00:00
public string LastFMApiKey { get; set; }
public string LastFMSecret { get; set; }
2018-12-14 03:52:14 +00:00
}
2018-11-02 21:04:49 +00:00
}
}