diff options
Diffstat (limited to 'Jellyfin.Api')
| -rw-r--r-- | Jellyfin.Api/Auth/CustomAuthenticationHandler.cs | 53 | ||||
| -rw-r--r-- | Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs | 35 | ||||
| -rw-r--r-- | Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs | 8 | ||||
| -rw-r--r-- | Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs | 18 | ||||
| -rw-r--r-- | Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs | 9 | ||||
| -rw-r--r-- | Jellyfin.Api/BaseJellyfinApiController.cs | 11 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/StartupController.cs | 25 | ||||
| -rw-r--r-- | Jellyfin.Api/Jellyfin.Api.csproj | 34 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/Startup/StartupConfigurationDto.cs (renamed from Jellyfin.Api/Models/Startup/StartupConfiguration.cs) | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/Startup/StartupUserDto.cs (renamed from Jellyfin.Api/Models/Startup/StartupUser.cs) | 2 |
10 files changed, 165 insertions, 32 deletions
diff --git a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs new file mode 100644 index 000000000..bb6192b03 --- /dev/null +++ b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs @@ -0,0 +1,53 @@ +using System.Security.Claims; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using MediaBrowser.Controller.Net; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Jellyfin.Api.Auth +{ + public class CustomAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> + { + private readonly IAuthService _authService; + + public CustomAuthenticationHandler( + IAuthService authService, + IOptionsMonitor<AuthenticationSchemeOptions> options, + ILoggerFactory logger, + UrlEncoder encoder, + ISystemClock clock) : base(options, logger, encoder, clock) + { + _authService = authService; + } + + protected override Task<AuthenticateResult> HandleAuthenticateAsync() + { + var authenticatedAttribute = new AuthenticatedAttribute(); + try + { + var user = _authService.Authenticate(Request, authenticatedAttribute); + if (user == null) + { + return Task.FromResult(AuthenticateResult.Fail("Invalid user")); + } + + var claims = new[] + { + new Claim(ClaimTypes.Name, user.Name), + new Claim(ClaimTypes.Role, user.Policy.IsAdministrator ? "Administrator" : "User"), + }; + var identity = new ClaimsIdentity(claims, Scheme.Name); + var principal = new ClaimsPrincipal(identity); + var ticket = new AuthenticationTicket(principal, Scheme.Name); + + return Task.FromResult(AuthenticateResult.Success(ticket)); + } + catch (SecurityException ex) + { + return Task.FromResult(AuthenticateResult.Fail(ex)); + } + } + } +} diff --git a/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs new file mode 100644 index 000000000..73925cd61 --- /dev/null +++ b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using Microsoft.AspNetCore.Authorization; + +namespace Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy +{ + public class FirstTimeSetupOrElevatedHandler : AuthorizationHandler<FirstTimeSetupOrElevatedRequirement> + { + private readonly IConfigurationManager _configurationManager; + + public FirstTimeSetupOrElevatedHandler(IConfigurationManager configurationManager) + { + _configurationManager = configurationManager; + } + + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeSetupOrElevatedRequirement firstTimeSetupOrElevatedRequirement) + { + if (!_configurationManager.CommonConfiguration.IsStartupWizardCompleted) + { + context.Succeed(firstTimeSetupOrElevatedRequirement); + } + else if (context.User.IsInRole("Administrator")) + { + // TODO user role enum + context.Succeed(firstTimeSetupOrElevatedRequirement); + } + else + { + context.Fail(); + } + + return Task.CompletedTask; + } + } +} diff --git a/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs new file mode 100644 index 000000000..42436c870 --- /dev/null +++ b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Authorization; + +namespace Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy +{ + public class FirstTimeSetupOrElevatedRequirement : IAuthorizationRequirement + { + } +} diff --git a/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs new file mode 100644 index 000000000..694827458 --- /dev/null +++ b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; + +namespace Jellyfin.Api.Auth.RequiresElevationPolicy +{ + public class RequiresElevationHandler : AuthorizationHandler<RequiresElevationRequirement> + { + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RequiresElevationRequirement requirement) + { + if (context.User.IsInRole("Administrator")) + { + context.Succeed(requirement); + } + + return Task.CompletedTask; + } + } +} diff --git a/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs new file mode 100644 index 000000000..dd51cd3c2 --- /dev/null +++ b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Authorization; + +namespace Jellyfin.Api.Auth.RequiresElevationPolicy +{ + public class RequiresElevationRequirement : IAuthorizationRequirement + { + + } +} diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs new file mode 100644 index 000000000..796a8039a --- /dev/null +++ b/Jellyfin.Api/BaseJellyfinApiController.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Jellyfin.Api +{ + [ApiController] + [Route("[controller]")] + public class BaseJellyfinApiController : ControllerBase + { + + } +} diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index 45e4cd5ac..fb61b8d0b 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -3,12 +3,13 @@ using System.Threading.Tasks; using Jellyfin.Api.Models.Startup; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { - [ApiVersion("1")] - public class StartupController : ControllerBase + [Authorize(Policy = "FirstTimeSetupOrElevated")] + public class StartupController : BaseJellyfinApiController { private readonly IServerConfigurationManager _config; private readonly IUserManager _userManager; @@ -28,9 +29,9 @@ namespace Jellyfin.Api.Controllers } [HttpGet("Configuration")] - public StartupConfiguration Get() + public StartupConfigurationDto GetStartupConfiguration() { - var result = new StartupConfiguration + var result = new StartupConfigurationDto { UICulture = _config.Configuration.UICulture, MetadataCountryCode = _config.Configuration.MetadataCountryCode, @@ -41,7 +42,7 @@ namespace Jellyfin.Api.Controllers } [HttpPost("Configuration")] - public void UpdateInitial([FromForm] string uiCulture, [FromForm] string metadataCountryCode, [FromForm] string preferredMetadataLanguage) + public void UpdateInitialConfiguration([FromForm] string uiCulture, [FromForm] string metadataCountryCode, [FromForm] string preferredMetadataLanguage) { _config.Configuration.UICulture = uiCulture; _config.Configuration.MetadataCountryCode = metadataCountryCode; @@ -50,7 +51,7 @@ namespace Jellyfin.Api.Controllers } [HttpPost("RemoteAccess")] - public void Post([FromForm] bool enableRemoteAccess, [FromForm] bool enableAutomaticPortMapping) + public void SetRemoteAccess([FromForm] bool enableRemoteAccess, [FromForm] bool enableAutomaticPortMapping) { _config.Configuration.EnableRemoteAccess = enableRemoteAccess; _config.Configuration.EnableUPnP = enableAutomaticPortMapping; @@ -58,11 +59,11 @@ namespace Jellyfin.Api.Controllers } [HttpGet("User")] - public StartupUser GetUser() + public StartupUserDto GetUser() { var user = _userManager.Users.First(); - return new StartupUser + return new StartupUserDto { Name = user.Name, Password = user.Password @@ -70,17 +71,17 @@ namespace Jellyfin.Api.Controllers } [HttpPost("User")] - public async Task UpdateUser([FromForm] StartupUser startupUser) + public async Task UpdateUser([FromForm] StartupUserDto startupUserDto) { var user = _userManager.Users.First(); - user.Name = startupUser.Name; + user.Name = startupUserDto.Name; _userManager.UpdateUser(user); - if (!string.IsNullOrEmpty(startupUser.Password)) + if (!string.IsNullOrEmpty(startupUserDto.Password)) { - await _userManager.ChangePassword(user, startupUser.Password).ConfigureAwait(false); + await _userManager.ChangePassword(user, startupUserDto.Password).ConfigureAwait(false); } } } diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index 7a7e49e30..647004cb6 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -1,18 +1,16 @@ -<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>netstandard2.0</TargetFramework>
- <OutputType>Library</OutputType>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
- <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.3" />
- <PackageReference Include="NETStandard.Library" Version="2.0.3" />
- </ItemGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
- </ItemGroup>
-
-</Project>
+<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netstandard2.1</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> + <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" /> + </ItemGroup> + +</Project> diff --git a/Jellyfin.Api/Models/Startup/StartupConfiguration.cs b/Jellyfin.Api/Models/Startup/StartupConfigurationDto.cs index 08dd59a17..769d2e1bb 100644 --- a/Jellyfin.Api/Models/Startup/StartupConfiguration.cs +++ b/Jellyfin.Api/Models/Startup/StartupConfigurationDto.cs @@ -1,6 +1,6 @@ namespace Jellyfin.Api.Models.Startup { - public class StartupConfiguration + public class StartupConfigurationDto { public string UICulture { get; set; } public string MetadataCountryCode { get; set; } diff --git a/Jellyfin.Api/Models/Startup/StartupUser.cs b/Jellyfin.Api/Models/Startup/StartupUserDto.cs index 93a09e865..c7c2e8cb0 100644 --- a/Jellyfin.Api/Models/Startup/StartupUser.cs +++ b/Jellyfin.Api/Models/Startup/StartupUserDto.cs @@ -1,6 +1,6 @@ namespace Jellyfin.Api.Models.Startup { - public class StartupUser + public class StartupUserDto { public string Name { get; set; } public string Password { get; set; } |
