2018-11-02 21:04:49 +00:00
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNet.OData.Builder;
|
|
|
|
|
using Microsoft.AspNet.OData.Extensions;
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2018-11-19 23:51:58 +00:00
|
|
|
|
using Microsoft.AspNetCore.Mvc.Formatters;
|
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 Microsoft.OData.Edm;
|
|
|
|
|
using Newtonsoft.Json;
|
2018-11-22 17:31:59 +00:00
|
|
|
|
using Roadie.Api.Controllers;
|
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;
|
2018-11-02 21:04:49 +00:00
|
|
|
|
using Roadie.Library.Identity;
|
2018-11-11 16:20:33 +00:00
|
|
|
|
using Roadie.Library.Imaging;
|
2018-11-06 21:55:31 +00:00
|
|
|
|
using Roadie.Library.Utility;
|
2018-11-23 15:10:33 +00:00
|
|
|
|
using Serilog;
|
2018-11-02 21:04:49 +00:00
|
|
|
|
using System;
|
2018-11-06 02:41:51 +00:00
|
|
|
|
using models = Roadie.Library.Models;
|
2018-11-02 21:04:49 +00:00
|
|
|
|
|
|
|
|
|
namespace Roadie.Api
|
|
|
|
|
{
|
|
|
|
|
public class Startup
|
|
|
|
|
{
|
|
|
|
|
private readonly IConfiguration _configuration;
|
|
|
|
|
private readonly ILoggerFactory _loggerFactory;
|
|
|
|
|
|
|
|
|
|
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
|
|
|
|
|
{
|
|
|
|
|
this._configuration = configuration;
|
|
|
|
|
this._loggerFactory = loggerFactory;
|
2018-11-06 21:55:31 +00:00
|
|
|
|
|
2018-11-11 01:11:58 +00:00
|
|
|
|
TypeAdapterConfig<Roadie.Library.Data.Image, Roadie.Library.Models.Image>
|
|
|
|
|
.NewConfig()
|
|
|
|
|
.Map(i => i.ArtistId,
|
|
|
|
|
src => src.Artist == null ? null : (Guid?)src.Artist.RoadieId)
|
|
|
|
|
.Map(i => i.ReleaseId,
|
|
|
|
|
src => src.Release == null ? null : (Guid?)src.Release.RoadieId)
|
|
|
|
|
.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)
|
|
|
|
|
{
|
2018-11-23 15:10:33 +00:00
|
|
|
|
|
2018-11-02 21:04:49 +00:00
|
|
|
|
if (env.IsDevelopment())
|
|
|
|
|
{
|
|
|
|
|
app.UseDeveloperExceptionPage();
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-02 00:11:55 +00:00
|
|
|
|
app.UseCors("CORSPolicy");
|
|
|
|
|
|
2018-11-02 21:04:49 +00:00
|
|
|
|
app.UseAuthentication();
|
|
|
|
|
//app.UseSwagger();
|
|
|
|
|
//app.UseSwaggerUI(c =>
|
|
|
|
|
//{
|
2018-11-18 16:40:52 +00:00
|
|
|
|
// c.SwaggerEndpoint("/swagger/swagger.json", "Roadie API");
|
2018-11-02 21:04:49 +00:00
|
|
|
|
// c.RoutePrefix = string.Empty;
|
|
|
|
|
//});
|
2018-11-17 02:44:08 +00:00
|
|
|
|
app.UseSignalR(routes =>
|
|
|
|
|
{
|
2018-11-18 14:42:02 +00:00
|
|
|
|
routes.MapHub<PlayActivityHub>("/playActivityHub");
|
2018-11-17 02:44:08 +00:00
|
|
|
|
});
|
2018-11-02 21:04:49 +00:00
|
|
|
|
app.UseMvc(b =>
|
|
|
|
|
{
|
|
|
|
|
b.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
|
|
|
|
|
b.MapODataServiceRoute("odata", "odata", GetEdmModel());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This method gets called by the runtime. Use this method to add services to the container.
|
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
|
|
|
{
|
2018-12-02 00:11:55 +00:00
|
|
|
|
services.AddCors(options => options.AddPolicy("CORSPolicy", builder =>
|
2018-11-02 21:04:49 +00:00
|
|
|
|
{
|
|
|
|
|
builder
|
|
|
|
|
.AllowAnyOrigin()
|
2018-12-02 00:11:55 +00:00
|
|
|
|
.AllowAnyHeader()
|
2018-11-02 21:04:49 +00:00
|
|
|
|
.AllowAnyMethod()
|
2018-12-02 00:11:55 +00:00
|
|
|
|
.AllowCredentials();
|
2018-11-02 21:04:49 +00:00
|
|
|
|
}));
|
2018-11-23 04:18:48 +00:00
|
|
|
|
|
2018-11-02 21:04:49 +00:00
|
|
|
|
services.AddSingleton<ITokenService, TokenService>();
|
|
|
|
|
|
2018-11-03 21:21:36 +00:00
|
|
|
|
services.AddSingleton<IHttpEncoder, HttpEncoder>();
|
|
|
|
|
|
2018-11-11 14:46:09 +00:00
|
|
|
|
var cacheManager = new DictionaryCacheManager(this._loggerFactory.CreateLogger<DictionaryCacheManager>(), new CachePolicy(TimeSpan.FromHours(4)));
|
2018-11-02 21:04:49 +00:00
|
|
|
|
services.AddSingleton<ICacheManager>(cacheManager);
|
|
|
|
|
|
2018-11-10 18:03:54 +00:00
|
|
|
|
services.AddDbContextPool<ApplicationUserDbContext>(
|
2018-12-02 15:51:54 +00:00
|
|
|
|
options => options.UseMySql(this._configuration.GetConnectionString("RoadieDatabaseConnection"),
|
|
|
|
|
mySqlOptions =>
|
|
|
|
|
{
|
|
|
|
|
mySqlOptions.ServerVersion(new Version(5, 5), Pomelo.EntityFrameworkCore.MySql.Infrastructure.ServerType.MariaDb);
|
|
|
|
|
}
|
2018-11-10 18:03:54 +00:00
|
|
|
|
));
|
2018-11-02 21:04:49 +00:00
|
|
|
|
|
2018-11-11 01:11:58 +00:00
|
|
|
|
services.AddDbContextPool<IRoadieDbContext, RoadieDbContext>(
|
2018-12-02 15:51:54 +00:00
|
|
|
|
options => options.UseMySql(this._configuration.GetConnectionString("RoadieDatabaseConnection"),
|
|
|
|
|
mySqlOptions =>
|
|
|
|
|
{
|
|
|
|
|
mySqlOptions.ServerVersion(new Version(5, 5), Pomelo.EntityFrameworkCore.MySql.Infrastructure.ServerType.MariaDb);
|
|
|
|
|
}
|
2018-11-10 18:03:54 +00:00
|
|
|
|
));
|
2018-11-02 21:04:49 +00:00
|
|
|
|
|
|
|
|
|
services.AddIdentity<ApplicationUser, ApplicationRole>()
|
2018-11-10 23:26:04 +00:00
|
|
|
|
.AddRoles<ApplicationRole>()
|
|
|
|
|
.AddEntityFrameworkStores<ApplicationUserDbContext>();
|
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"));
|
|
|
|
|
options.AddPolicy("Editor", policy => policy.RequireRole("Editor"));
|
2018-11-02 21:04:49 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
services.Configure<IConfiguration>(this._configuration);
|
|
|
|
|
|
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;
|
2018-11-12 00:28:37 +00:00
|
|
|
|
settings.ConnectionString = this._configuration.GetConnectionString("RoadieDatabaseConnection");
|
2018-11-06 21:55:31 +00:00
|
|
|
|
return settings;
|
|
|
|
|
});
|
|
|
|
|
|
2018-11-11 16:20:33 +00:00
|
|
|
|
services.AddSingleton<IDefaultNotFoundImages, DefaultNotFoundImages>();
|
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>();
|
2018-11-24 17:52:15 +00:00
|
|
|
|
services.AddScoped<IBookmarkService, BookmarkService>();
|
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>();
|
2018-11-14 23:18:02 +00:00
|
|
|
|
services.AddScoped<ILabelService, LabelService>();
|
2018-11-15 00:16:25 +00:00
|
|
|
|
services.AddScoped<IPlaylistService, PlaylistService>();
|
2018-11-15 04:11:25 +00:00
|
|
|
|
services.AddScoped<IPlayActivityService, PlayActivityService>();
|
2018-11-15 04:25:40 +00:00
|
|
|
|
services.AddScoped<IGenreService, GenreService>();
|
2018-11-15 15:10:29 +00:00
|
|
|
|
services.AddScoped<ISubsonicService, SubsonicService>();
|
|
|
|
|
services.AddScoped<IUserService, UserService>();
|
2018-11-06 21:55:31 +00:00
|
|
|
|
|
2018-11-10 18:03:54 +00:00
|
|
|
|
var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(this._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;
|
|
|
|
|
config.TokenValidationParameters = new TokenValidationParameters()
|
|
|
|
|
{
|
|
|
|
|
IssuerSigningKey = securityKey,
|
2018-12-01 03:22:35 +00:00
|
|
|
|
|
2018-11-02 21:04:49 +00:00
|
|
|
|
ValidateAudience = true,
|
|
|
|
|
ValidAudience = this._configuration["Tokens:Audience"],
|
|
|
|
|
ValidateIssuer = true,
|
|
|
|
|
ValidIssuer = this._configuration["Tokens:Issuer"],
|
|
|
|
|
ValidateLifetime = true,
|
|
|
|
|
ValidateIssuerSigningKey = true
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//services.AddSwaggerGen(c =>
|
|
|
|
|
//{
|
|
|
|
|
// c.SwaggerDoc("v1", new Info
|
|
|
|
|
// {
|
|
|
|
|
// Title = "Roadie API",
|
|
|
|
|
// Version = "v1"
|
|
|
|
|
// });
|
|
|
|
|
//});
|
|
|
|
|
|
|
|
|
|
services.AddOData();
|
|
|
|
|
|
2018-11-17 02:44:08 +00:00
|
|
|
|
services.AddSignalR();
|
|
|
|
|
|
2018-11-19 23:51:58 +00:00
|
|
|
|
services.AddMvc(options =>
|
|
|
|
|
{
|
|
|
|
|
options.RespectBrowserAcceptHeader = true; // false by default
|
2018-11-22 23:12:57 +00:00
|
|
|
|
options.ModelBinderProviders.Insert(0, new SubsonicRequestBinderProvider());
|
2018-11-19 23:51:58 +00:00
|
|
|
|
})
|
2018-11-23 04:18:48 +00:00
|
|
|
|
.AddJsonOptions(options =>
|
|
|
|
|
{
|
|
|
|
|
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
|
|
|
|
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
|
|
|
|
})
|
|
|
|
|
.AddXmlSerializerFormatters()
|
|
|
|
|
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
2018-11-06 21:55:31 +00:00
|
|
|
|
|
2018-11-10 18:03:54 +00:00
|
|
|
|
services.AddHttpContextAccessor();
|
2018-11-06 21:55:31 +00:00
|
|
|
|
services.AddScoped<IHttpContext>(factory =>
|
|
|
|
|
{
|
|
|
|
|
var actionContext = factory.GetService<IActionContextAccessor>()
|
2018-11-10 23:26:04 +00:00
|
|
|
|
.ActionContext;
|
2018-11-06 21:55:31 +00:00
|
|
|
|
return new HttpContext(new UrlHelper(actionContext));
|
|
|
|
|
});
|
2018-11-02 21:04:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IEdmModel GetEdmModel()
|
|
|
|
|
{
|
|
|
|
|
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
|
|
|
|
|
builder.EntitySet<models.Artist>("Artist");
|
|
|
|
|
builder.EntitySet<models.Label>("Label");
|
2018-11-06 02:41:51 +00:00
|
|
|
|
builder.EntitySet<models.Releases.Release>("Release");
|
2018-11-02 21:04:49 +00:00
|
|
|
|
return builder.GetEdmModel();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|