aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers
diff options
context:
space:
mode:
authorDavid <daullmer@gmail.com>2020-06-18 18:52:01 +0200
committerDavid <daullmer@gmail.com>2020-06-18 18:52:01 +0200
commit762eeb51e66368e5f6fdede7b6fab84ea5859107 (patch)
treec9d18360013b149f204e0d6e4e60292ce45d54f4 /Jellyfin.Api/Controllers
parent713ae7ae363cafd95bd93bfd69b4ac7ab5b9b32b (diff)
parent522e44de59a8661a859f6a373e495a9e0e8d13ff (diff)
Merge remote-tracking branch 'remotes/upstream/api-migration' into api-user
Diffstat (limited to 'Jellyfin.Api/Controllers')
-rw-r--r--Jellyfin.Api/Controllers/ActivityLogController.cs1
-rw-r--r--Jellyfin.Api/Controllers/ConfigurationController.cs4
-rw-r--r--Jellyfin.Api/Controllers/DevicesController.cs4
-rw-r--r--Jellyfin.Api/Controllers/FilterController.cs3
-rw-r--r--Jellyfin.Api/Controllers/ImageByNameController.cs2
-rw-r--r--Jellyfin.Api/Controllers/ItemRefreshController.cs1
-rw-r--r--Jellyfin.Api/Controllers/LibraryStructureController.cs341
-rw-r--r--Jellyfin.Api/Controllers/NotificationsController.cs1
-rw-r--r--Jellyfin.Api/Controllers/PackageController.cs4
-rw-r--r--Jellyfin.Api/Controllers/PluginsController.cs3
-rw-r--r--Jellyfin.Api/Controllers/RemoteImageController.cs (renamed from Jellyfin.Api/Controllers/Images/RemoteImageController.cs)4
-rw-r--r--Jellyfin.Api/Controllers/SearchController.cs3
-rw-r--r--Jellyfin.Api/Controllers/SubtitleController.cs9
-rw-r--r--Jellyfin.Api/Controllers/VideoAttachmentsController.cs5
14 files changed, 355 insertions, 30 deletions
diff --git a/Jellyfin.Api/Controllers/ActivityLogController.cs b/Jellyfin.Api/Controllers/ActivityLogController.cs
index 895d9f719..4ae7cf506 100644
--- a/Jellyfin.Api/Controllers/ActivityLogController.cs
+++ b/Jellyfin.Api/Controllers/ActivityLogController.cs
@@ -1,4 +1,3 @@
-#nullable enable
#pragma warning disable CA1801
using System;
diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs
index 780a38aa8..74f1677bd 100644
--- a/Jellyfin.Api/Controllers/ConfigurationController.cs
+++ b/Jellyfin.Api/Controllers/ConfigurationController.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System.Text.Json;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
@@ -18,7 +16,7 @@ namespace Jellyfin.Api.Controllers
/// Configuration Controller.
/// </summary>
[Route("System")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
public class ConfigurationController : BaseJellyfinApiController
{
private readonly IServerConfigurationManager _configurationManager;
diff --git a/Jellyfin.Api/Controllers/DevicesController.cs b/Jellyfin.Api/Controllers/DevicesController.cs
index 1754b0cbd..78368eed6 100644
--- a/Jellyfin.Api/Controllers/DevicesController.cs
+++ b/Jellyfin.Api/Controllers/DevicesController.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using Jellyfin.Api.Constants;
using MediaBrowser.Controller.Devices;
@@ -17,7 +15,7 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Devices Controller.
/// </summary>
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
public class DevicesController : BaseJellyfinApiController
{
private readonly IDeviceManager _deviceManager;
diff --git a/Jellyfin.Api/Controllers/FilterController.cs b/Jellyfin.Api/Controllers/FilterController.cs
index 46911ce93..6a6e6a64a 100644
--- a/Jellyfin.Api/Controllers/FilterController.cs
+++ b/Jellyfin.Api/Controllers/FilterController.cs
@@ -1,5 +1,4 @@
-#nullable enable
-#pragma warning disable CA1801
+#pragma warning disable CA1801
using System;
using System.Linq;
diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs
index fa46b6dd1..70f46ffa4 100644
--- a/Jellyfin.Api/Controllers/ImageByNameController.cs
+++ b/Jellyfin.Api/Controllers/ImageByNameController.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/Jellyfin.Api/Controllers/ItemRefreshController.cs b/Jellyfin.Api/Controllers/ItemRefreshController.cs
index d9b8357d2..a1df22e41 100644
--- a/Jellyfin.Api/Controllers/ItemRefreshController.cs
+++ b/Jellyfin.Api/Controllers/ItemRefreshController.cs
@@ -1,4 +1,3 @@
-#nullable enable
#pragma warning disable CA1801
using System.ComponentModel;
diff --git a/Jellyfin.Api/Controllers/LibraryStructureController.cs b/Jellyfin.Api/Controllers/LibraryStructureController.cs
new file mode 100644
index 000000000..ca2905b11
--- /dev/null
+++ b/Jellyfin.Api/Controllers/LibraryStructureController.cs
@@ -0,0 +1,341 @@
+#pragma warning disable CA1801
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Api.Constants;
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Jellyfin.Api.Controllers
+{
+ /// <summary>
+ /// The library structure controller.
+ /// </summary>
+ [Route("/Library/VirtualFolders")]
+ [Authorize(Policy = Policies.FirstTimeSetupOrElevated)]
+ public class LibraryStructureController : BaseJellyfinApiController
+ {
+ private readonly IServerApplicationPaths _appPaths;
+ private readonly ILibraryManager _libraryManager;
+ private readonly ILibraryMonitor _libraryMonitor;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LibraryStructureController"/> class.
+ /// </summary>
+ /// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param>
+ /// <param name="libraryManager">Instance of <see cref="ILibraryManager"/> interface.</param>
+ /// <param name="libraryMonitor">Instance of <see cref="ILibraryMonitor"/> interface.</param>
+ public LibraryStructureController(
+ IServerConfigurationManager serverConfigurationManager,
+ ILibraryManager libraryManager,
+ ILibraryMonitor libraryMonitor)
+ {
+ _appPaths = serverConfigurationManager.ApplicationPaths;
+ _libraryManager = libraryManager;
+ _libraryMonitor = libraryMonitor;
+ }
+
+ /// <summary>
+ /// Gets all virtual folders.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <response code="200">Virtual folders retrieved.</response>
+ /// <returns>An <see cref="IEnumerable{VirtualFolderInfo}"/> with the virtual folders.</returns>
+ [HttpGet]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult<IEnumerable<VirtualFolderInfo>> GetVirtualFolders([FromQuery] string userId)
+ {
+ return _libraryManager.GetVirtualFolders(true);
+ }
+
+ /// <summary>
+ /// Adds a virtual folder.
+ /// </summary>
+ /// <param name="name">The name of the virtual folder.</param>
+ /// <param name="collectionType">The type of the collection.</param>
+ /// <param name="refreshLibrary">Whether to refresh the library.</param>
+ /// <param name="paths">The paths of the virtual folder.</param>
+ /// <param name="libraryOptions">The library options.</param>
+ /// <response code="204">Folder added.</response>
+ /// <returns>A <see cref="NoContentResult"/>.</returns>
+ [HttpPost]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public async Task<ActionResult> AddVirtualFolder(
+ [FromQuery] string name,
+ [FromQuery] string collectionType,
+ [FromQuery] bool refreshLibrary,
+ [FromQuery] string[] paths,
+ [FromQuery] LibraryOptions libraryOptions)
+ {
+ libraryOptions ??= new LibraryOptions();
+
+ if (paths != null && paths.Length > 0)
+ {
+ libraryOptions.PathInfos = paths.Select(i => new MediaPathInfo { Path = i }).ToArray();
+ }
+
+ await _libraryManager.AddVirtualFolder(name, collectionType, libraryOptions, refreshLibrary).ConfigureAwait(false);
+
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Removes a virtual folder.
+ /// </summary>
+ /// <param name="name">The name of the folder.</param>
+ /// <param name="refreshLibrary">Whether to refresh the library.</param>
+ /// <response code="204">Folder removed.</response>
+ /// <returns>A <see cref="NoContentResult"/>.</returns>
+ [HttpDelete]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public async Task<ActionResult> RemoveVirtualFolder(
+ [FromQuery] string name,
+ [FromQuery] bool refreshLibrary)
+ {
+ await _libraryManager.RemoveVirtualFolder(name, refreshLibrary).ConfigureAwait(false);
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Renames a virtual folder.
+ /// </summary>
+ /// <param name="name">The name of the virtual folder.</param>
+ /// <param name="newName">The new name.</param>
+ /// <param name="refreshLibrary">Whether to refresh the library.</param>
+ /// <response code="204">Folder renamed.</response>
+ /// <response code="404">Library doesn't exist.</response>
+ /// <response code="409">Library already exists.</response>
+ /// <returns>A <see cref="NoContentResult"/> on success, a <see cref="NotFoundResult"/> if the library doesn't exist, a <see cref="ConflictResult"/> if the new name is already taken.</returns>
+ /// <exception cref="ArgumentNullException">The new name may not be null.</exception>
+ [HttpPost("Name")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status409Conflict)]
+ public ActionResult RenameVirtualFolder(
+ [FromQuery] string name,
+ [FromQuery] string newName,
+ [FromQuery] bool refreshLibrary)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ if (string.IsNullOrWhiteSpace(newName))
+ {
+ throw new ArgumentNullException(nameof(newName));
+ }
+
+ var rootFolderPath = _appPaths.DefaultUserViewsPath;
+
+ var currentPath = Path.Combine(rootFolderPath, name);
+ var newPath = Path.Combine(rootFolderPath, newName);
+
+ if (!Directory.Exists(currentPath))
+ {
+ return NotFound("The media collection does not exist.");
+ }
+
+ if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && Directory.Exists(newPath))
+ {
+ return Conflict($"The media library already exists at {newPath}.");
+ }
+
+ _libraryMonitor.Stop();
+
+ try
+ {
+ // Changing capitalization. Handle windows case insensitivity
+ if (string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase))
+ {
+ var tempPath = Path.Combine(
+ rootFolderPath,
+ Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture));
+ Directory.Move(currentPath, tempPath);
+ currentPath = tempPath;
+ }
+
+ Directory.Move(currentPath, newPath);
+ }
+ finally
+ {
+ CollectionFolder.OnCollectionFolderChange();
+
+ Task.Run(async () =>
+ {
+ // No need to start if scanning the library because it will handle it
+ if (refreshLibrary)
+ {
+ await _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None).ConfigureAwait(false);
+ }
+ else
+ {
+ // Need to add a delay here or directory watchers may still pick up the changes
+ // Have to block here to allow exceptions to bubble
+ await Task.Delay(1000).ConfigureAwait(false);
+ _libraryMonitor.Start();
+ }
+ });
+ }
+
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Add a media path to a library.
+ /// </summary>
+ /// <param name="name">The name of the library.</param>
+ /// <param name="path">The path to add.</param>
+ /// <param name="pathInfo">The path info.</param>
+ /// <param name="refreshLibrary">Whether to refresh the library.</param>
+ /// <returns>A <see cref="NoContentResult"/>.</returns>
+ /// <response code="204">Media path added.</response>
+ /// <exception cref="ArgumentNullException">The name of the library may not be empty.</exception>
+ [HttpPost("Paths")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public ActionResult AddMediaPath(
+ [FromQuery] string name,
+ [FromQuery] string path,
+ [FromQuery] MediaPathInfo pathInfo,
+ [FromQuery] bool refreshLibrary)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ _libraryMonitor.Stop();
+
+ try
+ {
+ var mediaPath = pathInfo ?? new MediaPathInfo { Path = path };
+
+ _libraryManager.AddMediaPath(name, mediaPath);
+ }
+ finally
+ {
+ Task.Run(async () =>
+ {
+ // No need to start if scanning the library because it will handle it
+ if (refreshLibrary)
+ {
+ await _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None).ConfigureAwait(false);
+ }
+ else
+ {
+ // Need to add a delay here or directory watchers may still pick up the changes
+ // Have to block here to allow exceptions to bubble
+ await Task.Delay(1000).ConfigureAwait(false);
+ _libraryMonitor.Start();
+ }
+ });
+ }
+
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Updates a media path.
+ /// </summary>
+ /// <param name="name">The name of the library.</param>
+ /// <param name="pathInfo">The path info.</param>
+ /// <returns>A <see cref="NoContentResult"/>.</returns>
+ /// <response code="204">Media path updated.</response>
+ /// <exception cref="ArgumentNullException">The name of the library may not be empty.</exception>
+ [HttpPost("Paths/Update")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public ActionResult UpdateMediaPath(
+ [FromQuery] string name,
+ [FromQuery] MediaPathInfo pathInfo)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ _libraryManager.UpdateMediaPath(name, pathInfo);
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Remove a media path.
+ /// </summary>
+ /// <param name="name">The name of the library.</param>
+ /// <param name="path">The path to remove.</param>
+ /// <param name="refreshLibrary">Whether to refresh the library.</param>
+ /// <returns>A <see cref="NoContentResult"/>.</returns>
+ /// <response code="204">Media path removed.</response>
+ /// <exception cref="ArgumentNullException">The name of the library may not be empty.</exception>
+ [HttpDelete("Paths")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public ActionResult RemoveMediaPath(
+ [FromQuery] string name,
+ [FromQuery] string path,
+ [FromQuery] bool refreshLibrary)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ _libraryMonitor.Stop();
+
+ try
+ {
+ _libraryManager.RemoveMediaPath(name, path);
+ }
+ finally
+ {
+ Task.Run(async () =>
+ {
+ // No need to start if scanning the library because it will handle it
+ if (refreshLibrary)
+ {
+ await _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None).ConfigureAwait(false);
+ }
+ else
+ {
+ // Need to add a delay here or directory watchers may still pick up the changes
+ // Have to block here to allow exceptions to bubble
+ await Task.Delay(1000).ConfigureAwait(false);
+ _libraryMonitor.Start();
+ }
+ });
+ }
+
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Update library options.
+ /// </summary>
+ /// <param name="id">The library name.</param>
+ /// <param name="libraryOptions">The library options.</param>
+ /// <response code="204">Library updated.</response>
+ /// <returns>A <see cref="NoContentResult"/>.</returns>
+ [HttpPost("LibraryOptions")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public ActionResult UpdateLibraryOptions(
+ [FromQuery] string id,
+ [FromQuery] LibraryOptions libraryOptions)
+ {
+ var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(id);
+
+ collectionFolder.UpdateLibraryOptions(libraryOptions);
+ return NoContent();
+ }
+ }
+}
diff --git a/Jellyfin.Api/Controllers/NotificationsController.cs b/Jellyfin.Api/Controllers/NotificationsController.cs
index a76675d5a..a1f9b9e8f 100644
--- a/Jellyfin.Api/Controllers/NotificationsController.cs
+++ b/Jellyfin.Api/Controllers/NotificationsController.cs
@@ -1,4 +1,3 @@
-#nullable enable
#pragma warning disable CA1801
using System;
diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs
index 8200f891c..943c23f8e 100644
--- a/Jellyfin.Api/Controllers/PackageController.cs
+++ b/Jellyfin.Api/Controllers/PackageController.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
@@ -18,7 +16,7 @@ namespace Jellyfin.Api.Controllers
/// Package Controller.
/// </summary>
[Route("Packages")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
public class PackageController : BaseJellyfinApiController
{
private readonly IInstallationManager _installationManager;
diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs
index 59196a41a..fdb2f4c35 100644
--- a/Jellyfin.Api/Controllers/PluginsController.cs
+++ b/Jellyfin.Api/Controllers/PluginsController.cs
@@ -1,5 +1,4 @@
-#nullable enable
-#pragma warning disable CA1801
+#pragma warning disable CA1801
using System;
using System.Collections.Generic;
diff --git a/Jellyfin.Api/Controllers/Images/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs
index 7c5f17e9e..80983ee64 100644
--- a/Jellyfin.Api/Controllers/Images/RemoteImageController.cs
+++ b/Jellyfin.Api/Controllers/RemoteImageController.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.IO;
@@ -21,7 +19,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
-namespace Jellyfin.Api.Controllers.Images
+namespace Jellyfin.Api.Controllers
{
/// <summary>
/// Remote Images Controller.
diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs
index ec05e4fb4..d971889db 100644
--- a/Jellyfin.Api/Controllers/SearchController.cs
+++ b/Jellyfin.Api/Controllers/SearchController.cs
@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
+using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
@@ -23,7 +24,7 @@ namespace Jellyfin.Api.Controllers
/// Search controller.
/// </summary>
[Route("/Search/Hints")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
public class SearchController : BaseJellyfinApiController
{
private readonly ISearchEngine _searchEngine;
diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs
index 97df8c60d..69b83379d 100644
--- a/Jellyfin.Api/Controllers/SubtitleController.cs
+++ b/Jellyfin.Api/Controllers/SubtitleController.cs
@@ -1,4 +1,3 @@
-#nullable enable
#pragma warning disable CA1801
using System;
@@ -110,7 +109,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Subtitles retrieved.</response>
/// <returns>An array of <see cref="RemoteSubtitleInfo"/>.</returns>
[HttpGet("/Items/{id}/RemoteSearch/Subtitles/{language}")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<RemoteSubtitleInfo>>> SearchRemoteSubtitles(
[FromRoute] Guid id,
@@ -130,7 +129,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="204">Subtitle downloaded.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Items/{id}/RemoteSearch/Subtitles/{subtitleId}")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> DownloadRemoteSubtitles(
[FromRoute] Guid id,
@@ -160,7 +159,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">File returned.</response>
/// <returns>A <see cref="FileStreamResult"/> with the subtitle file.</returns>
[HttpGet("/Providers/Subtitles/Subtitles/{id}")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
[Produces(MediaTypeNames.Application.Octet)]
public async Task<ActionResult> GetRemoteSubtitles([FromRoute] string id)
@@ -250,7 +249,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Subtitle playlist retrieved.</response>
/// <returns>A <see cref="FileContentResult"/> with the HLS subtitle playlist.</returns>
[HttpGet("/Videos/{id}/{mediaSourceId}/Subtitles/{index}/subtitles.m3u8")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> GetSubtitlePlaylist(
[FromRoute] Guid id,
diff --git a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs
index 86d9322fe..2528fd75d 100644
--- a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs
+++ b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs
@@ -1,9 +1,8 @@
-#nullable enable
-
using System;
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Api.Constants;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
@@ -17,7 +16,7 @@ namespace Jellyfin.Api.Controllers
/// Attachments controller.
/// </summary>
[Route("Videos")]
- [Authorize]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
public class VideoAttachmentsController : BaseJellyfinApiController
{
private readonly ILibraryManager _libraryManager;