|
|
@ -39,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
private readonly ILogger _logger;
|
|
|
|
private readonly ILogger _logger;
|
|
|
|
|
|
|
|
|
|
|
|
private readonly ILibraryManager _libraryManager;
|
|
|
|
private readonly ILibraryManager _libraryManager;
|
|
|
|
|
|
|
|
private readonly IUserManager _userManager;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the configuration manager.
|
|
|
|
/// Gets or sets the configuration manager.
|
|
|
@ -75,13 +76,14 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
/// <param name="logger">The logger.</param>
|
|
|
|
/// <param name="logger">The logger.</param>
|
|
|
|
/// <param name="userRepository">The user repository.</param>
|
|
|
|
/// <param name="userRepository">The user repository.</param>
|
|
|
|
/// <param name="libraryManager">The library manager.</param>
|
|
|
|
/// <param name="libraryManager">The library manager.</param>
|
|
|
|
public SessionManager(IUserDataManager userDataRepository, IServerConfigurationManager configurationManager, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager)
|
|
|
|
public SessionManager(IUserDataManager userDataRepository, IServerConfigurationManager configurationManager, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager, IUserManager userManager)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_userDataRepository = userDataRepository;
|
|
|
|
_userDataRepository = userDataRepository;
|
|
|
|
_configurationManager = configurationManager;
|
|
|
|
_configurationManager = configurationManager;
|
|
|
|
_logger = logger;
|
|
|
|
_logger = logger;
|
|
|
|
_userRepository = userRepository;
|
|
|
|
_userRepository = userRepository;
|
|
|
|
_libraryManager = libraryManager;
|
|
|
|
_libraryManager = libraryManager;
|
|
|
|
|
|
|
|
_userManager = userManager;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
@ -140,7 +142,10 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
|
|
|
|
|
|
|
|
var activityDate = DateTime.UtcNow;
|
|
|
|
var activityDate = DateTime.UtcNow;
|
|
|
|
|
|
|
|
|
|
|
|
var session = GetSessionInfo(clientType, appVersion, deviceId, deviceName, remoteEndPoint, user);
|
|
|
|
var userId = user == null ? (Guid?)null : user.Id;
|
|
|
|
|
|
|
|
var username = user == null ? null : user.Name;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var session = GetSessionInfo(clientType, appVersion, deviceId, deviceName, remoteEndPoint, userId, username);
|
|
|
|
|
|
|
|
|
|
|
|
session.LastActivityDate = activityDate;
|
|
|
|
session.LastActivityDate = activityDate;
|
|
|
|
|
|
|
|
|
|
|
@ -209,9 +214,10 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
/// <param name="deviceId">The device id.</param>
|
|
|
|
/// <param name="deviceId">The device id.</param>
|
|
|
|
/// <param name="deviceName">Name of the device.</param>
|
|
|
|
/// <param name="deviceName">Name of the device.</param>
|
|
|
|
/// <param name="remoteEndPoint">The remote end point.</param>
|
|
|
|
/// <param name="remoteEndPoint">The remote end point.</param>
|
|
|
|
/// <param name="user">The user.</param>
|
|
|
|
/// <param name="userId">The user identifier.</param>
|
|
|
|
|
|
|
|
/// <param name="username">The username.</param>
|
|
|
|
/// <returns>SessionInfo.</returns>
|
|
|
|
/// <returns>SessionInfo.</returns>
|
|
|
|
private SessionInfo GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint, User user)
|
|
|
|
private SessionInfo GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Guid? userId, string username)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var key = clientType + deviceId + appVersion;
|
|
|
|
var key = clientType + deviceId + appVersion;
|
|
|
|
|
|
|
|
|
|
|
@ -224,9 +230,15 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
connection.DeviceName = deviceName;
|
|
|
|
connection.DeviceName = deviceName;
|
|
|
|
connection.User = user;
|
|
|
|
connection.UserId = userId;
|
|
|
|
|
|
|
|
connection.UserName = username;
|
|
|
|
connection.RemoteEndPoint = remoteEndPoint;
|
|
|
|
connection.RemoteEndPoint = remoteEndPoint;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!userId.HasValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
connection.AdditionalUsersPresent.Clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (connection.SessionController == null)
|
|
|
|
if (connection.SessionController == null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
connection.SessionController = _sessionFactories
|
|
|
|
connection.SessionController = _sessionFactories
|
|
|
@ -237,6 +249,31 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
return connection;
|
|
|
|
return connection;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<User> GetUsers(SessionInfo session)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var users = new List<User>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (session.UserId.HasValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var user = _userManager.GetUserById(session.UserId.Value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (user == null)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
throw new InvalidOperationException("User not found");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
users.Add(user);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var additionalUsers = session.AdditionalUsersPresent
|
|
|
|
|
|
|
|
.Select(i => _userManager.GetUserById(new Guid(i.UserId)))
|
|
|
|
|
|
|
|
.Where(i => i != null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
users.AddRange(additionalUsers);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return users;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Used to report that playback has started for an item
|
|
|
|
/// Used to report that playback has started for an item
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
@ -265,31 +302,45 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
|
|
|
|
|
|
|
|
var key = item.GetUserDataKey();
|
|
|
|
var key = item.GetUserDataKey();
|
|
|
|
|
|
|
|
|
|
|
|
var user = session.User;
|
|
|
|
var users = GetUsers(session);
|
|
|
|
|
|
|
|
|
|
|
|
var data = _userDataRepository.GetUserData(user.Id, key);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data.PlayCount++;
|
|
|
|
foreach (var user in users)
|
|
|
|
data.LastPlayedDate = DateTime.UtcNow;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(item is Video))
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data.Played = true;
|
|
|
|
await OnPlaybackStart(user.Id, key, item).ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Nothing to save here
|
|
|
|
// Nothing to save here
|
|
|
|
// Fire events to inform plugins
|
|
|
|
// Fire events to inform plugins
|
|
|
|
EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
|
|
|
|
EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Item = item,
|
|
|
|
Item = item,
|
|
|
|
User = user,
|
|
|
|
Users = users
|
|
|
|
UserData = data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}, _logger);
|
|
|
|
}, _logger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Called when [playback start].
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <param name="userId">The user identifier.</param>
|
|
|
|
|
|
|
|
/// <param name="userDataKey">The user data key.</param>
|
|
|
|
|
|
|
|
/// <param name="item">The item.</param>
|
|
|
|
|
|
|
|
/// <returns>Task.</returns>
|
|
|
|
|
|
|
|
private async Task OnPlaybackStart(Guid userId, string userDataKey, IHasUserData item)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data.PlayCount++;
|
|
|
|
|
|
|
|
data.LastPlayedDate = DateTime.UtcNow;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(item is Video))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
data.Played = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Used to report playback progress for an item
|
|
|
|
/// Used to report playback progress for an item
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
@ -315,27 +366,34 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
|
|
|
|
|
|
|
|
var key = info.Item.GetUserDataKey();
|
|
|
|
var key = info.Item.GetUserDataKey();
|
|
|
|
|
|
|
|
|
|
|
|
var user = session.User;
|
|
|
|
var users = GetUsers(session);
|
|
|
|
|
|
|
|
|
|
|
|
var data = _userDataRepository.GetUserData(user.Id, key);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (info.PositionTicks.HasValue)
|
|
|
|
foreach (var user in users)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
UpdatePlayState(info.Item, data, info.PositionTicks.Value);
|
|
|
|
await OnPlaybackProgress(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
|
|
|
|
EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Item = info.Item,
|
|
|
|
Item = info.Item,
|
|
|
|
User = user,
|
|
|
|
Users = users,
|
|
|
|
PlaybackPositionTicks = info.PositionTicks,
|
|
|
|
PlaybackPositionTicks = info.PositionTicks
|
|
|
|
UserData = data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}, _logger);
|
|
|
|
}, _logger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (positionTicks.HasValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
UpdatePlayState(item, data, positionTicks.Value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Used to report that playback has ended for an item
|
|
|
|
/// Used to report that playback has ended for an item
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
@ -371,14 +429,32 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
|
|
|
|
|
|
|
|
var key = info.Item.GetUserDataKey();
|
|
|
|
var key = info.Item.GetUserDataKey();
|
|
|
|
|
|
|
|
|
|
|
|
var user = session.User;
|
|
|
|
var users = GetUsers(session);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var playedToCompletion = false;
|
|
|
|
|
|
|
|
foreach (var user in users)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Item = info.Item,
|
|
|
|
|
|
|
|
Users = users,
|
|
|
|
|
|
|
|
PlaybackPositionTicks = info.PositionTicks,
|
|
|
|
|
|
|
|
PlayedToCompletion = playedToCompletion
|
|
|
|
|
|
|
|
|
|
|
|
var data = _userDataRepository.GetUserData(user.Id, key);
|
|
|
|
}, _logger);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
|
|
|
bool playedToCompletion;
|
|
|
|
bool playedToCompletion;
|
|
|
|
|
|
|
|
|
|
|
|
if (info.PositionTicks.HasValue)
|
|
|
|
if (positionTicks.HasValue)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
playedToCompletion = UpdatePlayState(info.Item, data, info.PositionTicks.Value);
|
|
|
|
playedToCompletion = UpdatePlayState(item, data, positionTicks.Value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -389,17 +465,9 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
playedToCompletion = true;
|
|
|
|
playedToCompletion = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Item = info.Item,
|
|
|
|
|
|
|
|
User = user,
|
|
|
|
|
|
|
|
PlaybackPositionTicks = info.PositionTicks,
|
|
|
|
|
|
|
|
UserData = data,
|
|
|
|
|
|
|
|
PlayedToCompletion = playedToCompletion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}, _logger);
|
|
|
|
return playedToCompletion;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
@ -462,12 +530,12 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the session for remote control.
|
|
|
|
/// Gets the session.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sessionId">The session id.</param>
|
|
|
|
/// <param name="sessionId">The session identifier.</param>
|
|
|
|
/// <returns>SessionInfo.</returns>
|
|
|
|
/// <returns>SessionInfo.</returns>
|
|
|
|
/// <exception cref="ResourceNotFoundException"></exception>
|
|
|
|
/// <exception cref="ResourceNotFoundException"></exception>
|
|
|
|
private SessionInfo GetSessionForRemoteControl(Guid sessionId)
|
|
|
|
private SessionInfo GetSession(Guid sessionId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var session = Sessions.First(i => i.Id.Equals(sessionId));
|
|
|
|
var session = Sessions.First(i => i.Id.Equals(sessionId));
|
|
|
|
|
|
|
|
|
|
|
@ -476,6 +544,19 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId));
|
|
|
|
throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return session;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Gets the session for remote control.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <param name="sessionId">The session id.</param>
|
|
|
|
|
|
|
|
/// <returns>SessionInfo.</returns>
|
|
|
|
|
|
|
|
/// <exception cref="ResourceNotFoundException"></exception>
|
|
|
|
|
|
|
|
private SessionInfo GetSessionForRemoteControl(Guid sessionId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var session = GetSession(sessionId);
|
|
|
|
|
|
|
|
|
|
|
|
if (!session.SupportsRemoteControl)
|
|
|
|
if (!session.SupportsRemoteControl)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id));
|
|
|
|
throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id));
|
|
|
@ -595,7 +676,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
_logger.ErrorException("Error in SendRestartRequiredNotification.", ex);
|
|
|
|
_logger.ErrorException("Error in SendRestartRequiredNotification.", ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}));
|
|
|
|
}, cancellationToken));
|
|
|
|
|
|
|
|
|
|
|
|
return Task.WhenAll(tasks);
|
|
|
|
return Task.WhenAll(tasks);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -649,5 +730,68 @@ namespace MediaBrowser.Server.Implementations.Session
|
|
|
|
|
|
|
|
|
|
|
|
return Task.WhenAll(tasks);
|
|
|
|
return Task.WhenAll(tasks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Adds the additional user.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <param name="sessionId">The session identifier.</param>
|
|
|
|
|
|
|
|
/// <param name="userId">The user identifier.</param>
|
|
|
|
|
|
|
|
/// <exception cref="System.UnauthorizedAccessException">Cannot modify additional users without authenticating first.</exception>
|
|
|
|
|
|
|
|
/// <exception cref="System.ArgumentException">The requested user is already the primary user of the session.</exception>
|
|
|
|
|
|
|
|
public void AddAdditionalUser(Guid sessionId, Guid userId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var session = GetSession(sessionId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!session.UserId.HasValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
throw new UnauthorizedAccessException("Cannot modify additional users without authenticating first.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (session.UserId.Value == userId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
throw new ArgumentException("The requested user is already the primary user of the session.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (session.AdditionalUsersPresent.All(i => new Guid(i.UserId) != userId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var user = _userManager.GetUserById(userId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
session.AdditionalUsersPresent.Add(new SessionUserInfo
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
UserId = userId.ToString("N"),
|
|
|
|
|
|
|
|
UserName = user.Name
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Removes the additional user.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <param name="sessionId">The session identifier.</param>
|
|
|
|
|
|
|
|
/// <param name="userId">The user identifier.</param>
|
|
|
|
|
|
|
|
/// <exception cref="System.UnauthorizedAccessException">Cannot modify additional users without authenticating first.</exception>
|
|
|
|
|
|
|
|
/// <exception cref="System.ArgumentException">The requested user is already the primary user of the session.</exception>
|
|
|
|
|
|
|
|
public void RemoveAdditionalUser(Guid sessionId, Guid userId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var session = GetSession(sessionId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!session.UserId.HasValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
throw new UnauthorizedAccessException("Cannot modify additional users without authenticating first.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (session.UserId.Value == userId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
throw new ArgumentException("The requested user is already the primary user of the session.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var user = session.AdditionalUsersPresent.FirstOrDefault(i => new Guid(i.UserId) == userId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (user != null)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
session.AdditionalUsersPresent.Remove(user);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|