Files
analytics/src/Strata.Analytics.Api/Startup.cs
T
2026-06-23 11:18:54 -05:00

140 lines
6.6 KiB
C#

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<AuthorizationOptions>()
.Configure<IConfiguration>((options, configuration) =>
{
configuration.Bind("authorization", options);
})
.ValidateDataAnnotations();
services.AddScoped<IAuthorizationHandler, AuthorizedDbMinimumRoleHandler>();
services.AddScoped<IAuthorizationHandler, DataSourceMinimumRoleHandler>();
services.AddScoped<IAuthorizationHandler, WorkbookMinimumRoleHandler>();
services.AddScoped<IAuthorizationHandler, ExtractMinimumRoleHandler>();
services.AddScoped<IAuthorizationHandler, CustomSQLStrataOnlyRoleHandler>();
// 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());
}
}
}