· 2 years ago · Dec 09, 2022, 08:50 PM
1// Copyright (C) 2021 Sascha Manns <Sascha.Manns@outlook.de>
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15using HealthChecks.UI.Client;
16using MannsBlog.Config;
17using MannsBlog.Data;
18using MannsBlog.Helpers;
19using MannsBlog.Logger;
20using MannsBlog.MetaWeblog;
21using MannsBlog.Services;
22using MannsBlog.Services.DataProviders;
23using Microsoft.AspNetCore.Builder;
24using Microsoft.AspNetCore.Components;
25using Microsoft.AspNetCore.Diagnostics.HealthChecks;
26using Microsoft.AspNetCore.Hosting;
27using Microsoft.AspNetCore.Http;
28using Microsoft.AspNetCore.Identity;
29using Microsoft.AspNetCore.Localization;
30using Microsoft.AspNetCore.Mvc.Razor;
31using Microsoft.Extensions.Configuration;
32using Microsoft.Extensions.DependencyInjection;
33using Microsoft.Extensions.Hosting;
34using Microsoft.Extensions.Logging;
35using Microsoft.Extensions.Options;
36using System;
37using System.Collections.Generic;
38using System.Globalization;
39using System.Linq;
40using System.Net.Http;
41using WilderMinds.AzureImageStorageService;
42using WilderMinds.MetaWeblog;
43
44namespace MannsBlog
45{
46 public class Startup
47 {
48 public IConfiguration Configuration { get; }
49 private readonly IConfiguration _config;
50 private readonly IHostEnvironment _env;
51
52 public Startup(IConfiguration config, IHostEnvironment env)
53 {
54 _config = config;
55 _env = env;
56 }
57
58 public void ConfigureServices(IServiceCollection svcs)
59 {
60 svcs.Configure<AppSettings>(_config);
61
62 if (_env.IsDevelopment() && _config.GetValue<bool>("MailService:TestInDev") == false)
63 {
64 svcs.AddTransient<IMailService, LoggingMailService>();
65 }
66 else
67 {
68 svcs.AddTransient<IMailService, MailService>();
69 }
70 svcs.AddTransient<GoogleCaptchaService>();
71
72 svcs.AddDbContext<MannsContext>(ServiceLifetime.Scoped);
73
74 svcs.AddIdentity<MannsUser, IdentityRole>()
75 .AddEntityFrameworkStores<MannsContext>();
76
77 if (_config.GetValue<bool>("MannsDb:TestData"))
78 {
79 svcs.AddScoped<IMannsRepository, MemoryRepository>();
80 }
81 else
82 {
83 svcs.AddScoped<IMannsRepository, MannsRepository>();
84 }
85
86 svcs.ConfigureHealthChecks(_config);
87
88 svcs.AddTransient<MannsInitializer>();
89 svcs.AddScoped<AdService>();
90
91 // Data Providers (non-EF)
92 svcs.AddScoped<CalendarProvider>();
93 //svcs.AddScoped<CoursesProvider>();
94 svcs.AddScoped<PublicationsProvider>();
95 //svcs.AddScoped<PodcastEpisodesProvider>();
96 svcs.AddScoped<TalksProvider>();
97 svcs.AddScoped<VideosProvider>();
98 svcs.AddScoped<JobsProvider>();
99 svcs.AddScoped<TestimonialsProvider>();
100 svcs.AddScoped<CertsProvider>();
101 svcs.AddScoped<ProjectsProvider>();
102 if (_env.IsDevelopment() && _config.GetValue<bool>("BlobStorage:TestInDev") == false ||
103 _config["BlobStorage:Account"] == "FOO")
104 {
105 svcs.AddTransient<IAzureImageStorageService, FakeAzureImageService>();
106 }
107 else
108 {
109 svcs.AddAzureImageStorageService(_config["BlobStorage:Account"],
110 _config["BlobStorage:Key"],
111 _config["BlobStorage:StorageUrl"]);
112 }
113
114 // Supporting Live Writer (MetaWeblogAPI)
115 svcs.AddMetaWeblog<MannsWeblogProvider>();
116
117 //DSGVO
118 svcs.Configure<CookiePolicyOptions>(options =>
119 {
120 // Sets the display of the Cookie Consent banner (/Pages/Shared/_CookieConsentPartial.cshtml).
121 // This lambda determines whether user consent for non-essential cookies is needed for a given request.
122 options.CheckConsentNeeded = context => true;
123 options.MinimumSameSitePolicy = SameSiteMode.Strict;
124 });
125
126 // Add Caching Support
127 svcs.AddMemoryCache(opt => opt.ExpirationScanFrequency = TimeSpan.FromMinutes(5));
128
129 // Add MVC to the container
130 svcs.AddLocalization(opt =>
131 {
132 opt.ResourcesPath = "Resources";
133 });
134
135 svcs.Configure<RequestLocalizationOptions>(options =>
136 {
137 List<CultureInfo> supportedCultures = new List<CultureInfo>
138 {
139 new CultureInfo("en-US"),
140 new CultureInfo("de-DE")
141 };
142
143 options.DefaultRequestCulture = new RequestCulture("en-US");
144 options.SupportedCultures = supportedCultures;
145 options.SupportedUICultures = supportedCultures;
146 options.ApplyCurrentCultureToResponseHeaders = true;
147 });
148
149 svcs.AddMvc()
150 .AddMvcLocalization()
151 .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);
152
153
154 svcs.AddControllersWithViews()
155 .AddRazorRuntimeCompilation();
156
157 if (!svcs.Any(x => x.ServiceType == typeof(HttpClient)))
158 {
159 svcs.AddScoped<HttpClient>(s =>
160 {
161 var uriHelper = s.GetRequiredService<NavigationManager>();
162 return new HttpClient()
163 {
164 BaseAddress = new Uri(uriHelper.BaseUri)
165 };
166 });
167 }
168
169 svcs.AddServerSideBlazor();
170
171 svcs.AddApplicationInsightsTelemetry(_config["ApplicationInsights:InstrumentationKey"]);
172
173 }
174
175 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
176 public void Configure(IApplicationBuilder app,
177 ILoggerFactory loggerFactory,
178 IMailService mailService,
179 IServiceScopeFactory scopeFactory,
180 IOptions<AppSettings> settings,
181 IHttpContextAccessor contextAccessor)
182 {
183 // Add the following to the request pipeline only in development environment.
184 if (_env.IsDevelopment())
185 {
186 app.UseDeveloperExceptionPage();
187 app.UseBrowserLink();
188 }
189 else
190 {
191 // Early so we can catch the StatusCode error
192 app.UseStatusCodePagesWithReExecute("/Error/{0}");
193 app.UseExceptionHandler("/Exception");
194
195 // Support logging to email
196 loggerFactory.AddEmail(mailService, contextAccessor, LogLevel.Critical);
197
198 app.UseHttpsRedirection();
199 }
200
201 // Syncfusion License Key
202 Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(settings.Value.Syncfusion.EJ2AspNetCore);
203
204 // Support MetaWeblog API
205 app.UseMetaWeblog("/livewriter");
206
207 // Rewrite old URLs to new URLs
208 app.UseUrlRewriter();
209
210 app.UseStaticFiles();
211 app.UseCookiePolicy();
212
213 // Email Uncaught Exceptions
214 if (settings.Value.Exceptions.TestEmailExceptions || !_env.IsDevelopment())
215 {
216 app.UseMiddleware<EmailExceptionMiddleware>();
217 }
218
219 app.UseRouting();
220 app.UseAuthentication();
221 app.UseAuthorization();
222
223
224 // Globalizing & Localizing
225 var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>()?.Value;
226 app.UseRequestLocalization(options);
227
228 app.UseEndpoints(cfg =>
229 {
230 cfg.MapControllers();
231 cfg.MapHealthChecks("/_hc");
232 cfg.MapHealthChecks("/_hc.json", new HealthCheckOptions()
233 {
234 Predicate = _ => true,
235 ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
236 });
237 cfg.MapBlazorHub();
238 });
239 }
240 }
241}
242