1111using Microsoft . AspNetCore . Mvc . ViewFeatures . Internal ;
1212using Microsoft . EntityFrameworkCore ;
1313using Microsoft . Extensions . Caching . Distributed ;
14+ using Microsoft . Extensions . Caching . Memory ;
1415using Microsoft . Extensions . Configuration ;
1516using Microsoft . Extensions . DependencyInjection ;
1617using Microsoft . Extensions . Logging ;
2021using OpenPerpetuum . Api . Configuration ;
2122using OpenPerpetuum . Api . DependencyInstallers ;
2223using OpenPerpetuum . Core . Authorisation . Models ;
24+ using OpenPerpetuum . Core . Authorisation . Queries ;
2325using OpenPerpetuum . Core . DataServices ;
2426using OpenPerpetuum . Core . Extensions ;
27+ using OpenPerpetuum . Core . Foundation . Processing ;
2528using SimpleInjector ;
2629using SimpleInjector . Integration . AspNetCore . Mvc ;
2730using SimpleInjector . Lifestyles ;
2831using System ;
2932using System . Collections . Generic ;
33+ using System . Collections . ObjectModel ;
3034using System . Linq ;
3135using System . Net ;
36+ using System . Threading ;
3237using System . Threading . Tasks ;
3338
3439namespace OpenPerpetuum . Api
@@ -55,15 +60,11 @@ public void ConfigureServices(IServiceCollection services)
5560 services . AddOptions ( ) ;
5661 services . AddSingleton < IHttpContextAccessor , HttpContextAccessor > ( ) ;
5762
58- services
59- . AddEntityFrameworkInMemoryDatabase ( )
60- . AddDbContext < ApplicationContext > ( options => options . UseInMemoryDatabase ( nameof ( ApplicationContext ) ) ) ;
61-
6263 var openIdConnectConfig = Configuration . GetSection ( "OpenIdConnect" ) . Get < OpenIdConnectConfiguration > ( ) ;
6364
6465 services . Configure < OpenIdConnectConfiguration > ( options => Configuration . GetSection ( "OpenIdConnect" ) . Bind ( options ) ) ;
6566 services . Configure < DataProviderConfiguration > ( options => Configuration . GetSection ( "DataProviders" ) . Bind ( options ) ) ;
66-
67+
6768 services . AddAuthentication ( sharedOptions =>
6869 {
6970 sharedOptions . DefaultScheme = "ServerCookie" ;
@@ -136,14 +137,15 @@ public void ConfigureServices(IServiceCollection services)
136137#endif
137138 } ) . SetCompatibilityVersion ( CompatibilityVersion . Version_2_1 ) ;
138139
140+ services . AddMemoryCache ( ) ;
139141 services . AddDistributedMemoryCache ( ) ;
140142
141143 services . EnableSimpleInjectorCrossWiring ( container ) ;
142144 services . UseSimpleInjectorAspNetRequestScoping ( container ) ;
143145 }
144146
145147 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
146- public void Configure ( IApplicationBuilder app , IHostingEnvironment env , ILoggerFactory loggerFactory )
148+ public void Configure ( IApplicationBuilder app , IHostingEnvironment env , ILoggerFactory loggerFactory , IApplicationLifetime applicationLifetime )
147149 {
148150 // Event log is only support on Windows systems
149151 if ( Environment . OSVersion . Platform == PlatformID . Win32NT )
@@ -171,23 +173,6 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
171173 }
172174 } ) ;
173175
174- using ( AsyncScopedLifestyle . BeginScope ( container ) )
175- {
176- var dbContext = container . GetRequiredService < ApplicationContext > ( ) ;
177- dbContext . AddRange ( new [ ]
178- {
179- AccessClientModel . DefaultValue ,
180- new AccessClientModel
181- {
182- AdministratorContactAddress = "admin@email" ,
183- AdministratorName = "Development" ,
184- ClientId = Guid . Parse ( "8d24b83a-f04b-483d-8eb7-efd98ac91a9d" ) ,
185- FriendlyName = "Development Postman Test" ,
186- RedirectUri = "https://www.getpostman.com/oauth2/callback"
187- }
188- } ) ;
189- dbContext . SaveChanges ( ) ;
190- }
191176 bool isDevMode = false , isHsts = false , isHttps = false ;
192177
193178 if ( env . IsDevelopment ( ) )
@@ -209,6 +194,10 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
209194 app . UseAuthentication ( ) ;
210195 app . UseStaticFiles ( ) ;
211196 app . UseMvc ( ) ;
197+ CancellationTokenSource tokenSource = new CancellationTokenSource ( ) ;
198+ Task . Run ( ( ) => RunPeriodically ( ( ) => PopulateApplications ( container . GetRequiredService < IMemoryCache > ( ) , container . GetRequiredService < IQueryProcessor > ( ) ) , TimeSpan . FromMinutes ( 3 ) , tokenSource . Token ) ) ;
199+
200+ applicationLifetime . ApplicationStopping . Register ( ( ) => tokenSource . Cancel ( ) ) ;
212201
213202 UriParser . Register ( new GenericUriParser ( GenericUriParserOptions . GenericAuthority ) , "pack" , - 1 ) ; // Don't fail with Azure packed claims
214203
@@ -239,16 +228,21 @@ private void InitialiseContainer(IApplicationBuilder app, ILoggerFactory loggerF
239228 container . RegisterPerpetuumApiTypes ( ) ;
240229 }
241230
242- // This should stop the API from returning 302 redirects (attempts to present you a login page) for 401 Unauthorised
243- private static Func < RedirectContext < CookieAuthenticationOptions > , Task > ReplaceRedirector ( HttpStatusCode statusCode , Func < RedirectContext < CookieAuthenticationOptions > , Task > existingRedirector ) =>
244- context =>
245- {
246- if ( context . Request . Path . StartsWithSegments ( "/api" ) )
247- {
248- context . Response . StatusCode = ( int ) statusCode ;
249- return Task . CompletedTask ;
250- }
251- return existingRedirector ( context ) ;
252- } ;
253- }
231+ private async Task RunPeriodically ( Action action , TimeSpan interval , CancellationToken token )
232+ {
233+ while ( true )
234+ {
235+ action ( ) ;
236+ await Task . Delay ( interval , token ) ;
237+ }
238+ }
239+
240+ private void PopulateApplications ( IMemoryCache dbContext , IQueryProcessor queryProcessor )
241+ {
242+ dbContext . Remove ( CacheKeys . AccessClients ) ;
243+
244+ ReadOnlyCollection < AccessClientModel > applications = queryProcessor . Process ( new API_GetPermittedClientQuery { ClientId = null } ) ?? new List < AccessClientModel > ( ) . AsReadOnly ( ) ;
245+ dbContext . Set ( CacheKeys . AccessClients , applications ) ;
246+ }
247+ }
254248}
0 commit comments