< Summary - Jellyfin

Information
Class: Jellyfin.Api.Helpers.RequestHelpers
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Helpers/RequestHelpers.cs
Line coverage
45%
Covered lines: 22
Uncovered lines: 26
Coverable lines: 48
Total lines: 178
Line coverage: 45.8%
Branch coverage
90%
Covered branches: 18
Total branches: 20
Branch coverage: 90%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetOrderBy(...)100%88100%
GetUserId(...)100%66100%
AssertCanUpdateUser(...)66.66%6.84671.42%
CreateQueryResult(...)100%210%

File(s)

/srv/git/jellyfin/Jellyfin.Api/Helpers/RequestHelpers.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Security.Claims;
 5using System.Threading.Tasks;
 6using Jellyfin.Api.Constants;
 7using Jellyfin.Api.Extensions;
 8using Jellyfin.Data.Entities;
 9using Jellyfin.Data.Enums;
 10using Jellyfin.Extensions;
 11using MediaBrowser.Common.Extensions;
 12using MediaBrowser.Controller.Dto;
 13using MediaBrowser.Controller.Entities;
 14using MediaBrowser.Controller.Library;
 15using MediaBrowser.Controller.Net;
 16using MediaBrowser.Controller.Session;
 17using MediaBrowser.Model.Dto;
 18using MediaBrowser.Model.Querying;
 19using Microsoft.AspNetCore.Http;
 20
 21namespace Jellyfin.Api.Helpers;
 22
 23/// <summary>
 24/// Request Extensions.
 25/// </summary>
 26public static class RequestHelpers
 27{
 28    /// <summary>
 29    /// Get Order By.
 30    /// </summary>
 31    /// <param name="sortBy">Sort By. Comma delimited string.</param>
 32    /// <param name="requestedSortOrder">Sort Order. Comma delimited string.</param>
 33    /// <returns>Order By.</returns>
 34    public static (ItemSortBy, SortOrder)[] GetOrderBy(IReadOnlyList<ItemSortBy> sortBy, IReadOnlyList<SortOrder> reques
 35    {
 336        if (sortBy.Count == 0)
 37        {
 138            return Array.Empty<(ItemSortBy, SortOrder)>();
 39        }
 40
 241        var result = new (ItemSortBy, SortOrder)[sortBy.Count];
 242        var i = 0;
 43        // Add elements which have a SortOrder specified
 444        for (; i < requestedSortOrder.Count; i++)
 45        {
 146            result[i] = (sortBy[i], requestedSortOrder[i]);
 47        }
 48
 49        // Add remaining elements with the first specified SortOrder
 50        // or the default one if no SortOrders are specified
 251        var order = requestedSortOrder.Count > 0 ? requestedSortOrder[0] : SortOrder.Ascending;
 852        for (; i < sortBy.Count; i++)
 53        {
 354            result[i] = (sortBy[i], order);
 55        }
 56
 257        return result;
 58    }
 59
 60    /// <summary>
 61    /// Checks if the user can access a user.
 62    /// </summary>
 63    /// <param name="claimsPrincipal">The <see cref="ClaimsPrincipal"/> for the current request.</param>
 64    /// <param name="userId">The user id.</param>
 65    /// <returns>A <see cref="bool"/> whether the user can access the user.</returns>
 66    internal static Guid GetUserId(ClaimsPrincipal claimsPrincipal, Guid? userId)
 67    {
 5068        var authenticatedUserId = claimsPrincipal.GetUserId();
 69
 70        // UserId not provided, fall back to authenticated user id.
 5071        if (userId.IsNullOrEmpty())
 72        {
 1673            return authenticatedUserId;
 74        }
 75
 76        // User must be administrator to access another user.
 3477        var isAdministrator = claimsPrincipal.IsInRole(UserRoles.Administrator);
 3478        if (!userId.Value.Equals(authenticatedUserId) && !isAdministrator)
 79        {
 180            throw new SecurityException("Forbidden");
 81        }
 82
 3383        return userId.Value;
 84    }
 85
 86    /// <summary>
 87    /// Checks if the user can update an entry.
 88    /// </summary>
 89    /// <param name="claimsPrincipal">The <see cref="ClaimsPrincipal"/> for the current request.</param>
 90    /// <param name="user">The user id.</param>
 91    /// <param name="restrictUserPreferences">Whether to restrict the user preferences.</param>
 92    /// <returns>A <see cref="bool"/> whether the user can update the entry.</returns>
 93    internal static bool AssertCanUpdateUser(ClaimsPrincipal claimsPrincipal, User user, bool restrictUserPreferences)
 94    {
 295        var authenticatedUserId = claimsPrincipal.GetUserId();
 296        var isAdministrator = claimsPrincipal.IsInRole(UserRoles.Administrator);
 97
 98        // If they're going to update the record of another user, they must be an administrator
 299        if (!user.Id.Equals(authenticatedUserId) && !isAdministrator)
 100        {
 0101            return false;
 102        }
 103
 104        // TODO the EnableUserPreferenceAccess policy does not seem to be used elsewhere
 2105        if (!restrictUserPreferences || isAdministrator)
 106        {
 2107            return true;
 108        }
 109
 0110        return user.EnableUserPreferenceAccess;
 111    }
 112
 113    internal static async Task<SessionInfo> GetSession(ISessionManager sessionManager, IUserManager userManager, HttpCon
 114    {
 115        userId ??= httpContext.User.GetUserId();
 116        User? user = null;
 117        if (!userId.IsNullOrEmpty())
 118        {
 119            user = userManager.GetUserById(userId.Value);
 120        }
 121
 122        var session = await sessionManager.LogSessionActivity(
 123            httpContext.User.GetClient(),
 124            httpContext.User.GetVersion(),
 125            httpContext.User.GetDeviceId(),
 126            httpContext.User.GetDevice(),
 127            httpContext.GetNormalizedRemoteIP().ToString(),
 128            user).ConfigureAwait(false);
 129
 130        if (session is null)
 131        {
 132            throw new ResourceNotFoundException("Session not found.");
 133        }
 134
 135        return session;
 136    }
 137
 138    internal static async Task<string> GetSessionId(ISessionManager sessionManager, IUserManager userManager, HttpContex
 139    {
 140        var session = await GetSession(sessionManager, userManager, httpContext).ConfigureAwait(false);
 141
 142        return session.Id;
 143    }
 144
 145    internal static QueryResult<BaseItemDto> CreateQueryResult(
 146        QueryResult<(BaseItem Item, ItemCounts ItemCounts)> result,
 147        DtoOptions dtoOptions,
 148        IDtoService dtoService,
 149        bool includeItemTypes,
 150        User? user)
 151    {
 0152        var dtos = result.Items.Select(i =>
 0153        {
 0154            var (baseItem, counts) = i;
 0155            var dto = dtoService.GetItemByNameDto(baseItem, dtoOptions, null, user);
 0156
 0157            if (includeItemTypes)
 0158            {
 0159                dto.ChildCount = counts.ItemCount;
 0160                dto.ProgramCount = counts.ProgramCount;
 0161                dto.SeriesCount = counts.SeriesCount;
 0162                dto.EpisodeCount = counts.EpisodeCount;
 0163                dto.MovieCount = counts.MovieCount;
 0164                dto.TrailerCount = counts.TrailerCount;
 0165                dto.AlbumCount = counts.AlbumCount;
 0166                dto.SongCount = counts.SongCount;
 0167                dto.ArtistCount = counts.ArtistCount;
 0168            }
 0169
 0170            return dto;
 0171        });
 172
 0173        return new QueryResult<BaseItemDto>(
 0174            result.StartIndex,
 0175            result.TotalRecordCount,
 0176            dtos.ToArray());
 177    }
 178}