mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	Merge pull request #3324 from Ullmie02/api-sessionservice
Move SessionService to Jellyfin.Api
This commit is contained in:
		
						commit
						576ffeb2a9
					
				
							
								
								
									
										474
									
								
								Jellyfin.Api/Controllers/SessionController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								Jellyfin.Api/Controllers/SessionController.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,474 @@
 | 
				
			|||||||
 | 
					#pragma warning disable CA1801
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using Jellyfin.Api.Helpers;
 | 
				
			||||||
 | 
					using Jellyfin.Data.Enums;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Devices;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Library;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Net;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Session;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Dto;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Session;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Authorization;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Jellyfin.Api.Controllers
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The session controller.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public class SessionController : BaseJellyfinApiController
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly ISessionManager _sessionManager;
 | 
				
			||||||
 | 
					        private readonly IUserManager _userManager;
 | 
				
			||||||
 | 
					        private readonly IAuthorizationContext _authContext;
 | 
				
			||||||
 | 
					        private readonly IDeviceManager _deviceManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Initializes a new instance of the <see cref="SessionController"/> class.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="sessionManager">Instance of <see cref="ISessionManager"/> interface.</param>
 | 
				
			||||||
 | 
					        /// <param name="userManager">Instance of <see cref="IUserManager"/> interface.</param>
 | 
				
			||||||
 | 
					        /// <param name="authContext">Instance of <see cref="IAuthorizationContext"/> interface.</param>
 | 
				
			||||||
 | 
					        /// <param name="deviceManager">Instance of <see cref="IDeviceManager"/> interface.</param>
 | 
				
			||||||
 | 
					        public SessionController(
 | 
				
			||||||
 | 
					            ISessionManager sessionManager,
 | 
				
			||||||
 | 
					            IUserManager userManager,
 | 
				
			||||||
 | 
					            IAuthorizationContext authContext,
 | 
				
			||||||
 | 
					            IDeviceManager deviceManager)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _sessionManager = sessionManager;
 | 
				
			||||||
 | 
					            _userManager = userManager;
 | 
				
			||||||
 | 
					            _authContext = authContext;
 | 
				
			||||||
 | 
					            _deviceManager = deviceManager;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Gets a list of sessions.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="controllableByUserId">Filter by sessions that a given user is allowed to remote control.</param>
 | 
				
			||||||
 | 
					        /// <param name="deviceId">Filter by device Id.</param>
 | 
				
			||||||
 | 
					        /// <param name="activeWithinSeconds">Optional. Filter by sessions that were active in the last n seconds.</param>
 | 
				
			||||||
 | 
					        /// <response code="200">List of sessions returned.</response>
 | 
				
			||||||
 | 
					        /// <returns>An <see cref="IEnumerable{SessionInfo}"/> with the available sessions.</returns>
 | 
				
			||||||
 | 
					        [HttpGet("/Sessions")]
 | 
				
			||||||
 | 
					        [Authorize]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status200OK)]
 | 
				
			||||||
 | 
					        public ActionResult<IEnumerable<SessionInfo>> GetSessions(
 | 
				
			||||||
 | 
					            [FromQuery] Guid controllableByUserId,
 | 
				
			||||||
 | 
					            [FromQuery] string deviceId,
 | 
				
			||||||
 | 
					            [FromQuery] int? activeWithinSeconds)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var result = _sessionManager.Sessions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!string.IsNullOrEmpty(deviceId))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                result = result.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!controllableByUserId.Equals(Guid.Empty))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                result = result.Where(i => i.SupportsRemoteControl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var user = _userManager.GetUserById(controllableByUserId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    result = result.Where(i => i.UserId.Equals(Guid.Empty) || i.ContainsUser(controllableByUserId));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!user.HasPermission(PermissionKind.EnableSharedDeviceControl))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    result = result.Where(i => !i.UserId.Equals(Guid.Empty));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (activeWithinSeconds.HasValue && activeWithinSeconds.Value > 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var minActiveDate = DateTime.UtcNow.AddSeconds(0 - activeWithinSeconds.Value);
 | 
				
			||||||
 | 
					                    result = result.Where(i => i.LastActivityDate >= minActiveDate);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                result = result.Where(i =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (!string.IsNullOrWhiteSpace(i.DeviceId))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (!_deviceManager.CanAccessDevice(user, i.DeviceId))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            return false;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return Ok(result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Instructs a session to browse to an item or view.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult DisplayContent(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromQuery] string itemType,
 | 
				
			||||||
 | 
					            [FromQuery] string itemId,
 | 
				
			||||||
 | 
					            [FromQuery] string itemName)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var command = new BrowseRequest
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ItemId = itemId,
 | 
				
			||||||
 | 
					                ItemName = itemName,
 | 
				
			||||||
 | 
					                ItemType = itemType
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.SendBrowseCommand(
 | 
				
			||||||
 | 
					                RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
 | 
				
			||||||
 | 
					                id,
 | 
				
			||||||
 | 
					                command,
 | 
				
			||||||
 | 
					                CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Instructs a session to play an item.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult Play(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromQuery] Guid[] itemIds,
 | 
				
			||||||
 | 
					            [FromQuery] long? startPositionTicks,
 | 
				
			||||||
 | 
					            [FromQuery] PlayCommand playCommand,
 | 
				
			||||||
 | 
					            [FromBody, Required] PlayRequest playRequest)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (playRequest == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentException("Request Body may not be null");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            playRequest.ItemIds = itemIds;
 | 
				
			||||||
 | 
					            playRequest.StartPositionTicks = startPositionTicks;
 | 
				
			||||||
 | 
					            playRequest.PlayCommand = playCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.SendPlayCommand(
 | 
				
			||||||
 | 
					                RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
 | 
				
			||||||
 | 
					                id,
 | 
				
			||||||
 | 
					                playRequest,
 | 
				
			||||||
 | 
					                CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Issues a playstate command to a client.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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}")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult SendPlaystateCommand(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromBody] PlaystateRequest playstateRequest)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _sessionManager.SendPlaystateCommand(
 | 
				
			||||||
 | 
					                RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
 | 
				
			||||||
 | 
					                id,
 | 
				
			||||||
 | 
					                playstateRequest,
 | 
				
			||||||
 | 
					                CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Issues a system command to a client.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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}")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult SendSystemCommand(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromRoute] string command)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var name = command;
 | 
				
			||||||
 | 
					            if (Enum.TryParse(name, true, out GeneralCommandType commandType))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                name = commandType.ToString();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
 | 
				
			||||||
 | 
					            var generalCommand = new GeneralCommand
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Name = name,
 | 
				
			||||||
 | 
					                ControllingUserId = currentSession.UserId
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.SendGeneralCommand(currentSession.Id, id, generalCommand, CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Issues a general command to a client.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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}")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult SendGeneralCommand(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromRoute] string command)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var generalCommand = new GeneralCommand
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Name = command,
 | 
				
			||||||
 | 
					                ControllingUserId = currentSession.UserId
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.SendGeneralCommand(currentSession.Id, id, generalCommand, CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Issues a full general command to a client.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult SendFullGeneralCommand(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromBody, Required] GeneralCommand command)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (command == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentException("Request body may not be null");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            command.ControllingUserId = currentSession.UserId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.SendGeneralCommand(
 | 
				
			||||||
 | 
					                currentSession.Id,
 | 
				
			||||||
 | 
					                id,
 | 
				
			||||||
 | 
					                command,
 | 
				
			||||||
 | 
					                CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Issues a command to a client to display a message to the user.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult SendMessageCommand(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromQuery] string text,
 | 
				
			||||||
 | 
					            [FromQuery] string header,
 | 
				
			||||||
 | 
					            [FromQuery] long? timeoutMs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var command = new MessageCommand
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Header = string.IsNullOrEmpty(header) ? "Message from Server" : header,
 | 
				
			||||||
 | 
					                TimeoutMs = timeoutMs,
 | 
				
			||||||
 | 
					                Text = text
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.SendMessageCommand(RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id, id, command, CancellationToken.None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Adds an additional user to a session.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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}")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult AddUserToSession(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromRoute] Guid userId)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _sessionManager.AddAdditionalUser(id, userId);
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Removes an additional user from a session.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">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}")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult RemoveUserFromSession(
 | 
				
			||||||
 | 
					            [FromRoute] string id,
 | 
				
			||||||
 | 
					            [FromRoute] Guid userId)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _sessionManager.RemoveAdditionalUser(id, userId);
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Updates capabilities for a device.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">The session id.</param>
 | 
				
			||||||
 | 
					        /// <param name="playableMediaTypes">A list of playable media types, comma delimited. Audio, Video, Book, Photo.</param>
 | 
				
			||||||
 | 
					        /// <param name="supportedCommands">A list of supported remote control commands, comma delimited.</param>
 | 
				
			||||||
 | 
					        /// <param name="supportsMediaControl">Determines whether media can be played remotely..</param>
 | 
				
			||||||
 | 
					        /// <param name="supportsSync">Determines whether sync is supported.</param>
 | 
				
			||||||
 | 
					        /// <param name="supportsPersistentIdentifier">Determines whether the device supports a unique identifier.</param>
 | 
				
			||||||
 | 
					        /// <response code="204">Capabilities posted.</response>
 | 
				
			||||||
 | 
					        /// <returns>A <see cref="NoContentResult"/>.</returns>
 | 
				
			||||||
 | 
					        [HttpPost("/Sessions/Capabilities")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult PostCapabilities(
 | 
				
			||||||
 | 
					            [FromQuery] string id,
 | 
				
			||||||
 | 
					            [FromQuery] string playableMediaTypes,
 | 
				
			||||||
 | 
					            [FromQuery] string supportedCommands,
 | 
				
			||||||
 | 
					            [FromQuery] bool supportsMediaControl,
 | 
				
			||||||
 | 
					            [FromQuery] bool supportsSync,
 | 
				
			||||||
 | 
					            [FromQuery] bool supportsPersistentIdentifier = true)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrWhiteSpace(id))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                id = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.ReportCapabilities(id, new ClientCapabilities
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                PlayableMediaTypes = RequestHelpers.Split(playableMediaTypes, ',', true),
 | 
				
			||||||
 | 
					                SupportedCommands = RequestHelpers.Split(supportedCommands, ',', true),
 | 
				
			||||||
 | 
					                SupportsMediaControl = supportsMediaControl,
 | 
				
			||||||
 | 
					                SupportsSync = supportsSync,
 | 
				
			||||||
 | 
					                SupportsPersistentIdentifier = supportsPersistentIdentifier
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Updates capabilities for a device.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="id">The session id.</param>
 | 
				
			||||||
 | 
					        /// <param name="capabilities">The <see cref="ClientCapabilities"/>.</param>
 | 
				
			||||||
 | 
					        /// <response code="204">Capabilities updated.</response>
 | 
				
			||||||
 | 
					        /// <returns>A <see cref="NoContentResult"/>.</returns>
 | 
				
			||||||
 | 
					        [HttpPost("/Sessions/Capabilities/Full")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult PostFullCapabilities(
 | 
				
			||||||
 | 
					            [FromQuery] string id,
 | 
				
			||||||
 | 
					            [FromBody, Required] ClientCapabilities capabilities)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrWhiteSpace(id))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                id = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.ReportCapabilities(id, capabilities);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Reports that a session is viewing an item.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="sessionId">The session id.</param>
 | 
				
			||||||
 | 
					        /// <param name="itemId">The item id.</param>
 | 
				
			||||||
 | 
					        /// <response code="204">Session reported to server.</response>
 | 
				
			||||||
 | 
					        /// <returns>A <see cref="NoContentResult"/>.</returns>
 | 
				
			||||||
 | 
					        [HttpPost("/Sessions/Viewing")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult ReportViewing(
 | 
				
			||||||
 | 
					            [FromQuery] string sessionId,
 | 
				
			||||||
 | 
					            [FromQuery] string itemId)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string session = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.ReportNowViewingItem(session, itemId);
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Reports that a session has ended.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <response code="204">Session end reported to server.</response>
 | 
				
			||||||
 | 
					        /// <returns>A <see cref="NoContentResult"/>.</returns>
 | 
				
			||||||
 | 
					        [HttpPost("/Sessions/Logout")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
 | 
					        public ActionResult ReportSessionEnded()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            AuthorizationInfo auth = _authContext.GetAuthorizationInfo(Request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _sessionManager.Logout(auth.Token);
 | 
				
			||||||
 | 
					            return NoContent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Get all auth providers.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <response code="200">Auth providers retrieved.</response>
 | 
				
			||||||
 | 
					        /// <returns>An <see cref="IEnumerable{NameIdPair}"/> with the auth providers.</returns>
 | 
				
			||||||
 | 
					        [HttpGet("/Auth/Providers")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status200OK)]
 | 
				
			||||||
 | 
					        public ActionResult<IEnumerable<NameIdPair>> GetAuthProviders()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _userManager.GetAuthenticationProviders();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Get all password reset providers.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <response code="200">Password reset providers retrieved.</response>
 | 
				
			||||||
 | 
					        /// <returns>An <see cref="IEnumerable{NameIdPair}"/> with the password reset providers.</returns>
 | 
				
			||||||
 | 
					        [HttpGet("/Auto/PasswordResetProviders")]
 | 
				
			||||||
 | 
					        [ProducesResponseType(StatusCodes.Status200OK)]
 | 
				
			||||||
 | 
					        public ActionResult<IEnumerable<NameIdPair>> GetPasswordResetProviders()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _userManager.GetPasswordResetProviders();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using Jellyfin.Data.Enums;
 | 
					using Jellyfin.Data.Enums;
 | 
				
			||||||
using MediaBrowser.Controller.Net;
 | 
					using MediaBrowser.Controller.Net;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Session;
 | 
				
			||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Jellyfin.Api.Helpers
 | 
					namespace Jellyfin.Api.Helpers
 | 
				
			||||||
@ -52,5 +53,25 @@ namespace Jellyfin.Api.Helpers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static SessionInfo GetSession(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var authorization = authContext.GetAuthorizationInfo(request);
 | 
				
			||||||
 | 
					            var user = authorization.User;
 | 
				
			||||||
 | 
					            var session = sessionManager.LogSessionActivity(
 | 
				
			||||||
 | 
					                authorization.Client,
 | 
				
			||||||
 | 
					                authorization.Version,
 | 
				
			||||||
 | 
					                authorization.DeviceId,
 | 
				
			||||||
 | 
					                authorization.Device,
 | 
				
			||||||
 | 
					                request.HttpContext.Connection.RemoteIpAddress.ToString(),
 | 
				
			||||||
 | 
					                user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (session == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentException("Session not found.");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return session;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,499 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Threading;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					 | 
				
			||||||
using Jellyfin.Data.Enums;
 | 
					 | 
				
			||||||
using MediaBrowser.Controller.Configuration;
 | 
					 | 
				
			||||||
using MediaBrowser.Controller.Devices;
 | 
					 | 
				
			||||||
using MediaBrowser.Controller.Library;
 | 
					 | 
				
			||||||
using MediaBrowser.Controller.Net;
 | 
					 | 
				
			||||||
using MediaBrowser.Controller.Session;
 | 
					 | 
				
			||||||
using MediaBrowser.Model.Dto;
 | 
					 | 
				
			||||||
using MediaBrowser.Model.Services;
 | 
					 | 
				
			||||||
using MediaBrowser.Model.Session;
 | 
					 | 
				
			||||||
using Microsoft.Extensions.Logging;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace MediaBrowser.Api.Sessions
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// <summary>
 | 
					 | 
				
			||||||
    /// Class GetSessions.
 | 
					 | 
				
			||||||
    /// </summary>
 | 
					 | 
				
			||||||
    [Route("/Sessions", "GET", Summary = "Gets a list of sessions")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class GetSessions : IReturn<SessionInfo[]>
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [ApiMember(Name = "ControllableByUserId", Description = "Filter by sessions that a given user is allowed to remote control.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
 | 
					 | 
				
			||||||
        public Guid ControllableByUserId { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "DeviceId", Description = "Filter by device Id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
 | 
					 | 
				
			||||||
        public string DeviceId { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public int? ActiveWithinSeconds { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// <summary>
 | 
					 | 
				
			||||||
    /// Class DisplayContent.
 | 
					 | 
				
			||||||
    /// </summary>
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Viewing", "POST", Summary = "Instructs a session to browse to an item or view")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class DisplayContent : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Artist, Genre, Studio, Person, or any kind of BaseItem
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The type of the item.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "ItemType", Description = "The type of item to browse to.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string ItemType { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Artist name, genre name, item Id, etc
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The item identifier.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "ItemId", Description = "The Id of the item.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string ItemId { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the name of the item.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The name of the item.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "ItemName", Description = "The name of the item.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string ItemName { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Playing", "POST", Summary = "Instructs a session to play an item")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class Play : PlayRequest
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Playing/{Command}", "POST", Summary = "Issues a playstate command to a client")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class SendPlaystateCommand : PlaystateRequest, IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/System/{Command}", "POST", Summary = "Issues a system command to a client")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class SendSystemCommand : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the command.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The play command.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Command", Description = "The command to send.", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Command { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Command/{Command}", "POST", Summary = "Issues a system command to a client")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class SendGeneralCommand : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the command.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The play command.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Command", Description = "The command to send.", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Command { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Command", "POST", Summary = "Issues a system command to a client")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class SendFullGeneralCommand : GeneralCommand, IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Message", "POST", Summary = "Issues a command to a client to display a message to the user")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class SendMessageCommand : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Text", Description = "The message text.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Text { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Header", Description = "The message header.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Header { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "TimeoutMs", Description = "The message timeout. If omitted the user will have to confirm viewing the message.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public long? TimeoutMs { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Users/{UserId}", "POST", Summary = "Adds an additional user to a session")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class AddUserToSession : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "UserId", Description = "UserId Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string UserId { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/{Id}/Users/{UserId}", "DELETE", Summary = "Removes an additional user from a session")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class RemoveUserFromSession : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string UserId { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/Capabilities", "POST", Summary = "Updates capabilities for a device")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class PostCapabilities : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "PlayableMediaTypes", Description = "A list of playable media types, comma delimited. Audio, Video, Book, Photo.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string PlayableMediaTypes { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "SupportedCommands", Description = "A list of supported remote control commands, comma delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string SupportedCommands { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "SupportsMediaControl", Description = "Determines whether media can be played remotely.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public bool SupportsMediaControl { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "SupportsSync", Description = "Determines whether sync is supported.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public bool SupportsSync { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "SupportsPersistentIdentifier", Description = "Determines whether the device supports a unique identifier.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public bool SupportsPersistentIdentifier { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public PostCapabilities()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SupportsPersistentIdentifier = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/Capabilities/Full", "POST", Summary = "Updates capabilities for a device")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class PostFullCapabilities : ClientCapabilities, IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets or sets the id.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <value>The id.</value>
 | 
					 | 
				
			||||||
        [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string Id { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/Viewing", "POST", Summary = "Reports that a session is viewing an item")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class ReportViewing : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [ApiMember(Name = "SessionId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string SessionId { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ApiMember(Name = "ItemId", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
 | 
					 | 
				
			||||||
        public string ItemId { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Sessions/Logout", "POST", Summary = "Reports that a session has ended")]
 | 
					 | 
				
			||||||
    [Authenticated]
 | 
					 | 
				
			||||||
    public class ReportSessionEnded : IReturnVoid
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Auth/Providers", "GET")]
 | 
					 | 
				
			||||||
    [Authenticated(Roles = "Admin")]
 | 
					 | 
				
			||||||
    public class GetAuthProviders : IReturn<NameIdPair[]>
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [Route("/Auth/PasswordResetProviders", "GET")]
 | 
					 | 
				
			||||||
    [Authenticated(Roles = "Admin")]
 | 
					 | 
				
			||||||
    public class GetPasswordResetProviders : IReturn<NameIdPair[]>
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// <summary>
 | 
					 | 
				
			||||||
    /// Class SessionsService.
 | 
					 | 
				
			||||||
    /// </summary>
 | 
					 | 
				
			||||||
    public class SessionService : BaseApiService
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// The session manager.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        private readonly ISessionManager _sessionManager;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private readonly IUserManager _userManager;
 | 
					 | 
				
			||||||
        private readonly IAuthorizationContext _authContext;
 | 
					 | 
				
			||||||
        private readonly IDeviceManager _deviceManager;
 | 
					 | 
				
			||||||
        private readonly ISessionContext _sessionContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public SessionService(
 | 
					 | 
				
			||||||
            ILogger<SessionService> logger,
 | 
					 | 
				
			||||||
            IServerConfigurationManager serverConfigurationManager,
 | 
					 | 
				
			||||||
            IHttpResultFactory httpResultFactory,
 | 
					 | 
				
			||||||
            ISessionManager sessionManager,
 | 
					 | 
				
			||||||
            IUserManager userManager,
 | 
					 | 
				
			||||||
            IAuthorizationContext authContext,
 | 
					 | 
				
			||||||
            IDeviceManager deviceManager,
 | 
					 | 
				
			||||||
            ISessionContext sessionContext)
 | 
					 | 
				
			||||||
            : base(logger, serverConfigurationManager, httpResultFactory)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _sessionManager = sessionManager;
 | 
					 | 
				
			||||||
            _userManager = userManager;
 | 
					 | 
				
			||||||
            _authContext = authContext;
 | 
					 | 
				
			||||||
            _deviceManager = deviceManager;
 | 
					 | 
				
			||||||
            _sessionContext = sessionContext;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public object Get(GetAuthProviders request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return _userManager.GetAuthenticationProviders();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public object Get(GetPasswordResetProviders request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return _userManager.GetPasswordResetProviders();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Post(ReportSessionEnded request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var auth = _authContext.GetAuthorizationInfo(Request);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            _sessionManager.Logout(auth.Token);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets the specified request.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="request">The request.</param>
 | 
					 | 
				
			||||||
        /// <returns>System.Object.</returns>
 | 
					 | 
				
			||||||
        public object Get(GetSessions request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var result = _sessionManager.Sessions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!string.IsNullOrEmpty(request.DeviceId))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                result = result.Where(i => string.Equals(i.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!request.ControllableByUserId.Equals(Guid.Empty))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                result = result.Where(i => i.SupportsRemoteControl);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                var user = _userManager.GetUserById(request.ControllableByUserId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    result = result.Where(i => i.UserId.Equals(Guid.Empty) || i.ContainsUser(request.ControllableByUserId));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!user.HasPermission(PermissionKind.EnableSharedDeviceControl))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    result = result.Where(i => !i.UserId.Equals(Guid.Empty));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (request.ActiveWithinSeconds.HasValue && request.ActiveWithinSeconds.Value > 0)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    var minActiveDate = DateTime.UtcNow.AddSeconds(0 - request.ActiveWithinSeconds.Value);
 | 
					 | 
				
			||||||
                    result = result.Where(i => i.LastActivityDate >= minActiveDate);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                result = result.Where(i =>
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    var deviceId = i.DeviceId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (!string.IsNullOrWhiteSpace(deviceId))
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        if (!_deviceManager.CanAccessDevice(user, deviceId))
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            return false;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return ToOptimizedResult(result.ToArray());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public Task Post(SendPlaystateCommand request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Id, request.Id, request, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Posts the specified request.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="request">The request.</param>
 | 
					 | 
				
			||||||
        public Task Post(DisplayContent request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var command = new BrowseRequest
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                ItemId = request.ItemId,
 | 
					 | 
				
			||||||
                ItemName = request.ItemName,
 | 
					 | 
				
			||||||
                ItemType = request.ItemType
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return _sessionManager.SendBrowseCommand(GetSession(_sessionContext).Id, request.Id, command, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Posts the specified request.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="request">The request.</param>
 | 
					 | 
				
			||||||
        public Task Post(SendSystemCommand request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var name = request.Command;
 | 
					 | 
				
			||||||
            if (Enum.TryParse(name, true, out GeneralCommandType commandType))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                name = commandType.ToString();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var currentSession = GetSession(_sessionContext);
 | 
					 | 
				
			||||||
            var command = new GeneralCommand
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Name = name,
 | 
					 | 
				
			||||||
                ControllingUserId = currentSession.UserId
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Posts the specified request.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="request">The request.</param>
 | 
					 | 
				
			||||||
        public Task Post(SendMessageCommand request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var command = new MessageCommand
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Header = string.IsNullOrEmpty(request.Header) ? "Message from Server" : request.Header,
 | 
					 | 
				
			||||||
                TimeoutMs = request.TimeoutMs,
 | 
					 | 
				
			||||||
                Text = request.Text
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return _sessionManager.SendMessageCommand(GetSession(_sessionContext).Id, request.Id, command, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Posts the specified request.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="request">The request.</param>
 | 
					 | 
				
			||||||
        public Task Post(Play request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return _sessionManager.SendPlayCommand(GetSession(_sessionContext).Id, request.Id, request, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public Task Post(SendGeneralCommand request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var currentSession = GetSession(_sessionContext);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var command = new GeneralCommand
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Name = request.Command,
 | 
					 | 
				
			||||||
                ControllingUserId = currentSession.UserId
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public Task Post(SendFullGeneralCommand request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var currentSession = GetSession(_sessionContext);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            request.ControllingUserId = currentSession.UserId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, request, CancellationToken.None);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Post(AddUserToSession request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _sessionManager.AddAdditionalUser(request.Id, new Guid(request.UserId));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Delete(RemoveUserFromSession request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _sessionManager.RemoveAdditionalUser(request.Id, new Guid(request.UserId));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Post(PostCapabilities request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(request.Id))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                request.Id = GetSession(_sessionContext).Id;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            _sessionManager.ReportCapabilities(request.Id, new ClientCapabilities
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                PlayableMediaTypes = SplitValue(request.PlayableMediaTypes, ','),
 | 
					 | 
				
			||||||
                SupportedCommands = SplitValue(request.SupportedCommands, ','),
 | 
					 | 
				
			||||||
                SupportsMediaControl = request.SupportsMediaControl,
 | 
					 | 
				
			||||||
                SupportsSync = request.SupportsSync,
 | 
					 | 
				
			||||||
                SupportsPersistentIdentifier = request.SupportsPersistentIdentifier
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Post(PostFullCapabilities request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(request.Id))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                request.Id = GetSession(_sessionContext).Id;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            _sessionManager.ReportCapabilities(request.Id, request);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Post(ReportViewing request)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            request.SessionId = GetSession(_sessionContext).Id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            _sessionManager.ReportNowViewingItem(request.SessionId, request.ItemId);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user