| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Globalization;
 
- using System.Linq;
 
- using System.Threading;
 
- using Microsoft.Extensions.Logging;
 
- using MediaBrowser.Controller.Entities;
 
- using MediaBrowser.Controller.Library;
 
- using MediaBrowser.Controller.Session;
 
- using MediaBrowser.Controller.SyncPlay;
 
- using MediaBrowser.Model.Configuration;
 
- using MediaBrowser.Model.SyncPlay;
 
- namespace Emby.Server.Implementations.SyncPlay
 
- {
 
-     /// <summary>
 
-     /// Class SyncPlayManager.
 
-     /// </summary>
 
-     public class SyncPlayManager : ISyncPlayManager, IDisposable
 
-     {
 
-         /// <summary>
 
-         /// The logger.
 
-         /// </summary>
 
-         private readonly ILogger _logger;
 
-         /// <summary>
 
-         /// The user manager.
 
-         /// </summary>
 
-         private readonly IUserManager _userManager;
 
-         /// <summary>
 
-         /// The session manager.
 
-         /// </summary>
 
-         private readonly ISessionManager _sessionManager;
 
-         /// <summary>
 
-         /// The library manager.
 
-         /// </summary>
 
-         private readonly ILibraryManager _libraryManager;
 
-         /// <summary>
 
-         /// The map between sessions and groups.
 
-         /// </summary>
 
-         private readonly Dictionary<string, ISyncPlayController> _sessionToGroupMap =
 
-             new Dictionary<string, ISyncPlayController>(StringComparer.OrdinalIgnoreCase);
 
-         /// <summary>
 
-         /// The groups.
 
-         /// </summary>
 
-         private readonly Dictionary<Guid, ISyncPlayController> _groups =
 
-             new Dictionary<Guid, ISyncPlayController>();
 
-         /// <summary>
 
-         /// Lock used for accesing any group.
 
-         /// </summary>
 
-         private readonly object _groupsLock = new object();
 
-         private bool _disposed = false;
 
-         /// <summary>
 
-         /// Initializes a new instance of the <see cref="SyncPlayManager" /> class.
 
-         /// </summary>
 
-         /// <param name="logger">The logger.</param>
 
-         /// <param name="userManager">The user manager.</param>
 
-         /// <param name="sessionManager">The session manager.</param>
 
-         /// <param name="libraryManager">The library manager.</param>
 
-         public SyncPlayManager(
 
-             ILogger<SyncPlayManager> logger,
 
-             IUserManager userManager,
 
-             ISessionManager sessionManager,
 
-             ILibraryManager libraryManager)
 
-         {
 
-             _logger = logger;
 
-             _userManager = userManager;
 
-             _sessionManager = sessionManager;
 
-             _libraryManager = libraryManager;
 
-             _sessionManager.SessionEnded += OnSessionManagerSessionEnded;
 
-             _sessionManager.PlaybackStopped += OnSessionManagerPlaybackStopped;
 
-         }
 
-         /// <summary>
 
-         /// Gets all groups.
 
-         /// </summary>
 
-         /// <value>All groups.</value>
 
-         public IEnumerable<ISyncPlayController> Groups => _groups.Values;
 
-         /// <inheritdoc />
 
-         public void Dispose()
 
-         {
 
-             Dispose(true);
 
-             GC.SuppressFinalize(this);
 
-         }
 
-         /// <summary>
 
-         /// Releases unmanaged and optionally managed resources.
 
-         /// </summary>
 
-         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
 
-         protected virtual void Dispose(bool disposing)
 
-         {
 
-             if (_disposed)
 
-             {
 
-                 return;
 
-             }
 
-             _sessionManager.SessionEnded -= OnSessionManagerSessionEnded;
 
-             _sessionManager.PlaybackStopped -= OnSessionManagerPlaybackStopped;
 
-             _disposed = true;
 
-         }
 
-         private void CheckDisposed()
 
-         {
 
-             if (_disposed)
 
-             {
 
-                 throw new ObjectDisposedException(GetType().Name);
 
-             }
 
-         }
 
-         private void OnSessionManagerSessionEnded(object sender, SessionEventArgs e)
 
-         {
 
-             var session = e.SessionInfo;
 
-             if (!IsSessionInGroup(session))
 
-             {
 
-                 return;
 
-             }
 
-             LeaveGroup(session, CancellationToken.None);
 
-         }
 
-         private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
 
-         {
 
-             var session = e.Session;
 
-             if (!IsSessionInGroup(session))
 
-             {
 
-                 return;
 
-             }
 
-             LeaveGroup(session, CancellationToken.None);
 
-         }
 
-         private bool IsSessionInGroup(SessionInfo session)
 
-         {
 
-             return _sessionToGroupMap.ContainsKey(session.Id);
 
-         }
 
-         private bool HasAccessToItem(User user, Guid itemId)
 
-         {
 
-             var item = _libraryManager.GetItemById(itemId);
 
-             // Check ParentalRating access
 
-             var hasParentalRatingAccess = true;
 
-             if (user.Policy.MaxParentalRating.HasValue)
 
-             {
 
-                 hasParentalRatingAccess = item.InheritedParentalRatingValue <= user.Policy.MaxParentalRating;
 
-             }
 
-             if (!user.Policy.EnableAllFolders && hasParentalRatingAccess)
 
-             {
 
-                 var collections = _libraryManager.GetCollectionFolders(item).Select(
 
-                     folder => folder.Id.ToString("N", CultureInfo.InvariantCulture)
 
-                 );
 
-                 var intersect = collections.Intersect(user.Policy.EnabledFolders);
 
-                 return intersect.Any();
 
-             }
 
-             else
 
-             {
 
-                 return hasParentalRatingAccess;
 
-             }
 
-         }
 
-         private Guid? GetSessionGroup(SessionInfo session)
 
-         {
 
-             ISyncPlayController group;
 
-             _sessionToGroupMap.TryGetValue(session.Id, out group);
 
-             if (group != null)
 
-             {
 
-                 return group.GetGroupId();
 
-             }
 
-             else
 
-             {
 
-                 return null;
 
-             }
 
-         }
 
-         /// <inheritdoc />
 
-         public void NewGroup(SessionInfo session, CancellationToken cancellationToken)
 
-         {
 
-             var user = _userManager.GetUserById(session.UserId);
 
-             if (user.Policy.SyncPlayAccess != SyncPlayAccess.CreateAndJoinGroups)
 
-             {
 
-                 _logger.LogWarning("NewGroup: {0} does not have permission to create groups.", session.Id);
 
-                 var error = new GroupUpdate<string>()
 
-                 {
 
-                     Type = GroupUpdateType.CreateGroupDenied
 
-                 };
 
-                 _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                 return;
 
-             }
 
-             lock (_groupsLock)
 
-             {
 
-                 if (IsSessionInGroup(session))
 
-                 {
 
-                     LeaveGroup(session, cancellationToken);
 
-                 }
 
-                 var group = new SyncPlayController(_sessionManager, this);
 
-                 _groups[group.GetGroupId()] = group;
 
-                 group.InitGroup(session, cancellationToken);
 
-             }
 
-         }
 
-         /// <inheritdoc />
 
-         public void JoinGroup(SessionInfo session, Guid groupId, JoinGroupRequest request, CancellationToken cancellationToken)
 
-         {
 
-             var user = _userManager.GetUserById(session.UserId);
 
-             if (user.Policy.SyncPlayAccess == SyncPlayAccess.None)
 
-             {
 
-                 _logger.LogWarning("JoinGroup: {0} does not have access to SyncPlay.", session.Id);
 
-                 var error = new GroupUpdate<string>()
 
-                 {
 
-                     Type = GroupUpdateType.JoinGroupDenied
 
-                 };
 
-                 _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                 return;
 
-             }
 
-             lock (_groupsLock)
 
-             {
 
-                 ISyncPlayController group;
 
-                 _groups.TryGetValue(groupId, out group);
 
-                 if (group == null)
 
-                 {
 
-                     _logger.LogWarning("JoinGroup: {0} tried to join group {0} that does not exist.", session.Id, groupId);
 
-                     var error = new GroupUpdate<string>()
 
-                     {
 
-                         Type = GroupUpdateType.GroupDoesNotExist
 
-                     };
 
-                     _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                     return;
 
-                 }
 
-                 if (!HasAccessToItem(user, group.GetPlayingItemId()))
 
-                 {
 
-                     _logger.LogWarning("JoinGroup: {0} does not have access to {1}.", session.Id, group.GetPlayingItemId());
 
-                     var error = new GroupUpdate<string>()
 
-                     {
 
-                         GroupId = group.GetGroupId().ToString(),
 
-                         Type = GroupUpdateType.LibraryAccessDenied
 
-                     };
 
-                     _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                     return;
 
-                 }
 
-                 if (IsSessionInGroup(session))
 
-                 {
 
-                     if (GetSessionGroup(session).Equals(groupId))
 
-                     {
 
-                         return;
 
-                     }
 
-                     LeaveGroup(session, cancellationToken);
 
-                 }
 
-                 group.SessionJoin(session, request, cancellationToken);
 
-             }
 
-         }
 
-         /// <inheritdoc />
 
-         public void LeaveGroup(SessionInfo session, CancellationToken cancellationToken)
 
-         {
 
-             // TODO: determine what happens to users that are in a group and get their permissions revoked
 
-             lock (_groupsLock)
 
-             {
 
-                 ISyncPlayController group;
 
-                 _sessionToGroupMap.TryGetValue(session.Id, out group);
 
-                 if (group == null)
 
-                 {
 
-                     _logger.LogWarning("LeaveGroup: {0} does not belong to any group.", session.Id);
 
-                     var error = new GroupUpdate<string>()
 
-                     {
 
-                         Type = GroupUpdateType.NotInGroup
 
-                     };
 
-                     _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                     return;
 
-                 }
 
-                 group.SessionLeave(session, cancellationToken);
 
-                 if (group.IsGroupEmpty())
 
-                 {
 
-                     _logger.LogInformation("LeaveGroup: removing empty group {0}.", group.GetGroupId());
 
-                     _groups.Remove(group.GetGroupId(), out _);
 
-                 }
 
-             }
 
-         }
 
-         /// <inheritdoc />
 
-         public List<GroupInfoView> ListGroups(SessionInfo session, Guid filterItemId)
 
-         {
 
-             var user = _userManager.GetUserById(session.UserId);
 
-             if (user.Policy.SyncPlayAccess == SyncPlayAccess.None)
 
-             {
 
-                 return new List<GroupInfoView>();
 
-             }
 
-             // Filter by item if requested
 
-             if (!filterItemId.Equals(Guid.Empty))
 
-             {
 
-                 return _groups.Values.Where(
 
-                     group => group.GetPlayingItemId().Equals(filterItemId) && HasAccessToItem(user, group.GetPlayingItemId())
 
-                 ).Select(
 
-                     group => group.GetInfo()
 
-                 ).ToList();
 
-             }
 
-             // Otherwise show all available groups
 
-             else
 
-             {
 
-                 return _groups.Values.Where(
 
-                     group => HasAccessToItem(user, group.GetPlayingItemId())
 
-                 ).Select(
 
-                     group => group.GetInfo()
 
-                 ).ToList();
 
-             }
 
-         }
 
-         /// <inheritdoc />
 
-         public void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken)
 
-         {
 
-             var user = _userManager.GetUserById(session.UserId);
 
-             if (user.Policy.SyncPlayAccess == SyncPlayAccess.None)
 
-             {
 
-                 _logger.LogWarning("HandleRequest: {0} does not have access to SyncPlay.", session.Id);
 
-                 var error = new GroupUpdate<string>()
 
-                 {
 
-                     Type = GroupUpdateType.JoinGroupDenied
 
-                 };
 
-                 _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                 return;
 
-             }
 
-             lock (_groupsLock)
 
-             {
 
-                 ISyncPlayController group;
 
-                 _sessionToGroupMap.TryGetValue(session.Id, out group);
 
-                 if (group == null)
 
-                 {
 
-                     _logger.LogWarning("HandleRequest: {0} does not belong to any group.", session.Id);
 
-                     var error = new GroupUpdate<string>()
 
-                     {
 
-                         Type = GroupUpdateType.NotInGroup
 
-                     };
 
-                     _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), error, CancellationToken.None);
 
-                     return;
 
-                 }
 
-                 group.HandleRequest(session, request, cancellationToken);
 
-             }
 
-         }
 
-         /// <inheritdoc />
 
-         public void AddSessionToGroup(SessionInfo session, ISyncPlayController group)
 
-         {
 
-             if (IsSessionInGroup(session))
 
-             {
 
-                 throw new InvalidOperationException("Session in other group already!");
 
-             }
 
-             _sessionToGroupMap[session.Id] = group;
 
-         }
 
-         /// <inheritdoc />
 
-         public void RemoveSessionFromGroup(SessionInfo session, ISyncPlayController group)
 
-         {
 
-             if (!IsSessionInGroup(session))
 
-             {
 
-                 throw new InvalidOperationException("Session not in any group!");
 
-             }
 
-             ISyncPlayController tempGroup;
 
-             _sessionToGroupMap.Remove(session.Id, out tempGroup);
 
-             if (!tempGroup.GetGroupId().Equals(group.GetGroupId()))
 
-             {
 
-                 throw new InvalidOperationException("Session was in wrong group!");
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |