< 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: 188
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%7671.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.Enums;
 9using Jellyfin.Database.Implementations.Entities;
 10using Jellyfin.Database.Implementations.Enums;
 11using Jellyfin.Extensions;
 12using MediaBrowser.Common.Extensions;
 13using MediaBrowser.Controller.Dto;
 14using MediaBrowser.Controller.Entities;
 15using MediaBrowser.Controller.Library;
 16using MediaBrowser.Controller.Net;
 17using MediaBrowser.Controller.Session;
 18using MediaBrowser.Model.Dto;
 19using MediaBrowser.Model.Querying;
 20using Microsoft.AspNetCore.Http;
 21
 22namespace Jellyfin.Api.Helpers;
 23
 24/// <summary>
 25/// Request Extensions.
 26/// </summary>
 27public static class RequestHelpers
 28{
 29    /// <summary>
 30    /// Get Order By.
 31    /// </summary>
 32    /// <param name="sortBy">Sort By. Comma delimited string.</param>
 33    /// <param name="requestedSortOrder">Sort Order. Comma delimited string.</param>
 34    /// <returns>Order By.</returns>
 35    public static (ItemSortBy, SortOrder)[] GetOrderBy(IReadOnlyList<ItemSortBy> sortBy, IReadOnlyList<SortOrder> reques
 36    {
 337        if (sortBy.Count == 0)
 38        {
 139            return Array.Empty<(ItemSortBy, SortOrder)>();
 40        }
 41
 242        var result = new (ItemSortBy, SortOrder)[sortBy.Count];
 243        var i = 0;
 44        // Add elements which have a SortOrder specified
 445        for (; i < requestedSortOrder.Count; i++)
 46        {
 147            result[i] = (sortBy[i], requestedSortOrder[i]);
 48        }
 49
 50        // Add remaining elements with the first specified SortOrder
 51        // or the default one if no SortOrders are specified
 252        var order = requestedSortOrder.Count > 0 ? requestedSortOrder[0] : SortOrder.Ascending;
 853        for (; i < sortBy.Count; i++)
 54        {
 355            result[i] = (sortBy[i], order);
 56        }
 57
 258        return result;
 59    }
 60
 61    /// <summary>
 62    /// Checks if the user can access a user.
 63    /// </summary>
 64    /// <param name="claimsPrincipal">The <see cref="ClaimsPrincipal"/> for the current request.</param>
 65    /// <param name="userId">The user id.</param>
 66    /// <returns>A <see cref="bool"/> whether the user can access the user.</returns>
 67    internal static Guid GetUserId(ClaimsPrincipal claimsPrincipal, Guid? userId)
 68    {
 4269        var authenticatedUserId = claimsPrincipal.GetUserId();
 70
 71        // UserId not provided, fall back to authenticated user id.
 4272        if (userId.IsNullOrEmpty())
 73        {
 1674            return authenticatedUserId;
 75        }
 76
 77        // User must be administrator to access another user.
 2678        var isAdministrator = claimsPrincipal.IsInRole(UserRoles.Administrator);
 2679        if (!userId.Value.Equals(authenticatedUserId) && !isAdministrator)
 80        {
 181            throw new SecurityException("Forbidden");
 82        }
 83
 2584        return userId.Value;
 85    }
 86
 87    /// <summary>
 88    /// Checks if the user can update an entry.
 89    /// </summary>
 90    /// <param name="claimsPrincipal">The <see cref="ClaimsPrincipal"/> for the current request.</param>
 91    /// <param name="user">The user id.</param>
 92    /// <param name="restrictUserPreferences">Whether to restrict the user preferences.</param>
 93    /// <returns>A <see cref="bool"/> whether the user can update the entry.</returns>
 94    internal static bool AssertCanUpdateUser(ClaimsPrincipal claimsPrincipal, User user, bool restrictUserPreferences)
 95    {
 296        var authenticatedUserId = claimsPrincipal.GetUserId();
 297        var isAdministrator = claimsPrincipal.IsInRole(UserRoles.Administrator);
 98
 99        // If they're going to update the record of another user, they must be an administrator
 2100        if (!user.Id.Equals(authenticatedUserId) && !isAdministrator)
 101        {
 0102            return false;
 103        }
 104
 105        // TODO the EnableUserPreferenceAccess policy does not seem to be used elsewhere
 2106        if (!restrictUserPreferences || isAdministrator)
 107        {
 2108            return true;
 109        }
 110
 0111        return user.EnableUserPreferenceAccess;
 112    }
 113
 114    /// <summary>
 115    /// Get the session based on http request.
 116    /// </summary>
 117    /// <param name="sessionManager">The session manager.</param>
 118    /// <param name="userManager">The user manager.</param>
 119    /// <param name="httpContext">The http context.</param>
 120    /// <param name="userId">The optional userid.</param>
 121    /// <returns>The session.</returns>
 122    /// <exception cref="ResourceNotFoundException">Session not found.</exception>
 123    public static async Task<SessionInfo> GetSession(ISessionManager sessionManager, IUserManager userManager, HttpConte
 124    {
 125        userId ??= httpContext.User.GetUserId();
 126        User? user = null;
 127        if (!userId.IsNullOrEmpty())
 128        {
 129            user = userManager.GetUserById(userId.Value);
 130        }
 131
 132        var session = await sessionManager.LogSessionActivity(
 133            httpContext.User.GetClient(),
 134            httpContext.User.GetVersion(),
 135            httpContext.User.GetDeviceId(),
 136            httpContext.User.GetDevice(),
 137            httpContext.GetNormalizedRemoteIP().ToString(),
 138            user).ConfigureAwait(false);
 139
 140        if (session is null)
 141        {
 142            throw new ResourceNotFoundException("Session not found.");
 143        }
 144
 145        return session;
 146    }
 147
 148    internal static async Task<string> GetSessionId(ISessionManager sessionManager, IUserManager userManager, HttpContex
 149    {
 150        var session = await GetSession(sessionManager, userManager, httpContext).ConfigureAwait(false);
 151
 152        return session.Id;
 153    }
 154
 155    internal static QueryResult<BaseItemDto> CreateQueryResult(
 156        QueryResult<(BaseItem Item, ItemCounts ItemCounts)> result,
 157        DtoOptions dtoOptions,
 158        IDtoService dtoService,
 159        bool includeItemTypes,
 160        User? user)
 161    {
 0162        var dtos = result.Items.Select(i =>
 0163        {
 0164            var (baseItem, counts) = i;
 0165            var dto = dtoService.GetItemByNameDto(baseItem, dtoOptions, null, user);
 0166
 0167            if (includeItemTypes)
 0168            {
 0169                dto.ChildCount = counts.ItemCount;
 0170                dto.ProgramCount = counts.ProgramCount;
 0171                dto.SeriesCount = counts.SeriesCount;
 0172                dto.EpisodeCount = counts.EpisodeCount;
 0173                dto.MovieCount = counts.MovieCount;
 0174                dto.TrailerCount = counts.TrailerCount;
 0175                dto.AlbumCount = counts.AlbumCount;
 0176                dto.SongCount = counts.SongCount;
 0177                dto.ArtistCount = counts.ArtistCount;
 0178            }
 0179
 0180            return dto;
 0181        });
 182
 0183        return new QueryResult<BaseItemDto>(
 0184            result.StartIndex,
 0185            result.TotalRecordCount,
 0186            dtos.ToArray());
 187    }
 188}