using Jellyfin.Api; using Jellyfin.Api.Auth; using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy; using Jellyfin.Api.Auth.RequiresElevationPolicy; using Jellyfin.Api.Constants; using Jellyfin.Api.Controllers; using Jellyfin.Server.Formatters; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; namespace Jellyfin.Server.Extensions { /// /// API specific extensions for the service collection. /// public static class ApiServiceCollectionExtensions { /// /// Adds jellyfin API authorization policies to the DI container. /// /// The service collection. /// The updated service collection. public static IServiceCollection AddJellyfinApiAuthorization(this IServiceCollection serviceCollection) { serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); return serviceCollection.AddAuthorizationCore(options => { options.AddPolicy( Policies.RequiresElevation, policy => { policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication); policy.AddRequirements(new RequiresElevationRequirement()); }); options.AddPolicy( Policies.FirstTimeSetupOrElevated, policy => { policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication); policy.AddRequirements(new FirstTimeSetupOrElevatedRequirement()); }); }); } /// /// Adds custom legacy authentication to the service collection. /// /// The service collection. /// The updated service collection. public static AuthenticationBuilder AddCustomAuthentication(this IServiceCollection serviceCollection) { return serviceCollection.AddAuthentication(AuthenticationSchemes.CustomAuthentication) .AddScheme(AuthenticationSchemes.CustomAuthentication, null); } /// /// Extension method for adding the jellyfin API to the service collection. /// /// The service collection. /// The base url for the API. /// The MVC builder. public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl) { return serviceCollection.AddMvc(opts => { opts.UseGeneralRoutePrefix(baseUrl); opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Setting the naming policy to null leaves the property names as-is when serializing objects to JSON. options.JsonSerializerOptions.PropertyNamingPolicy = null; }) .AddControllersAsServices(); } /// /// Adds Swagger to the service collection. /// /// The service collection. /// The updated service collection. public static IServiceCollection AddJellyfinApiSwagger(this IServiceCollection serviceCollection) { return serviceCollection.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Jellyfin API", Version = "v1" }); }); } } }