Add missing attributes, fix response codes, fix route parameter casing

This commit is contained in:
crobibero 2020-06-20 18:02:07 -06:00
parent deac459b62
commit 10ddbc34ec
13 changed files with 172 additions and 163 deletions

View file

@ -68,7 +68,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="key">Configuration key.</param>
/// <response code="200">Configuration returned.</response>
/// <returns>Configuration.</returns>
[HttpGet("Configuration/{Key}")]
[HttpGet("Configuration/{key}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<object> GetNamedConfiguration([FromRoute] string key)
{
@ -81,7 +81,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="key">Configuration key.</param>
/// <response code="204">Named configuration updated.</response>
/// <returns>Update status.</returns>
[HttpPost("Configuration/{Key}")]
[HttpPost("Configuration/{key}")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> UpdateNamedConfiguration([FromRoute] string key)

View file

@ -133,6 +133,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the device could not be found.</returns>
[HttpDelete]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult DeleteDevice([FromQuery, BindRequired] string id)
{
var existingDevice = _deviceManager.GetDevice(id);

View file

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
@ -34,9 +35,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="client">Client.</param>
/// <response code="200">Display preferences retrieved.</response>
/// <returns>An <see cref="OkResult"/> containing the display preferences on success, or a <see cref="NotFoundResult"/> if the display preferences could not be found.</returns>
[HttpGet("{DisplayPreferencesId}")]
[HttpGet("{displayPreferencesId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<DisplayPreferences> GetDisplayPreferences(
[FromRoute] string displayPreferencesId,
[FromQuery] [Required] string userId,
@ -52,30 +52,24 @@ namespace Jellyfin.Api.Controllers
/// <param name="userId">User Id.</param>
/// <param name="client">Client.</param>
/// <param name="displayPreferences">New Display Preferences object.</param>
/// <response code="200">Display preferences updated.</response>
/// <returns>An <see cref="OkResult"/> on success, or a <see cref="NotFoundResult"/> if the display preferences could not be found.</returns>
[HttpPost("{DisplayPreferencesId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ModelStateDictionary), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
/// <response code="204">Display preferences updated.</response>
/// <returns>An <see cref="OkResult"/> on success.</returns>
[HttpPost("{displayPreferencesId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "displayPreferencesId", Justification = "Imported from ServiceStack")]
public ActionResult UpdateDisplayPreferences(
[FromRoute] string displayPreferencesId,
[FromQuery, BindRequired] string userId,
[FromQuery, BindRequired] string client,
[FromBody, BindRequired] DisplayPreferences displayPreferences)
{
if (displayPreferencesId == null)
{
// TODO - refactor so parameter doesn't exist or is actually used.
}
_displayPreferencesRepository.SaveDisplayPreferences(
displayPreferences,
userId,
client,
CancellationToken.None);
return Ok();
return NoContent();
}
}
}

View file

@ -58,7 +58,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Image stream retrieved.</response>
/// <response code="404">Image not found.</response>
/// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns>
[HttpGet("General/{Name}/{Type}")]
[HttpGet("General/{name}/{type}")]
[AllowAnonymous]
[Produces(MediaTypeNames.Application.Octet)]
[ProducesResponseType(StatusCodes.Status200OK)]
@ -103,7 +103,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Image stream retrieved.</response>
/// <response code="404">Image not found.</response>
/// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns>
[HttpGet("Ratings/{Theme}/{Name}")]
[HttpGet("Ratings/{theme}/{name}")]
[AllowAnonymous]
[Produces(MediaTypeNames.Application.Octet)]
[ProducesResponseType(StatusCodes.Status200OK)]
@ -136,7 +136,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Image stream retrieved.</response>
/// <response code="404">Image not found.</response>
/// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns>
[HttpGet("MediaInfo/{Theme}/{Name}")]
[HttpGet("MediaInfo/{theme}/{name}")]
[AllowAnonymous]
[Produces(MediaTypeNames.Application.Octet)]
[ProducesResponseType(StatusCodes.Status200OK)]

View file

@ -1,3 +1,4 @@
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using MediaBrowser.Controller.Library;
@ -40,29 +41,29 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Refreshes metadata for an item.
/// </summary>
/// <param name="id">Item id.</param>
/// <param name="itemId">Item id.</param>
/// <param name="metadataRefreshMode">(Optional) Specifies the metadata refresh mode.</param>
/// <param name="imageRefreshMode">(Optional) Specifies the image refresh mode.</param>
/// <param name="replaceAllMetadata">(Optional) Determines if metadata should be replaced. Only applicable if mode is FullRefresh.</param>
/// <param name="replaceAllImages">(Optional) Determines if images should be replaced. Only applicable if mode is FullRefresh.</param>
/// <param name="recursive">(Unused) Indicates if the refresh should occur recursively.</param>
/// <response code="200">Item metadata refresh queued.</response>
/// <response code="204">Item metadata refresh queued.</response>
/// <response code="404">Item to refresh not found.</response>
/// <returns>An <see cref="OkResult"/> on success, or a <see cref="NotFoundResult"/> if the item could not be found.</returns>
[HttpPost("{Id}/Refresh")]
[HttpPost("{itemId}/Refresh")]
[Description("Refreshes metadata for an item.")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "recursive", Justification = "Imported from ServiceStack")]
public ActionResult Post(
[FromRoute] string id,
[FromRoute] Guid itemId,
[FromQuery] MetadataRefreshMode metadataRefreshMode = MetadataRefreshMode.None,
[FromQuery] MetadataRefreshMode imageRefreshMode = MetadataRefreshMode.None,
[FromQuery] bool replaceAllMetadata = false,
[FromQuery] bool replaceAllImages = false,
[FromQuery] bool recursive = false)
{
var item = _libraryManager.GetItemById(id);
var item = _libraryManager.GetItemById(itemId);
if (item == null)
{
return NotFound();
@ -82,7 +83,7 @@ namespace Jellyfin.Api.Controllers
};
_providerManager.QueueRefresh(item.Id, refreshOptions, RefreshPriority.High);
return Ok();
return NoContent();
}
}
}

View file

@ -42,7 +42,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="limit">An optional limit on the number of notifications returned.</param>
/// <response code="200">Notifications returned.</response>
/// <returns>An <see cref="OkResult"/> containing a list of notifications.</returns>
[HttpGet("{UserID}")]
[HttpGet("{userId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isRead", Justification = "Imported from ServiceStack")]
@ -63,7 +63,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="userId">The user's ID.</param>
/// <response code="200">Summary of user's notifications returned.</response>
/// <returns>An <cref see="OkResult"/> containing a summary of the users notifications.</returns>
[HttpGet("{UserID}/Summary")]
[HttpGet("{userId}/Summary")]
[ProducesResponseType(StatusCodes.Status200OK)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")]
public ActionResult<NotificationsSummaryDto> GetNotificationsSummary(
@ -138,7 +138,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="ids">A comma-separated list of the IDs of notifications which should be set as read.</param>
/// <response code="204">Notifications set as read.</response>
/// <returns>A <cref see="NoContentResult"/>.</returns>
[HttpPost("{UserID}/Read")]
[HttpPost("{userId}/Read")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "ids", Justification = "Imported from ServiceStack")]
@ -156,7 +156,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="ids">A comma-separated list of the IDs of notifications which should be set as unread.</param>
/// <response code="204">Notifications set as unread.</response>
/// <returns>A <cref see="NoContentResult"/>.</returns>
[HttpPost("{UserID}/Unread")]
[HttpPost("{userId}/Unread")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "ids", Justification = "Imported from ServiceStack")]

View file

@ -35,9 +35,10 @@ namespace Jellyfin.Api.Controllers
/// </summary>
/// <param name="name">The name of the package.</param>
/// <param name="assemblyGuid">The GUID of the associated assembly.</param>
/// <response code="200">Package retrieved.</response>
/// <returns>A <see cref="PackageInfo"/> containing package information.</returns>
[HttpGet("/{Name}")]
[ProducesResponseType(typeof(PackageInfo), StatusCodes.Status200OK)]
[HttpGet("/{name}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<PackageInfo>> GetPackageInfo(
[FromRoute] [Required] string name,
[FromQuery] string? assemblyGuid)
@ -54,9 +55,10 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets available packages.
/// </summary>
/// <response code="200">Available packages returned.</response>
/// <returns>An <see cref="PackageInfo"/> containing available packages information.</returns>
[HttpGet]
[ProducesResponseType(typeof(PackageInfo[]), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IEnumerable<PackageInfo>> GetPackages()
{
IEnumerable<PackageInfo> packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false);
@ -73,7 +75,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="204">Package found.</response>
/// <response code="404">Package not found.</response>
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the package could not be found.</returns>
[HttpPost("/Installed/{Name}")]
[HttpPost("/Installed/{name}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[Authorize(Policy = Policies.RequiresElevation)]
@ -102,17 +104,16 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Cancels a package installation.
/// </summary>
/// <param name="id">Installation Id.</param>
/// <param name="packageId">Installation Id.</param>
/// <response code="204">Installation cancelled.</response>
/// <returns>A <see cref="NoContentResult"/> on successfully cancelling a package installation.</returns>
[HttpDelete("/Installing/{id}")]
[HttpDelete("/Installing/{packageId}")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public IActionResult CancelPackageInstallation(
[FromRoute] [Required] string id)
[FromRoute] [Required] Guid packageId)
{
_installationManager.CancelInstallation(new Guid(id));
_installationManager.CancelInstallation(packageId);
return NoContent();
}
}

View file

@ -11,6 +11,7 @@ using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
using MediaBrowser.Model.Plugins;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
@ -45,6 +46,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Installed plugins returned.</response>
/// <returns>List of currently installed plugins.</returns>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isAppStoreEnabled", Justification = "Imported from ServiceStack")]
public ActionResult<IEnumerable<PluginInfo>> GetPlugins([FromRoute] bool? isAppStoreEnabled)
{
@ -55,11 +57,13 @@ namespace Jellyfin.Api.Controllers
/// Uninstalls a plugin.
/// </summary>
/// <param name="pluginId">Plugin id.</param>
/// <response code="200">Plugin uninstalled.</response>
/// <response code="204">Plugin uninstalled.</response>
/// <response code="404">Plugin not found.</response>
/// <returns>An <see cref="OkResult"/> on success, or a <see cref="NotFoundResult"/> if the file could not be found.</returns>
[HttpDelete("{pluginId}")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult UninstallPlugin([FromRoute] Guid pluginId)
{
var plugin = _appHost.Plugins.FirstOrDefault(p => p.Id == pluginId);
@ -69,7 +73,7 @@ namespace Jellyfin.Api.Controllers
}
_installationManager.UninstallPlugin(plugin);
return Ok();
return NoContent();
}
/// <summary>
@ -80,6 +84,8 @@ namespace Jellyfin.Api.Controllers
/// <response code="404">Plugin not found or plugin configuration not found.</response>
/// <returns>Plugin configuration.</returns>
[HttpGet("{pluginId}/Configuration")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<BasePluginConfiguration> GetPluginConfiguration([FromRoute] Guid pluginId)
{
if (!(_appHost.Plugins.FirstOrDefault(p => p.Id == pluginId) is IHasPluginConfiguration plugin))
@ -97,14 +103,16 @@ namespace Jellyfin.Api.Controllers
/// Accepts plugin configuration as JSON body.
/// </remarks>
/// <param name="pluginId">Plugin id.</param>
/// <response code="200">Plugin configuration updated.</response>
/// <response code="200">Plugin not found or plugin does not have configuration.</response>
/// <response code="204">Plugin configuration updated.</response>
/// <response code="404">Plugin not found or plugin does not have configuration.</response>
/// <returns>
/// A <see cref="Task" /> that represents the asynchronous operation to update plugin configuration.
/// The task result contains an <see cref="OkResult"/> indicating success, or <see cref="NotFoundResult"/>
/// when plugin not found or plugin doesn't have configuration.
/// </returns>
[HttpPost("{pluginId}/Configuration")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> UpdatePluginConfiguration([FromRoute] Guid pluginId)
{
if (!(_appHost.Plugins.FirstOrDefault(p => p.Id == pluginId) is IHasPluginConfiguration plugin))
@ -116,7 +124,7 @@ namespace Jellyfin.Api.Controllers
.ConfigureAwait(false);
plugin.UpdateConfiguration(configuration);
return Ok();
return NoContent();
}
/// <summary>
@ -126,6 +134,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>Plugin security info.</returns>
[Obsolete("This endpoint should not be used.")]
[HttpGet("SecurityInfo")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<PluginSecurityInfo> GetPluginSecurityInfo()
{
return new PluginSecurityInfo
@ -139,14 +148,15 @@ namespace Jellyfin.Api.Controllers
/// Updates plugin security info.
/// </summary>
/// <param name="pluginSecurityInfo">Plugin security info.</param>
/// <response code="200">Plugin security info updated.</response>
/// <returns>An <see cref="OkResult"/>.</returns>
/// <response code="204">Plugin security info updated.</response>
/// <returns>An <see cref="NoContentResult"/>.</returns>
[Obsolete("This endpoint should not be used.")]
[HttpPost("SecurityInfo")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult UpdatePluginSecurityInfo([FromBody, BindRequired] PluginSecurityInfo pluginSecurityInfo)
{
return Ok();
return NoContent();
}
/// <summary>
@ -157,6 +167,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>Mb registration record.</returns>
[Obsolete("This endpoint should not be used.")]
[HttpPost("RegistrationRecords/{name}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<MBRegistrationRecord> GetRegistrationStatus([FromRoute] string name)
{
return new MBRegistrationRecord
@ -178,6 +189,7 @@ namespace Jellyfin.Api.Controllers
/// <exception cref="NotImplementedException">This endpoint is not implemented.</exception>
[Obsolete("Paid plugins are not supported")]
[HttpGet("/Registrations/{name}")]
[ProducesResponseType(StatusCodes.Status501NotImplemented)]
public ActionResult GetRegistration([FromRoute] string name)
{
// TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins,

View file

@ -55,7 +55,7 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets available remote images for an item.
/// </summary>
/// <param name="id">Item Id.</param>
/// <param name="itemId">Item Id.</param>
/// <param name="type">The image type.</param>
/// <param name="startIndex">Optional. The record index to start at. All items with a lower index will be dropped from the results.</param>
/// <param name="limit">Optional. The maximum number of records to return.</param>
@ -64,18 +64,18 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Remote Images returned.</response>
/// <response code="404">Item not found.</response>
/// <returns>Remote Image Result.</returns>
[HttpGet("{Id}/RemoteImages")]
[HttpGet("{itemId}/RemoteImages")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<RemoteImageResult>> GetRemoteImages(
[FromRoute] string id,
[FromRoute] Guid itemId,
[FromQuery] ImageType? type,
[FromQuery] int? startIndex,
[FromQuery] int? limit,
[FromQuery] string providerName,
[FromQuery] bool includeAllLanguages)
{
var item = _libraryManager.GetItemById(id);
var item = _libraryManager.GetItemById(itemId);
if (item == null)
{
return NotFound();
@ -123,16 +123,16 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets available remote image providers for an item.
/// </summary>
/// <param name="id">Item Id.</param>
/// <param name="itemId">Item Id.</param>
/// <response code="200">Returned remote image providers.</response>
/// <response code="404">Item not found.</response>
/// <returns>List of remote image providers.</returns>
[HttpGet("{Id}/RemoteImages/Providers")]
[HttpGet("{itemId}/RemoteImages/Providers")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<IEnumerable<ImageProviderInfo>> GetRemoteImageProviders([FromRoute] string id)
public ActionResult<IEnumerable<ImageProviderInfo>> GetRemoteImageProviders([FromRoute] Guid itemId)
{
var item = _libraryManager.GetItemById(id);
var item = _libraryManager.GetItemById(itemId);
if (item == null)
{
return NotFound();
@ -195,21 +195,21 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Downloads a remote image for an item.
/// </summary>
/// <param name="id">Item Id.</param>
/// <param name="itemId">Item Id.</param>
/// <param name="type">The image type.</param>
/// <param name="imageUrl">The image url.</param>
/// <response code="200">Remote image downloaded.</response>
/// <response code="204">Remote image downloaded.</response>
/// <response code="404">Remote image not found.</response>
/// <returns>Download status.</returns>
[HttpPost("{Id}/RemoteImages/Download")]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpPost("{itemId}/RemoteImages/Download")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> DownloadRemoteImage(
[FromRoute] string id,
[FromRoute] Guid itemId,
[FromQuery, BindRequired] ImageType type,
[FromQuery] string imageUrl)
{
var item = _libraryManager.GetItemById(id);
var item = _libraryManager.GetItemById(itemId);
if (item == null)
{
return NotFound();
@ -219,7 +219,7 @@ namespace Jellyfin.Api.Controllers
.ConfigureAwait(false);
item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
return Ok();
return NoContent();
}
/// <summary>

View file

@ -113,16 +113,16 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Instructs a session to browse to an item or view.
/// </summary>
/// <param name="id">The session Id.</param>
/// <param name="sessionId">The session Id.</param>
/// <param name="itemType">The type of item to browse to.</param>
/// <param name="itemId">The Id of the item.</param>
/// <param name="itemName">The name of the item.</param>
/// <response code="204">Instruction sent to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/Viewing")]
[HttpPost("/Sessions/{sessionId}/Viewing")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult DisplayContent(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromQuery] string itemType,
[FromQuery] string itemId,
[FromQuery] string itemName)
@ -136,7 +136,7 @@ namespace Jellyfin.Api.Controllers
_sessionManager.SendBrowseCommand(
RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
id,
sessionId,
command,
CancellationToken.None);
@ -146,17 +146,17 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Instructs a session to play an item.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="itemIds">The ids of the items to play, comma delimited.</param>
/// <param name="startPositionTicks">The starting position of the first item.</param>
/// <param name="playCommand">The type of play command to issue (PlayNow, PlayNext, PlayLast). Clients who have not yet implemented play next and play last may play now.</param>
/// <param name="playRequest">The <see cref="PlayRequest"/>.</param>
/// <response code="204">Instruction sent to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/Playing")]
[HttpPost("/Sessions/{sessionId}/Playing")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult Play(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromQuery] Guid[] itemIds,
[FromQuery] long? startPositionTicks,
[FromQuery] PlayCommand playCommand,
@ -173,7 +173,7 @@ namespace Jellyfin.Api.Controllers
_sessionManager.SendPlayCommand(
RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
id,
sessionId,
playRequest,
CancellationToken.None);
@ -183,19 +183,19 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Issues a playstate command to a client.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="playstateRequest">The <see cref="PlaystateRequest"/>.</param>
/// <response code="204">Playstate command sent to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/Playing/{command}")]
[HttpPost("/Sessions/{sessionId}/Playing/{command}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendPlaystateCommand(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromBody] PlaystateRequest playstateRequest)
{
_sessionManager.SendPlaystateCommand(
RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
id,
sessionId,
playstateRequest,
CancellationToken.None);
@ -205,14 +205,14 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Issues a system command to a client.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="command">The command to send.</param>
/// <response code="204">System command sent to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/System/{Command}")]
[HttpPost("/Sessions/{sessionId}/System/{command}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendSystemCommand(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromRoute] string command)
{
var name = command;
@ -228,7 +228,7 @@ namespace Jellyfin.Api.Controllers
ControllingUserId = currentSession.UserId
};
_sessionManager.SendGeneralCommand(currentSession.Id, id, generalCommand, CancellationToken.None);
_sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
return NoContent();
}
@ -236,14 +236,14 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Issues a general command to a client.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="command">The command to send.</param>
/// <response code="204">General command sent to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/Command/{Command}")]
[HttpPost("/Sessions/{sessionId}/Command/{Command}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendGeneralCommand(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromRoute] string command)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
@ -254,7 +254,7 @@ namespace Jellyfin.Api.Controllers
ControllingUserId = currentSession.UserId
};
_sessionManager.SendGeneralCommand(currentSession.Id, id, generalCommand, CancellationToken.None);
_sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
return NoContent();
}
@ -262,14 +262,14 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Issues a full general command to a client.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="command">The <see cref="GeneralCommand"/>.</param>
/// <response code="204">Full general command sent to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/Command")]
[HttpPost("/Sessions/{sessionId}/Command")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendFullGeneralCommand(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromBody, Required] GeneralCommand command)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
@ -283,7 +283,7 @@ namespace Jellyfin.Api.Controllers
_sessionManager.SendGeneralCommand(
currentSession.Id,
id,
sessionId,
command,
CancellationToken.None);
@ -293,16 +293,16 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Issues a command to a client to display a message to the user.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="text">The message test.</param>
/// <param name="header">The message header.</param>
/// <param name="timeoutMs">The message timeout. If omitted the user will have to confirm viewing the message.</param>
/// <response code="204">Message sent.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/Message")]
[HttpPost("/Sessions/{sessionId}/Message")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendMessageCommand(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromQuery] string text,
[FromQuery] string header,
[FromQuery] long? timeoutMs)
@ -314,7 +314,7 @@ namespace Jellyfin.Api.Controllers
Text = text
};
_sessionManager.SendMessageCommand(RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id, id, command, CancellationToken.None);
_sessionManager.SendMessageCommand(RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id, sessionId, command, CancellationToken.None);
return NoContent();
}
@ -322,34 +322,34 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Adds an additional user to a session.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="userId">The user id.</param>
/// <response code="204">User added to session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Sessions/{id}/User/{userId}")]
[HttpPost("/Sessions/{sessionId}/User/{userId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult AddUserToSession(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromRoute] Guid userId)
{
_sessionManager.AddAdditionalUser(id, userId);
_sessionManager.AddAdditionalUser(sessionId, userId);
return NoContent();
}
/// <summary>
/// Removes an additional user from a session.
/// </summary>
/// <param name="id">The session id.</param>
/// <param name="sessionId">The session id.</param>
/// <param name="userId">The user id.</param>
/// <response code="204">User removed from session.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpDelete("/Sessions/{id}/User/{userId}")]
[HttpDelete("/Sessions/{sessionId}/User/{userId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult RemoveUserFromSession(
[FromRoute] string id,
[FromRoute] string sessionId,
[FromRoute] Guid userId)
{
_sessionManager.RemoveAdditionalUser(id, userId);
_sessionManager.RemoveAdditionalUser(sessionId, userId);
return NoContent();
}

View file

@ -75,20 +75,20 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Deletes an external subtitle file.
/// </summary>
/// <param name="id">The item id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="index">The index of the subtitle file.</param>
/// <response code="204">Subtitle deleted.</response>
/// <response code="404">Item not found.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpDelete("/Videos/{id}/Subtitles/{index}")]
[HttpDelete("/Videos/{itemId}/Subtitles/{index}")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Task> DeleteSubtitle(
[FromRoute] Guid id,
[FromRoute] Guid itemId,
[FromRoute] int index)
{
var item = _libraryManager.GetItemById(id);
var item = _libraryManager.GetItemById(itemId);
if (item == null)
{
@ -102,20 +102,20 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Search remote subtitles.
/// </summary>
/// <param name="id">The item id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="language">The language of the subtitles.</param>
/// <param name="isPerfectMatch">Optional. Only show subtitles which are a perfect match.</param>
/// <response code="200">Subtitles retrieved.</response>
/// <returns>An array of <see cref="RemoteSubtitleInfo"/>.</returns>
[HttpGet("/Items/{id}/RemoteSearch/Subtitles/{language}")]
[HttpGet("/Items/{itemId}/RemoteSearch/Subtitles/{language}")]
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<RemoteSubtitleInfo>>> SearchRemoteSubtitles(
[FromRoute] Guid id,
[FromRoute] Guid itemId,
[FromRoute] string language,
[FromQuery] bool? isPerfectMatch)
{
var video = (Video)_libraryManager.GetItemById(id);
var video = (Video)_libraryManager.GetItemById(itemId);
return await _subtitleManager.SearchSubtitles(video, language, isPerfectMatch, CancellationToken.None).ConfigureAwait(false);
}
@ -123,18 +123,18 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Downloads a remote subtitle.
/// </summary>
/// <param name="id">The item id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="subtitleId">The subtitle id.</param>
/// <response code="204">Subtitle downloaded.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Items/{id}/RemoteSearch/Subtitles/{subtitleId}")]
[HttpPost("/Items/{itemId}/RemoteSearch/Subtitles/{subtitleId}")]
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> DownloadRemoteSubtitles(
[FromRoute] Guid id,
[FromRoute] Guid itemId,
[FromRoute] string subtitleId)
{
var video = (Video)_libraryManager.GetItemById(id);
var video = (Video)_libraryManager.GetItemById(itemId);
try
{
@ -171,28 +171,28 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets subtitles in a specified format.
/// </summary>
/// <param name="id">The item id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="index">The subtitle stream index.</param>
/// <param name="format">The format of the returned subtitle.</param>
/// <param name="startPositionTicks">Optional. The start position of the subtitle in ticks.</param>
/// <param name="endPositionTicks">Optional. The end position of the subtitle in ticks.</param>
/// <param name="copyTimestamps">Optional. Whether to copy the timestamps.</param>
/// <param name="addVttTimeMap">Optional. Whether to add a VTT time map.</param>
/// <param name="startPositionTicks">Optional. The start position of the subtitle in ticks.</param>
/// <response code="200">File returned.</response>
/// <returns>A <see cref="FileContentResult"/> with the subtitle file.</returns>
[HttpGet("/Videos/{id}/{mediaSourceId}/Subtitles/{index}/Stream.{format}")]
[HttpGet("/Videos/{id}/{mediaSourceId}/Subtitles/{index}/{startPositionTicks}/Stream.{format}")]
[HttpGet("/Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/Stream.{format}")]
[HttpGet("/Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/{startPositionTicks?}/Stream.{format}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> GetSubtitle(
[FromRoute, Required] Guid id,
[FromRoute, Required] Guid itemId,
[FromRoute, Required] string mediaSourceId,
[FromRoute, Required] int index,
[FromRoute, Required] string format,
[FromRoute] long startPositionTicks,
[FromQuery] long? endPositionTicks,
[FromQuery] bool copyTimestamps,
[FromQuery] bool addVttTimeMap)
[FromQuery] bool addVttTimeMap,
[FromRoute] long startPositionTicks = 0)
{
if (string.Equals(format, "js", StringComparison.OrdinalIgnoreCase))
{
@ -201,9 +201,9 @@ namespace Jellyfin.Api.Controllers
if (string.IsNullOrEmpty(format))
{
var item = (Video)_libraryManager.GetItemById(id);
var item = (Video)_libraryManager.GetItemById(itemId);
var idString = id.ToString("N", CultureInfo.InvariantCulture);
var idString = itemId.ToString("N", CultureInfo.InvariantCulture);
var mediaSource = _mediaSourceManager.GetStaticMediaSources(item, false)
.First(i => string.Equals(i.Id, mediaSourceId ?? idString, StringComparison.Ordinal));
@ -216,7 +216,7 @@ namespace Jellyfin.Api.Controllers
if (string.Equals(format, "vtt", StringComparison.OrdinalIgnoreCase) && addVttTimeMap)
{
await using Stream stream = await EncodeSubtitles(id, mediaSourceId, index, format, startPositionTicks, endPositionTicks, copyTimestamps).ConfigureAwait(false);
await using Stream stream = await EncodeSubtitles(itemId, mediaSourceId, index, format, startPositionTicks, endPositionTicks, copyTimestamps).ConfigureAwait(false);
using var reader = new StreamReader(stream);
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
@ -228,7 +228,7 @@ namespace Jellyfin.Api.Controllers
return File(
await EncodeSubtitles(
id,
itemId,
mediaSourceId,
index,
format,
@ -241,23 +241,23 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets an HLS subtitle playlist.
/// </summary>
/// <param name="id">The item id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="index">The subtitle stream index.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="segmentLength">The subtitle segment length.</param>
/// <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")]
[HttpGet("/Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/subtitles.m3u8")]
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
public async Task<ActionResult> GetSubtitlePlaylist(
[FromRoute] Guid id,
[FromRoute] Guid itemId,
[FromRoute] int index,
[FromRoute] string mediaSourceId,
[FromQuery, Required] int segmentLength)
{
var item = (Video)_libraryManager.GetItemById(id);
var item = (Video)_libraryManager.GetItemById(itemId);
var mediaSource = await _mediaSourceManager.GetMediaSource(item, mediaSourceId, null, false, CancellationToken.None).ConfigureAwait(false);

View file

@ -105,17 +105,17 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets a user by Id.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <response code="200">User returned.</response>
/// <response code="404">User not found.</response>
/// <returns>An <see cref="UserDto"/> with information about the user or a <see cref="NotFoundResult"/> if the user was not found.</returns>
[HttpGet("{id}")]
[HttpGet("{userId}")]
[Authorize(Policy = Policies.IgnoreSchedule)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<UserDto> GetUserById([FromRoute] Guid id)
public ActionResult<UserDto> GetUserById([FromRoute] Guid userId)
{
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
if (user == null)
{
@ -129,17 +129,17 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Deletes a user.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <response code="200">User deleted.</response>
/// <response code="404">User not found.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success or a <see cref="NotFoundResult"/> if the user was not found.</returns>
[HttpDelete("{id}")]
[HttpDelete("{userId}")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult DeleteUser([FromRoute] Guid id)
public ActionResult DeleteUser([FromRoute] Guid userId)
{
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
if (user == null)
{
@ -154,23 +154,23 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Authenticates a user.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="pw">The password as plain text.</param>
/// <param name="password">The password sha1-hash.</param>
/// <response code="200">User authenticated.</response>
/// <response code="403">Sha1-hashed password only is not allowed.</response>
/// <response code="404">User not found.</response>
/// <returns>A <see cref="Task"/> containing an <see cref="AuthenticationResult"/>.</returns>
[HttpPost("{id}/Authenticate")]
[HttpPost("{userId}/Authenticate")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<AuthenticationResult>> AuthenticateUser(
[FromRoute, Required] Guid id,
[FromRoute, Required] Guid userId,
[FromQuery, BindRequired] string pw,
[FromQuery, BindRequired] string password)
{
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
if (user == null)
{
@ -230,27 +230,27 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Updates a user's password.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="request">The <see cref="UpdateUserPassword"/> request.</param>
/// <response code="200">Password successfully reset.</response>
/// <response code="403">User is not allowed to update the password.</response>
/// <response code="404">User not found.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success or a <see cref="ForbidResult"/> or a <see cref="NotFoundResult"/> on failure.</returns>
[HttpPost("{id}/Password")]
[HttpPost("{userId}/Password")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> UpdateUserPassword(
[FromRoute] Guid id,
[FromRoute] Guid userId,
[FromBody] UpdateUserPassword request)
{
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, id, true))
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true))
{
return Forbid("User is not allowed to update the password.");
}
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
if (user == null)
{
@ -288,27 +288,27 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Updates a user's easy password.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="request">The <see cref="UpdateUserEasyPassword"/> request.</param>
/// <response code="200">Password successfully reset.</response>
/// <response code="403">User is not allowed to update the password.</response>
/// <response code="404">User not found.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success or a <see cref="ForbidResult"/> or a <see cref="NotFoundResult"/> on failure.</returns>
[HttpPost("{id}/EasyPassword")]
[HttpPost("{userId}/EasyPassword")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult UpdateUserEasyPassword(
[FromRoute] Guid id,
[FromRoute] Guid userId,
[FromBody] UpdateUserEasyPassword request)
{
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, id, true))
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true))
{
return Forbid("User is not allowed to update the easy password.");
}
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
if (user == null)
{
@ -330,19 +330,19 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Updates a user.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="updateUser">The updated user model.</param>
/// <response code="204">User updated.</response>
/// <response code="400">User information was not supplied.</response>
/// <response code="403">User update forbidden.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success or a <see cref="BadRequestResult"/> or a <see cref="ForbidResult"/> on failure.</returns>
[HttpPost("{id}")]
[HttpPost("{userId}")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult> UpdateUser(
[FromRoute] Guid id,
[FromRoute] Guid userId,
[FromBody] UserDto updateUser)
{
if (updateUser == null)
@ -350,12 +350,12 @@ namespace Jellyfin.Api.Controllers
return BadRequest();
}
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, id, false))
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, false))
{
return Forbid("User update not allowed.");
}
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
if (string.Equals(user.Username, updateUser.Name, StringComparison.Ordinal))
{
@ -374,19 +374,19 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Updates a user policy.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="newPolicy">The new user policy.</param>
/// <response code="204">User policy updated.</response>
/// <response code="400">User policy was not supplied.</response>
/// <response code="403">User policy update forbidden.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success or a <see cref="BadRequestResult"/> or a <see cref="ForbidResult"/> on failure..</returns>
[HttpPost("{id}/Policy")]
[HttpPost("{userId}/Policy")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult UpdateUserPolicy(
[FromRoute] Guid id,
[FromRoute] Guid userId,
[FromBody] UserPolicy newPolicy)
{
if (newPolicy == null)
@ -394,7 +394,7 @@ namespace Jellyfin.Api.Controllers
return BadRequest();
}
var user = _userManager.GetUserById(id);
var user = _userManager.GetUserById(userId);
// If removing admin access
if (!(newPolicy.IsAdministrator && user.HasPermission(PermissionKind.IsAdministrator)))
@ -423,7 +423,7 @@ namespace Jellyfin.Api.Controllers
_sessionManager.RevokeUserTokens(user.Id, currentToken);
}
_userManager.UpdatePolicy(id, newPolicy);
_userManager.UpdatePolicy(userId, newPolicy);
return NoContent();
}
@ -431,25 +431,25 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Updates a user configuration.
/// </summary>
/// <param name="id">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="userConfig">The new user configuration.</param>
/// <response code="204">User configuration updated.</response>
/// <response code="403">User configuration update forbidden.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
[HttpPost("{id}/Configuration")]
[HttpPost("{userId}/Configuration")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult UpdateUserConfiguration(
[FromRoute] Guid id,
[FromRoute] Guid userId,
[FromBody] UserConfiguration userConfig)
{
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, id, false))
if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, false))
{
return Forbid("User configuration update not allowed");
}
_userManager.UpdateConfiguration(id, userConfig);
_userManager.UpdateConfiguration(userId, userConfig);
return NoContent();
}

View file

@ -44,7 +44,7 @@ namespace Jellyfin.Api.Controllers
/// <response code="200">Attachment retrieved.</response>
/// <response code="404">Video or attachment not found.</response>
/// <returns>An <see cref="FileStreamResult"/> containing the attachment stream on success, or a <see cref="NotFoundResult"/> if the attachment could not be found.</returns>
[HttpGet("{VideoID}/{MediaSourceID}/Attachments/{Index}")]
[HttpGet("{videoId}/{mediaSourceId}/Attachments/{index}")]
[Produces(MediaTypeNames.Application.Octet)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]