Merge branch 'master' into network-rewrite

This commit is contained in:
Shadowghost
2023-02-20 11:58:14 +01:00
86 changed files with 766 additions and 531 deletions

View File

@@ -118,6 +118,7 @@ public class ArtistsController : BaseJellyfinApiController
[FromQuery] bool? enableImages = true,
[FromQuery] bool enableTotalRecordCount = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
@@ -125,7 +126,7 @@ public class ArtistsController : BaseJellyfinApiController
User? user = null;
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
if (userId.HasValue && !userId.Equals(default))
if (!userId.Value.Equals(default))
{
user = _userManager.GetUserById(userId.Value);
}
@@ -321,6 +322,7 @@ public class ArtistsController : BaseJellyfinApiController
[FromQuery] bool? enableImages = true,
[FromQuery] bool enableTotalRecordCount = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
@@ -328,7 +330,7 @@ public class ArtistsController : BaseJellyfinApiController
User? user = null;
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
if (userId.HasValue && !userId.Equals(default))
if (!userId.Value.Equals(default))
{
user = _userManager.GetUserById(userId.Value);
}
@@ -462,11 +464,12 @@ public class ArtistsController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<BaseItemDto> GetArtistByName([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions().AddClientFields(User);
var item = _libraryManager.GetArtist(name, dtoOptions);
if (userId.HasValue && !userId.Value.Equals(default))
if (!userId.Value.Equals(default))
{
var user = _userManager.GetUserById(userId.Value);

View File

@@ -60,11 +60,12 @@ public class ChannelsController : BaseJellyfinApiController
[FromQuery] bool? supportsMediaDeletion,
[FromQuery] bool? isFavorite)
{
userId = RequestHelpers.GetUserId(User, userId);
return _channelManager.GetChannels(new ChannelQuery
{
Limit = limit,
StartIndex = startIndex,
UserId = userId ?? Guid.Empty,
UserId = userId.Value,
SupportsLatestItems = supportsLatestItems,
SupportsMediaDeletion = supportsMediaDeletion,
IsFavorite = isFavorite
@@ -124,7 +125,8 @@ public class ChannelsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -198,7 +200,8 @@ public class ChannelsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] channelIds)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);

View File

@@ -2,6 +2,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using Jellyfin.Data.Dtos;
using Jellyfin.Data.Entities.Security;
using Jellyfin.Data.Queries;
@@ -48,6 +49,7 @@ public class DevicesController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<QueryResult<DeviceInfo>>> GetDevices([FromQuery] bool? supportsSync, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
return await _deviceManager.GetDevicesForUser(userId, supportsSync).ConfigureAwait(false);
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Linq;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
@@ -51,7 +53,8 @@ public class FilterController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -143,7 +146,8 @@ public class FilterController : BaseJellyfinApiController
[FromQuery] bool? isSeries,
[FromQuery] bool? recursive)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);

View File

@@ -90,11 +90,12 @@ public class GenresController : BaseJellyfinApiController
[FromQuery] bool? enableImages = true,
[FromQuery] bool enableTotalRecordCount = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
User? user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -155,6 +156,7 @@ public class GenresController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<BaseItemDto> GetGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions()
.AddClientFields(User);
@@ -170,7 +172,7 @@ public class GenresController : BaseJellyfinApiController
item ??= new Genre();
if (userId is null || userId.Value.Equals(default))
if (userId.Value.Equals(default))
{
return _dtoService.GetBaseItemDto(item, dtoOptions);
}

View File

@@ -91,6 +91,7 @@ public class ImageController : BaseJellyfinApiController
[Authorize]
[AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
@@ -110,6 +111,11 @@ public class ImageController : BaseJellyfinApiController
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
}
if (!TryGetImageExtensionFromContentType(Request.ContentType, out string? extension))
{
return BadRequest("Incorrect ContentType.");
}
var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
await using (memoryStream.ConfigureAwait(false))
{
@@ -121,7 +127,7 @@ public class ImageController : BaseJellyfinApiController
await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
}
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType ?? string.Empty)));
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + extension));
await _providerManager
.SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
@@ -145,6 +151,7 @@ public class ImageController : BaseJellyfinApiController
[Authorize]
[AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
@@ -164,6 +171,11 @@ public class ImageController : BaseJellyfinApiController
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
}
if (!TryGetImageExtensionFromContentType(Request.ContentType, out string? extension))
{
return BadRequest("Incorrect ContentType.");
}
var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
await using (memoryStream.ConfigureAwait(false))
{
@@ -175,7 +187,7 @@ public class ImageController : BaseJellyfinApiController
await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
}
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType ?? string.Empty)));
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + extension));
await _providerManager
.SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
@@ -342,6 +354,7 @@ public class ImageController : BaseJellyfinApiController
[Authorize(Policy = Policies.RequiresElevation)]
[AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
public async Task<ActionResult> SetItemImage(
@@ -354,6 +367,11 @@ public class ImageController : BaseJellyfinApiController
return NotFound();
}
if (!TryGetImageExtensionFromContentType(Request.ContentType, out _))
{
return BadRequest("Incorrect ContentType.");
}
var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
await using (memoryStream.ConfigureAwait(false))
{
@@ -379,6 +397,7 @@ public class ImageController : BaseJellyfinApiController
[Authorize(Policy = Policies.RequiresElevation)]
[AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
public async Task<ActionResult> SetItemImageByIndex(
@@ -392,6 +411,11 @@ public class ImageController : BaseJellyfinApiController
return NotFound();
}
if (!TryGetImageExtensionFromContentType(Request.ContentType, out _))
{
return BadRequest("Incorrect ContentType.");
}
var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
await using (memoryStream.ConfigureAwait(false))
{
@@ -1763,22 +1787,14 @@ public class ImageController : BaseJellyfinApiController
[AcceptsImageFile]
public async Task<ActionResult> UploadCustomSplashscreen()
{
if (!TryGetImageExtensionFromContentType(Request.ContentType, out var extension))
{
return BadRequest("Incorrect ContentType.");
}
var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
await using (memoryStream.ConfigureAwait(false))
{
var mimeType = MediaTypeHeaderValue.Parse(Request.ContentType).MediaType;
if (!mimeType.HasValue)
{
return BadRequest("Error reading mimetype from uploaded image");
}
var extension = MimeTypes.ToExtension(mimeType.Value);
if (string.IsNullOrEmpty(extension))
{
return BadRequest("Error converting mimetype to an image extension");
}
var filePath = Path.Combine(_appPaths.DataPath, "splashscreen-upload" + extension);
var brandingOptions = _serverConfigurationManager.GetConfiguration<BrandingOptions>("branding");
brandingOptions.SplashscreenLocation = filePath;
@@ -2106,4 +2122,23 @@ public class ImageController : BaseJellyfinApiController
return PhysicalFile(imagePath, imageContentType ?? MediaTypeNames.Text.Plain);
}
internal static bool TryGetImageExtensionFromContentType(string? contentType, [NotNullWhen(true)] out string? extension)
{
extension = null;
if (string.IsNullOrEmpty(contentType))
{
return false;
}
if (MediaTypeHeaderValue.TryParse(contentType, out var parsedValue)
&& parsedValue.MediaType.HasValue
&& MimeTypes.IsImage(parsedValue.MediaType.Value))
{
extension = MimeTypes.ToExtension(parsedValue.MediaType.Value);
return extension is not null;
}
return false;
}
}

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Dto;
@@ -74,7 +75,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var item = _libraryManager.GetItemById(id);
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
@@ -110,7 +112,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var album = _libraryManager.GetItemById(id);
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
@@ -146,7 +149,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var playlist = (Playlist)_libraryManager.GetItemById(id);
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
@@ -181,7 +185,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery] int? imageTypeLimit,
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
@@ -217,7 +222,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var item = _libraryManager.GetItemById(id);
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
@@ -253,7 +259,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var item = _libraryManager.GetItemById(id);
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
@@ -326,7 +333,8 @@ public class InstantMixController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
{
var item = _libraryManager.GetItemById(id);
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }

View File

@@ -240,7 +240,8 @@ public class ItemsController : BaseJellyfinApiController
{
var isApiKey = User.GetIsApiKey();
// if api key is used (auth.IsApiKey == true), then `user` will be null throughout this method
var user = !isApiKey && userId.HasValue && !userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = !isApiKey && !userId.Value.Equals(default)
? _userManager.GetUserById(userId.Value) ?? throw new ResourceNotFoundException()
: null;

View File

@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.LibraryDtos;
using Jellyfin.Data.Entities;
@@ -142,12 +143,13 @@ public class LibraryController : BaseJellyfinApiController
[FromQuery] Guid? userId,
[FromQuery] bool inheritFromParent = false)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var item = itemId.Equals(default)
? (userId is null || userId.Value.Equals(default)
? (userId.Value.Equals(default)
? _libraryManager.RootFolder
: _libraryManager.GetUserRootFolder())
: _libraryManager.GetItemById(itemId);
@@ -208,12 +210,13 @@ public class LibraryController : BaseJellyfinApiController
[FromQuery] Guid? userId,
[FromQuery] bool inheritFromParent = false)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var item = itemId.Equals(default)
? (userId is null || userId.Value.Equals(default)
? (userId.Value.Equals(default)
? _libraryManager.RootFolder
: _libraryManager.GetUserRootFolder())
: _libraryManager.GetItemById(itemId);
@@ -403,7 +406,8 @@ public class LibraryController : BaseJellyfinApiController
[FromQuery] Guid? userId,
[FromQuery] bool? isFavorite)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -437,6 +441,7 @@ public class LibraryController : BaseJellyfinApiController
public ActionResult<IEnumerable<BaseItemDto>> GetAncestors([FromRoute, Required] Guid itemId, [FromQuery] Guid? userId)
{
var item = _libraryManager.GetItemById(itemId);
userId = RequestHelpers.GetUserId(User, userId);
if (item is null)
{
@@ -445,7 +450,7 @@ public class LibraryController : BaseJellyfinApiController
var baseItemDtos = new List<BaseItemDto>();
var user = userId is null || userId.Value.Equals(default)
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -675,8 +680,9 @@ public class LibraryController : BaseJellyfinApiController
[FromQuery] int? limit,
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
{
userId = RequestHelpers.GetUserId(User, userId);
var item = itemId.Equals(default)
? (userId is null || userId.Value.Equals(default)
? (userId.Value.Equals(default)
? _libraryManager.RootFolder
: _libraryManager.GetUserRootFolder())
: _libraryManager.GetItemById(itemId);
@@ -691,7 +697,7 @@ public class LibraryController : BaseJellyfinApiController
return new QueryResult<BaseItemDto>();
}
var user = userId is null || userId.Value.Equals(default)
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }

View File

@@ -153,6 +153,7 @@ public class LiveTvController : BaseJellyfinApiController
[FromQuery] bool enableFavoriteSorting = false,
[FromQuery] bool addCurrentProgram = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
@@ -161,7 +162,7 @@ public class LiveTvController : BaseJellyfinApiController
new LiveTvChannelQuery
{
ChannelType = type,
UserId = userId ?? Guid.Empty,
UserId = userId.Value,
StartIndex = startIndex,
Limit = limit,
IsFavorite = isFavorite,
@@ -180,7 +181,7 @@ public class LiveTvController : BaseJellyfinApiController
dtoOptions,
CancellationToken.None);
var user = userId is null || userId.Value.Equals(default)
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -211,7 +212,8 @@ public class LiveTvController : BaseJellyfinApiController
[Authorize(Policy = Policies.LiveTvAccess)]
public ActionResult<BaseItemDto> GetChannel([FromRoute, Required] Guid channelId, [FromQuery] Guid? userId)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var item = channelId.Equals(default)
@@ -271,6 +273,7 @@ public class LiveTvController : BaseJellyfinApiController
[FromQuery] bool? isLibraryItem,
[FromQuery] bool enableTotalRecordCount = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
@@ -279,7 +282,7 @@ public class LiveTvController : BaseJellyfinApiController
new RecordingQuery
{
ChannelId = channelId,
UserId = userId ?? Guid.Empty,
UserId = userId.Value,
StartIndex = startIndex,
Limit = limit,
Status = status,
@@ -382,7 +385,8 @@ public class LiveTvController : BaseJellyfinApiController
[Authorize(Policy = Policies.LiveTvAccess)]
public ActionResult<QueryResult<BaseItemDto>> GetRecordingFolders([FromQuery] Guid? userId)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var folders = _liveTvManager.GetRecordingFolders(user);
@@ -404,7 +408,8 @@ public class LiveTvController : BaseJellyfinApiController
[Authorize(Policy = Policies.LiveTvAccess)]
public ActionResult<BaseItemDto> GetRecording([FromRoute, Required] Guid recordingId, [FromQuery] Guid? userId)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var item = recordingId.Equals(default) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId);
@@ -560,7 +565,8 @@ public class LiveTvController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
[FromQuery] bool enableTotalRecordCount = true)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -699,7 +705,8 @@ public class LiveTvController : BaseJellyfinApiController
[FromQuery] bool? enableUserData,
[FromQuery] bool enableTotalRecordCount = true)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -737,7 +744,8 @@ public class LiveTvController : BaseJellyfinApiController
[FromRoute, Required] string programId,
[FromQuery] Guid? userId)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);

View File

@@ -132,6 +132,7 @@ public class MediaInfoController : BaseJellyfinApiController
// Copy params from posted body
// TODO clean up when breaking API compatibility.
userId ??= playbackInfoDto?.UserId;
userId = RequestHelpers.GetUserId(User, userId);
maxStreamingBitrate ??= playbackInfoDto?.MaxStreamingBitrate;
startTimeTicks ??= playbackInfoDto?.StartTimeTicks;
audioStreamIndex ??= playbackInfoDto?.AudioStreamIndex;
@@ -253,10 +254,12 @@ public class MediaInfoController : BaseJellyfinApiController
[FromQuery] bool? enableDirectPlay,
[FromQuery] bool? enableDirectStream)
{
userId ??= openLiveStreamDto?.UserId;
userId = RequestHelpers.GetUserId(User, userId);
var request = new LiveStreamRequest
{
OpenToken = openToken ?? openLiveStreamDto?.OpenToken,
UserId = userId ?? openLiveStreamDto?.UserId ?? Guid.Empty,
UserId = userId.Value,
PlaySessionId = playSessionId ?? openLiveStreamDto?.PlaySessionId,
MaxStreamingBitrate = maxStreamingBitrate ?? openLiveStreamDto?.MaxStreamingBitrate,
StartTimeTicks = startTimeTicks ?? openLiveStreamDto?.StartTimeTicks,

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
@@ -67,7 +68,8 @@ public class MoviesController : BaseJellyfinApiController
[FromQuery] int categoryLimit = 5,
[FromQuery] int itemLimit = 8)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }

