using Hangfire; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Prometheus; using Strata.Analytics.Api.Authorization; using Strata.Analytics.Biz.DataSources.Models; using Strata.Analytics.Biz.Extracts.Models; using Strata.Analytics.Biz.Utils; using Strata.Analytics.Models.Workbooks; using Strata.ApiLib.Core; using Strata.ApiLib.Core.Transformers; using Strata.CoreLib.Claims.Extensions; using Strata.Hangfire.AspNetCore.Filters.Dashboard; using Strata.Hangfire.TaskManagement.AspNetCore; using Strata.SwaggerExtensions; using System.Diagnostics.CodeAnalysis; using System.Net.Mime; using System.Text.Json; using System.Text.Json.Serialization; using AuthorizationOptions = Strata.Analytics.Api.Authorization.AuthorizationOptions; namespace Strata.Analytics.Api { [ExcludeFromCodeCoverage] public class Startup { private readonly IConfiguration _configuration; public Startup(IConfiguration configuration) { _configuration = configuration; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddStrataPlatformServices(_configuration); services.AddControllers(options => { //Prevent browsers from caching API responses (this addresses an IE11 issue): options.Filters.Add( new ResponseCacheAttribute() { Location = ResponseCacheLocation.None, NoStore = false, Duration = -1 }); options.ReturnHttpNotAcceptable = true; options.Filters.Add(new ProducesAttribute(MediaTypeNames.Application.Json)); options.Filters.Add(new ConsumesAttribute(MediaTypeNames.Application.Json)); options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer())); }) .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; // Uncomment this line if you want enum to be serialized / deserialized as string value instead of int value options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); // Date and Time Only serialization/deserialization support options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter()); options.JsonSerializerOptions.Converters.Add(new TimeOnlyJsonConverter()); }); // authorization services.AddAuthorization(options => { options.AddPolicy(Policies.DataSourceViewer, policy => policy.Requirements.Add(new DataSourceMinimumRoleRequirement(DataSourceRole.Viewer))); options.AddPolicy(Policies.DataSourceEditor, policy => policy.Requirements.Add(new DataSourceMinimumRoleRequirement(DataSourceRole.Editor))); options.AddPolicy(Policies.WorkbookViewer, policy => policy.Requirements.Add(new WorkbookMinimumRoleRequirement(WorkbookRole.Viewer))); options.AddPolicy(Policies.WorkbookEditor, policy => policy.Requirements.Add(new WorkbookMinimumRoleRequirement(WorkbookRole.Editor))); options.AddPolicy(Policies.ExtractViewer, policy => policy.Requirements.Add(new ExtractMinimumRoleRequirement(ExtractRole.Viewer))); options.AddPolicy(Policies.ExtractEditor, policy => policy.Requirements.Add(new ExtractMinimumRoleRequirement(ExtractRole.Editor))); options.AddPolicy(Policies.CustomSqlAccess, policy => policy.Requirements.Add(new ExtractCustomSqlStrataOnlyRoleRequirement())); options.AddPolicy(Policies.StrataOnly, policy => policy.RequireAssertion(context => context.User.IsSdtEmployee())); options.AddPolicy(Policies.IsAdmin, policy => policy.RequireAssertion(context => context.User.IsAdmin())); options.AddPolicy(Policies.AuthorizedDbOnly, policy => policy.Requirements.Add(new AuthorizedDbMinimumRoleRequirement())); }); services .AddOptions() .Configure((options, configuration) => { configuration.Bind("authorization", options); }) .ValidateDataAnnotations(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); // configure hangfire services.AddStrataHangfire(); services.AddStrataHangfireTaskManagement(); services.AddAnalyticsServices(_configuration); services.AddRouting(); services.AddSwagger(_configuration); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider) { app.UseRouting(); app.UseStrataPlatformMiddleware(); app.UseMetricServer(); app.UseHttpMetrics(); app.ConfigureSwagger(env, provider); app.UseStrataHangfireTaskManagement(); #if DEBUG app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new AllowAnyoneDashboardAuthorizationFilter() } }); #endif app.UseEndpoints(endpoints => endpoints.MapControllers().RequireAuthorization()); } } }