Bond_009 2 years ago
parent
commit
8316bd590e

+ 32 - 12
Jellyfin.Api/Controllers/LibraryController.cs

@@ -15,6 +15,7 @@ using Jellyfin.Api.Models.LibraryDtos;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using Jellyfin.Extensions;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
@@ -332,12 +333,26 @@ public class LibraryController : BaseJellyfinApiController
     [Authorize]
     [ProducesResponseType(StatusCodes.Status204NoContent)]
     [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+    [ProducesResponseType(StatusCodes.Status404NotFound)]
     public ActionResult DeleteItem(Guid itemId)
     {
+        var isApiKey = User.GetIsApiKey();
+        var userId = User.GetUserId();
+        var user = !isApiKey && !userId.Equals(default)
+            ? _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException()
+            : null;
+        if (!isApiKey && user is null)
+        {
+            return Unauthorized("Unauthorized access");
+        }
+
         var item = _libraryManager.GetItemById(itemId);
-        var user = _userManager.GetUserById(User.GetUserId());
+        if (item is null)
+        {
+            return NotFound();
+        }
 
-        if (!item.CanDelete(user))
+        if (user is not null && !item.CanDelete(user))
         {
             return Unauthorized("Unauthorized access");
         }
@@ -361,26 +376,31 @@ public class LibraryController : BaseJellyfinApiController
     [Authorize]
     [ProducesResponseType(StatusCodes.Status204NoContent)]
     [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+    [ProducesResponseType(StatusCodes.Status404NotFound)]
     public ActionResult DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids)
     {
-        if (ids.Length == 0)
+        var isApiKey = User.GetIsApiKey();
+        var userId = User.GetUserId();
+        var user = !isApiKey && !userId.Equals(default)
+            ? _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException()
+            : null;
+
+        if (!isApiKey && user is null)
         {
-            return NoContent();
+            return Unauthorized("Unauthorized access");
         }
 
         foreach (var i in ids)
         {
             var item = _libraryManager.GetItemById(i);
-            var user = _userManager.GetUserById(User.GetUserId());
-
-            if (!item.CanDelete(user))
+            if (item is null)
             {
-                if (ids.Length > 1)
-                {
-                    return Unauthorized("Unauthorized access");
-                }
+                return NotFound();
+            }
 
-                continue;
+            if (user is not null && !item.CanDelete(user))
+            {
+                return Unauthorized("Unauthorized access");
             }
 
             _libraryManager.DeleteItem(

+ 23 - 0
tests/Jellyfin.Server.Integration.Tests/Controllers/LibraryControllerTests.cs

@@ -37,4 +37,27 @@ public sealed class LibraryControllerTests : IClassFixture<JellyfinApplicationFa
         var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
         Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
     }
+
+    [Theory]
+    [InlineData("Items/{0}")]
+    [InlineData("Items?ids={0}")]
+    public async Task Delete_NonExistentItemId_Unauthorised(string format)
+    {
+        var client = _factory.CreateClient();
+
+        var response = await client.DeleteAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
+        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+    }
+
+    [Theory]
+    [InlineData("Items/{0}")]
+    [InlineData("Items?ids={0}")]
+    public async Task Delete_NonExistentItemId_NotFound(string format)
+    {
+        var client = _factory.CreateClient();
+        client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+
+        var response = await client.DeleteAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
+        Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
+    }
 }