View File

@@ -90,11 +90,12 @@ public class MusicGenresController : BaseJellyfinApiController
[FromQuery] bool? enableImages = true,
[FromQuery] bool enableTotalRecordCount = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
User? user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -144,6 +145,7 @@ public class MusicGenresController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<BaseItemDto> GetMusicGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions().AddClientFields(User);
MusicGenre? item;
@@ -162,7 +164,7 @@ public class MusicGenresController : BaseJellyfinApiController
return NotFound();
}
if (userId.HasValue && !userId.Value.Equals(default))
if (!userId.Value.Equals(default))
{
var user = _userManager.GetUserById(userId.Value);

View File

@@ -2,6 +2,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Dto;
@@ -77,11 +78,12 @@ public class PersonsController : BaseJellyfinApiController
[FromQuery] Guid? userId,
[FromQuery] bool? enableImages = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
User? user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -117,6 +119,7 @@ public class PersonsController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<BaseItemDto> GetPerson([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions()
.AddClientFields(User);
@@ -126,7 +129,7 @@ public class PersonsController : BaseJellyfinApiController
return NotFound();
}
if (userId.HasValue && !userId.Value.Equals(default))
if (!userId.Value.Equals(default))
{
var user = _userManager.GetUserById(userId.Value);
return _dtoService.GetBaseItemDto(item, dtoOptions, user);

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.PlaylistDtos;
using MediaBrowser.Controller.Dto;
@@ -81,11 +82,13 @@ public class PlaylistsController : BaseJellyfinApiController
ids = createPlaylistRequest?.Ids ?? Array.Empty<Guid>();
}
userId ??= createPlaylistRequest?.UserId ?? default;
userId = RequestHelpers.GetUserId(User, userId);
var result = await _playlistManager.CreatePlaylist(new PlaylistCreationRequest
{
Name = name ?? createPlaylistRequest?.Name,
ItemIdList = ids,
UserId = userId ?? createPlaylistRequest?.UserId ?? default,
UserId = userId.Value,
MediaType = mediaType ?? createPlaylistRequest?.MediaType
}).ConfigureAwait(false);
@@ -107,7 +110,8 @@ public class PlaylistsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids,
[FromQuery] Guid? userId)
{
await _playlistManager.AddToPlaylistAsync(playlistId, ids, userId ?? Guid.Empty).ConfigureAwait(false);
userId = RequestHelpers.GetUserId(User, userId);
await _playlistManager.AddToPlaylistAsync(playlistId, ids, userId.Value).ConfigureAwait(false);
return NoContent();
}

View File

@@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Net;
@@ -116,17 +117,11 @@ public class QuickConnectController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<bool>> AuthorizeQuickConnect([FromQuery, Required] string code, [FromQuery] Guid? userId = null)
{
var currentUserId = User.GetUserId();
var actualUserId = userId ?? currentUserId;
if (actualUserId.Equals(default) || (!userId.Equals(currentUserId) && !User.IsInRole(UserRoles.Administrator)))
{
return Forbid("Unknown user id");
}
userId = RequestHelpers.GetUserId(User, userId);
try
{
return await _quickConnect.AuthorizeRequest(actualUserId, code).ConfigureAwait(false);
return await _quickConnect.AuthorizeRequest(userId.Value, code).ConfigureAwait(false);
}
catch (AuthenticationException)
{

View File

@@ -3,6 +3,8 @@ using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
@@ -98,6 +100,7 @@ public class SearchController : BaseJellyfinApiController
[FromQuery] bool includeStudios = true,
[FromQuery] bool includeArtists = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var result = _searchEngine.GetSearchHints(new SearchQuery
{
Limit = limit,
@@ -108,7 +111,7 @@ public class SearchController : BaseJellyfinApiController
IncludePeople = includePeople,
IncludeStudios = includeStudios,
StartIndex = startIndex,
UserId = userId ?? Guid.Empty,
UserId = userId.Value,
IncludeItemTypes = includeItemTypes,
ExcludeItemTypes = excludeItemTypes,
MediaTypes = mediaTypes,

View File

@@ -86,11 +86,12 @@ public class StudiosController : BaseJellyfinApiController
[FromQuery] bool? enableImages = true,
[FromQuery] bool enableTotalRecordCount = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
User? user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -139,10 +140,11 @@ public class StudiosController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<BaseItemDto> GetStudio([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions().AddClientFields(User);
var item = _libraryManager.GetStudio(name);
if (userId.HasValue && !userId.Equals(default))
if (!userId.Equals(default))
{
var user = _userManager.GetUserById(userId.Value);

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
@@ -87,6 +88,7 @@ public class TvShowsController : BaseJellyfinApiController
[FromQuery] bool disableFirstEpisode = false,
[FromQuery] bool enableRewatching = false)
{
userId = RequestHelpers.GetUserId(User, userId);
var options = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
@@ -98,7 +100,7 @@ public class TvShowsController : BaseJellyfinApiController
ParentId = parentId,
SeriesId = seriesId,
StartIndex = startIndex,
UserId = userId ?? Guid.Empty,
UserId = userId.Value,
EnableTotalRecordCount = enableTotalRecordCount,
DisableFirstEpisode = disableFirstEpisode,
NextUpDateCutoff = nextUpDateCutoff ?? DateTime.MinValue,
@@ -106,7 +108,7 @@ public class TvShowsController : BaseJellyfinApiController
},
options);
var user = userId is null || userId.Value.Equals(default)
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -144,7 +146,8 @@ public class TvShowsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
[FromQuery] bool? enableUserData)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -215,7 +218,8 @@ public class TvShowsController : BaseJellyfinApiController
[FromQuery] bool? enableUserData,
[FromQuery] string? sortBy)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
@@ -331,7 +335,8 @@ public class TvShowsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
[FromQuery] bool? enableUserData)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);

View File

@@ -106,11 +106,7 @@ public class UniversalAudioController : BaseJellyfinApiController
[FromQuery] bool enableRedirection = true)
{
var deviceProfile = GetDeviceProfile(container, transcodingContainer, audioCodec, transcodingProtocol, breakOnNonKeyFrames, transcodingAudioChannels, maxAudioSampleRate, maxAudioBitDepth, maxAudioChannels);
if (!userId.HasValue || userId.Value.Equals(default))
{
userId = User.GetUserId();
}
userId = RequestHelpers.GetUserId(User, userId);
_logger.LogInformation("GetPostedPlaybackInfo profile: {@Profile}", deviceProfile);

View File

@@ -104,12 +104,13 @@ public class VideosController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<QueryResult<BaseItemDto>> GetAdditionalPart([FromRoute, Required] Guid itemId, [FromQuery] Guid? userId)
{
var user = userId is null || userId.Value.Equals(default)
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
var item = itemId.Equals(default)
? (userId is null || userId.Value.Equals(default)
? (userId.Value.Equals(default)
? _libraryManager.RootFolder
: _libraryManager.GetUserRootFolder())
: _libraryManager.GetItemById(itemId);

View File

@@ -85,11 +85,12 @@ public class YearsController : BaseJellyfinApiController
[FromQuery] bool recursive = true,
[FromQuery] bool? enableImages = true)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
User? user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
@@ -171,6 +172,7 @@ public class YearsController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<BaseItemDto> GetYear([FromRoute, Required] int year, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var item = _libraryManager.GetYear(year);
if (item is null)
{
@@ -180,7 +182,7 @@ public class YearsController : BaseJellyfinApiController
var dtoOptions = new DtoOptions()
.AddClientFields(User);
if (userId.HasValue && !userId.Value.Equals(default))
if (!userId.Value.Equals(default))
{
var user = _userManager.GetUserById(userId.Value);
return _dtoService.GetBaseItemDto(item, dtoOptions, user);