1
0
mirror of https://github.com/mxpv/podsync.git synced 2024-05-11 05:55:04 +00:00
Files
mxpv-podsync/src/Podsync/Startup.cs
2017-06-14 00:44:41 -07:00

170 lines
6.6 KiB
C#

using System.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Podsync.Helpers;
using Podsync.Services;
using Podsync.Services.Links;
using Podsync.Services.Patreon;
using Podsync.Services.Resolver;
using Podsync.Services.Rss;
using Podsync.Services.Rss.Builders;
using Podsync.Services.Storage;
using Podsync.Services.Videos.Vimeo;
using Podsync.Services.Videos.YouTube;
namespace Podsync
{
// ReSharper disable once ClassNeverInstantiated.Global
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", true, true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
.AddEnvironmentVariables();
if (env.IsDevelopment())
{
builder.AddUserSecrets();
}
Configuration = builder.Build();
}
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)
{
services.Configure<PodsyncConfiguration>(Configuration.GetSection("Podsync"));
// Register core services
services.AddSingleton<ILinkService, LinkService>();
services.AddSingleton<IYouTubeClient, YouTubeClient>();
services.AddSingleton<IVimeoClient, VimeoClient>();
services.AddSingleton<IResolverService, RemoteResolver>();
services.AddSingleton<IStorageService, RedisStorage>();
services.AddSingleton<IRssBuilder, CompositeRssBuilder>();
services.AddSingleton<IPatreonApi, PatreonApi>();
services.AddSingleton<IFeedService, FeedService>();
// Add authentication services
services.AddAuthentication(config => config.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
// Add framework services
services.AddScoped<HandleExceptionAttribute>();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// See https://docs.microsoft.com/en-us/aspnet/core/publishing/linuxproduction
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
RequireHeaderSymmetry = false,
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
app.UseStaticFiles();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
CookieName = "podsync_cookies",
LoginPath = new PathString("/login"),
LogoutPath = new PathString("/logout")
});
// Patreon authentication
app.UseOAuthAuthentication(new OAuthOptions
{
AuthenticationScheme = Constants.Patreon.AuthenticationScheme,
ClientId = Configuration[$"Podsync:{nameof(PodsyncConfiguration.PatreonClientId)}"],
ClientSecret = Configuration[$"Podsync:{nameof(PodsyncConfiguration.PatreonSecret)}"],
CallbackPath = new PathString("/oauth-patreon"),
AuthorizationEndpoint = Constants.Patreon.AuthorizationEndpoint,
TokenEndpoint = Constants.Patreon.TokenEndpoint,
SaveTokens = true,
Scope = { "users", "pledges-to-me", "my-campaign" },
Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var patreonApi = app.ApplicationServices.GetService<IPatreonApi>();
var tokens = new Tokens
{
AccessToken = context.AccessToken,
RefreshToken = context.RefreshToken
};
var user = await patreonApi.FetchUserAndPledges(tokens);
context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
context.Identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
context.Identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
context.Identity.AddClaim(new Claim(ClaimTypes.Uri, user.Url));
var amountCents = user.Pledges.Sum(x => x.AmountCents);
context.Identity.AddClaim(new Claim(Constants.Patreon.AmountDonated, amountCents.ToString()));
}
}
});
app.Map("/login", builder =>
{
builder.Run(async context =>
{
// Return a challenge to invoke the Patreon authentication scheme
await context.Authentication.ChallengeAsync(Constants.Patreon.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
});
});
app.Map("/logout", builder =>
{
builder.Run(async context =>
{
// Sign the user out of the authentication middleware (i.e. it will clear the Auth cookie)
await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// Redirect the user to the home page after signing out
context.Response.Redirect("/");
});
});
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
}
}